linphone-去掉HistoryListFragment界面

奋斗吧
奋斗吧
擅长邻域:未填写

标签: linphone-去掉HistoryListFragment界面 JavaScript博客 51CTO博客

2023-05-29 18:24:14 71浏览

linphone-去掉HistoryListFragment界面,去掉原生Linphone的HistoryListFragment界面


说明

HistoryListFragment界面包括:
1. 拨打电话记录
2. 未接听记录
3. 修改记录

看图

linphone-去掉HistoryListFragment界面_sed


HistoryListFragment主界面

linphone-去掉HistoryListFragment界面_sed_02


修改拨打记录界面

linphone-去掉HistoryListFragment界面_linphone_03

好,开始去掉这个界面

需要分析的点

  1. 每次拨打记录是怎样形成的。
  2. 记录还可以分日期显示一组。
  3. 没有接到的电话是怎样记录的
  4. 就该记录时,那个工具栏是怎样变化的。
  5. 编辑时如何做到全选。
  6. 编辑时的删除命令。

界面完整代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorH"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/top_bar"
        android:orientation="horizontal"
        android:background="@color/colorF"
        android:layout_width="match_parent"
        android:layout_height="60dp">

        <RelativeLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.2">

            <ImageView
                android:id="@+id/all_calls"
                android:src="@drawable/history_all"
                android:background="@drawable/toolbar_button"
                android:contentDescription="@string/content_description_all_contacts"
                android:padding="15dp"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>

            <View
                android:id="@+id/all_calls_select"
                android:background="@color/colorA"
                android:layout_width="match_parent"
                android:layout_height="5dp"
                android:layout_alignParentBottom="true"/>
        </RelativeLayout>

        <RelativeLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.2">

            <ImageView
                android:id="@+id/missed_calls"
                android:src="@drawable/history_missed"
                android:background="@drawable/toolbar_button"
                android:contentDescription="@string/content_description_linphone_contacts"
                android:gravity="center"
                android:padding="15dp"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>

            <View
                android:id="@+id/missed_calls_select"
                android:background="@color/colorA"
                android:layout_width="match_parent"
                android:layout_height="5dp"
                android:visibility="gone"
                android:layout_alignParentBottom="true"/>
        </RelativeLayout>

        <View
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.4"/>

        <ImageView
            android:id="@+id/edit"
            android:src="@drawable/edit_list_button"
            android:background="@drawable/toolbar_button"
            android:contentDescription="@string/content_description_edit_list"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.2"
            android:padding="15dp"/>
    </LinearLayout>

    <include layout="@layout/edit_list"/>

    <ListView
        android:id="@+id/history_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="@color/colorE"
        android:cacheColorHint="@color/transparent"
        android:dividerHeight="1dp" />

    <TextView
        android:id="@+id/no_call_history"
        android:text="@string/no_call_history"
        style="@style/font6"
        android:visibility="gone"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"/>

    <TextView
        android:id="@+id/no_missed_call_history"
        android:text="@string/no_missed_call_history"
        style="@style/font6"
        android:visibility="gone"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"/>

</LinearLayout>

界面部分代码分析心得

  1. 按钮使用ImageView标签。
  2. 此部分所有的逻辑,其实全部在这个布局中。使用的时候显示,不使用的时候使其消失。得到了现在的逻辑。
  3. 多选,就是重新设置了一下ListView, 将Checkbox显示出来。

HistoryListFragment

package org.linphone;
/*
HistoryListFragment.java
Copyright (C) 2015  Belledonne Communications, Grenoble, France

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

import org.linphone.core.CallDirection;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCallLog;
import org.linphone.core.LinphoneCallLog.CallStatus;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

/**
 * @author Sylvain Berfini
 */
public class HistoryListFragment extends Fragment implements OnClickListener, OnItemClickListener, ContactsUpdatedListener {
    private ListView historyList;
    private LayoutInflater mInflater;
    private TextView noCallHistory, noMissedCallHistory;
    private ImageView missedCalls, allCalls, edit, selectAll, deselectAll, delete, cancel;
    private View allCallsSelected, missedCallsSelected;
    private LinearLayout editList, topBar;
    private boolean onlyDisplayMissedCalls, isEditMode;
    private List<LinphoneCallLog> mLogs;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        mInflater = inflater;
        View view = inflater.inflate(R.layout.history, container, false);

        noCallHistory = (TextView) view.findViewById(R.id.no_call_history);
        noMissedCallHistory = (TextView) view.findViewById(R.id.no_missed_call_history);

        historyList = (ListView) view.findViewById(R.id.history_list);
        historyList.setOnItemClickListener(this);

        delete = (ImageView) view.findViewById(R.id.delete);
        delete.setOnClickListener(this);

        editList = (LinearLayout) view.findViewById(R.id.edit_list);
        topBar = (LinearLayout) view.findViewById(R.id.top_bar);

        cancel = (ImageView) view.findViewById(R.id.cancel);
        cancel.setOnClickListener(this);

        allCalls = (ImageView) view.findViewById(R.id.all_calls);
        allCalls.setOnClickListener(this);

        allCallsSelected = view.findViewById(R.id.all_calls_select);

        missedCalls = (ImageView) view.findViewById(R.id.missed_calls);
        missedCalls.setOnClickListener(this);

        missedCallsSelected = view.findViewById(R.id.missed_calls_select);

        selectAll = (ImageView) view.findViewById(R.id.select_all);
        selectAll.setOnClickListener(this);

        deselectAll = (ImageView) view.findViewById(R.id.deselect_all);
        deselectAll.setOnClickListener(this);

        allCalls.setEnabled(false);
        onlyDisplayMissedCalls = false;

        edit = (ImageView) view.findViewById(R.id.edit);
        edit.setOnClickListener(this);

        return view;
    }

    public void refresh() {
        mLogs = Arrays.asList(LinphoneManager.getLc().getCallLogs());
    }

    private void selectAllList(boolean isSelectAll){
        int size = historyList.getAdapter().getCount();
        for(int i=0; i<size; i++) {
            historyList.setItemChecked(i,isSelectAll);
        }
    }

    public void displayFirstLog(){
        if (mLogs != null && mLogs.size() > 0) {
            LinphoneCallLog log = mLogs.get(0);
            if (log.getDirection() == CallDirection.Incoming) {
                LinphoneActivity.instance().displayHistoryDetail(mLogs.get(0).getFrom().toString(), mLogs.get(0));
            } else {
                LinphoneActivity.instance().displayHistoryDetail(mLogs.get(0).getTo().toString(), mLogs.get(0));
            }
        } else {
            LinphoneActivity.instance().displayEmptyFragment();
        }
    }

    private void removeCallLogs(){
        int size = historyList.getAdapter().getCount();
        for(int i=0; i<size; i++) {
            if(historyList.isItemChecked(i)){
                LinphoneCallLog log = mLogs.get(i);
                LinphoneManager.getLc().removeCallLog(log);
            }
        }
    }

    public int getNbItemsChecked(){
        int size = historyList.getAdapter().getCount();
        int nb = 0;
        for(int i=0; i<size; i++) {
            if(historyList.isItemChecked(i)) {
                nb ++;
            }
        }
        return nb;
    }

    public void enabledDeleteButton(Boolean enabled){
        if(enabled){
            delete.setEnabled(true);
        } else {
            if (getNbItemsChecked() == 0){
                delete.setEnabled(false);
            }
        }
    }

    private void removeNotMissedCallsFromLogs() {
        if (onlyDisplayMissedCalls) {
            List<LinphoneCallLog> missedCalls = new ArrayList<LinphoneCallLog>();
            for (LinphoneCallLog log : mLogs) {
                if (log.getStatus() == CallStatus.Missed) {
                    missedCalls.add(log);
                }
            }
            mLogs = missedCalls;
        }
    }

    private boolean hideHistoryListAndDisplayMessageIfEmpty() {
        removeNotMissedCallsFromLogs();
        if (mLogs.isEmpty()) {
            if (onlyDisplayMissedCalls) {
                noMissedCallHistory.setVisibility(View.VISIBLE);
            } else {
                noCallHistory.setVisibility(View.VISIBLE);
            }
            historyList.setVisibility(View.GONE);
            edit.setEnabled(false);
            return true;
        } else {
            noCallHistory.setVisibility(View.GONE);
            noMissedCallHistory.setVisibility(View.GONE);
            historyList.setVisibility(View.VISIBLE);
            edit.setEnabled(true);
            return false;
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        ContactsManager.addContactsListener(this);

        if (LinphoneActivity.isInstanciated()) {
            LinphoneActivity.instance().selectMenu(FragmentsAvailable.HISTORY_LIST);
            LinphoneActivity.instance().hideTabBar(false);
            LinphoneActivity.instance().displayMissedCalls(0);
        }

        mLogs = Arrays.asList(LinphoneManager.getLc().getCallLogs());
        if (!hideHistoryListAndDisplayMessageIfEmpty()) {
            historyList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
            historyList.setAdapter(new CallHistoryAdapter(getActivity().getApplicationContext()));
        }
    }

    @Override
    public void onPause() {
        ContactsManager.removeContactsListener(this);
        super.onPause();
    }

    @Override
    public void onContactsUpdated() {
        CallHistoryAdapter adapter = (CallHistoryAdapter)historyList.getAdapter();
        if (adapter != null) {
            adapter.notifyDataSetChanged();
        }
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();

        if (id == R.id.select_all) {
            deselectAll.setVisibility(View.VISIBLE);
            selectAll.setVisibility(View.GONE);
            enabledDeleteButton(true);
            selectAllList(true);
            return;
        }
        if (id == R.id.deselect_all) {
            deselectAll.setVisibility(View.GONE);
            selectAll.setVisibility(View.VISIBLE);
            enabledDeleteButton(false);
            selectAllList(false);
            return;
        }

        if (id == R.id.cancel) {
            quitEditMode();
            return;
        }

        if (id == R.id.delete) {
            if(historyList.getCheckedItemCount() == 0) {
                quitEditMode();
                return;
            }

            final Dialog dialog = LinphoneActivity.instance().displayDialog(getString(R.string.delete_text));
            Button delete = (Button) dialog.findViewById(R.id.delete_button);
            Button cancel = (Button) dialog.findViewById(R.id.cancel);

            delete.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view) {
                    removeCallLogs();
                    dialog.dismiss();
                    quitEditMode();
                }
            });

            cancel.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view) {
                    dialog.dismiss();
                    quitEditMode();
                }
            });
            dialog.show();
            return;
        }

        if (id == R.id.all_calls) {
            allCalls.setEnabled(false);
            allCallsSelected.setVisibility(View.VISIBLE);
            missedCallsSelected.setVisibility(View.INVISIBLE);
            missedCalls.setEnabled(true);
            onlyDisplayMissedCalls = false;
            refresh();
        }
        if (id == R.id.missed_calls) {
            allCalls.setEnabled(true);
            allCallsSelected.setVisibility(View.INVISIBLE);
            missedCallsSelected.setVisibility(View.VISIBLE);
            missedCalls.setEnabled(false);
            onlyDisplayMissedCalls = true;
        }

        if (id == R.id.edit) {
            topBar.setVisibility(View.GONE);
            editList.setVisibility(View.VISIBLE);
            enabledDeleteButton(false);
            isEditMode = true;
        }

        if (!hideHistoryListAndDisplayMessageIfEmpty()) {
            historyList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
            historyList.setAdapter(new CallHistoryAdapter(getActivity().getApplicationContext()));
        }

        if(isEditMode){
            deselectAll.setVisibility(View.GONE);
            selectAll.setVisibility(View.VISIBLE);
        }

    }

    @Override
    public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
        if (isEditMode) {
            LinphoneCallLog log = mLogs.get(position);
            LinphoneManager.getLc().removeCallLog(log);
            mLogs = Arrays.asList(LinphoneManager.getLc().getCallLogs());
        } else {
            if (LinphoneActivity.isInstanciated()) {
                LinphoneCallLog log = mLogs.get(position);
                LinphoneAddress address;
                if (log.getDirection() == CallDirection.Incoming) {
                    address = log.getFrom();
                } else {
                    address = log.getTo();
                }
                LinphoneActivity.instance().setAddresGoToDialerAndCall(address.asStringUriOnly(), address.getDisplayName(), null);
            }
        }
    }

    public void quitEditMode(){
        isEditMode = false;
        editList.setVisibility(View.GONE);
        topBar.setVisibility(View.VISIBLE);

        refresh();
        if (!hideHistoryListAndDisplayMessageIfEmpty()) {
            historyList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
            historyList.setAdapter(new CallHistoryAdapter(getActivity().getApplicationContext()));
        }
        if (getResources().getBoolean(R.bool.isTablet)) {
            displayFirstLog();
        }
    }

    class CallHistoryAdapter extends  BaseAdapter {
        private class ViewHolder {
            public TextView contact;
            public ImageView detail;
            public CheckBox select;
            public ImageView callDirection;
            public ImageView contactPicture;

            public ViewHolder(View view) {
                contact = (TextView) view.findViewById(R.id.sip_uri);
                detail = (ImageView) view.findViewById(R.id.detail);
                select = (CheckBox) view.findViewById(R.id.delete);
                callDirection = (ImageView) view.findViewById(R.id.icon);
                contactPicture = (ImageView) view.findViewById(R.id.contact_picture);
            }
        }

        CallHistoryAdapter(Context aContext) {

        }

        public int getCount() {
            return mLogs.size();
        }

        public Object getItem(int position) {
            return mLogs.get(position);
        }

        public long getItemId(int position) {
            return position;
        }

        @SuppressLint("SimpleDateFormat")
        private String timestampToHumanDate(Calendar cal) {
            SimpleDateFormat dateFormat;
            if (isToday(cal)) {
                return getString(R.string.today);
            } else if (isYesterday(cal)) {
                return getString(R.string.yesterday);
            } else {
                dateFormat = new SimpleDateFormat(getResources().getString(R.string.history_date_format));
            }

            return dateFormat.format(cal.getTime());
        }

        private boolean isSameDay(Calendar cal1, Calendar cal2) {
            if (cal1 == null || cal2 == null) {
                return false;
            }

            return (cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA) &&
                    cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                    cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR));
        }

        private boolean isToday(Calendar cal) {
            return isSameDay(cal, Calendar.getInstance());
        }

        private boolean isYesterday(Calendar cal) {
            Calendar yesterday = Calendar.getInstance();
            yesterday.roll(Calendar.DAY_OF_MONTH, -1);
            return isSameDay(cal, yesterday);
        }

        public View getView(final int position, View convertView, ViewGroup parent) {
            View view = null;
            ViewHolder holder = null;

            if (convertView != null) {
                view = convertView;
                holder = (ViewHolder) view.getTag();
            } else {
                view = mInflater.inflate(R.layout.history_cell, parent,false);
                holder = new ViewHolder(view);
                view.setTag(holder);
            }

            final LinphoneCallLog log = mLogs.get(position);
            long timestamp = log.getTimestamp();
            LinphoneAddress address;

            holder.contact.setSelected(true); // For automated horizontal scrolling of long texts

            LinearLayout separator = (LinearLayout) view.findViewById(R.id.separator);
            TextView separatorText = (TextView) view.findViewById(R.id.separator_text);
            Calendar logTime = Calendar.getInstance();
            logTime.setTimeInMillis(timestamp);
            separatorText.setText(timestampToHumanDate(logTime));

            if (position > 0) {
                LinphoneCallLog previousLog = mLogs.get(position-1);
                long previousTimestamp = previousLog.getTimestamp();
                Calendar previousLogTime = Calendar.getInstance();
                previousLogTime.setTimeInMillis(previousTimestamp);

                if (isSameDay(previousLogTime, logTime)) {
                    separator.setVisibility(View.GONE);
                } else {
                    separator.setVisibility(View.VISIBLE);
                }
            } else {
                separator.setVisibility(View.VISIBLE);
            }

            if (log.getDirection() == CallDirection.Incoming) {
                address = log.getFrom();
                if (log.getStatus() == CallStatus.Missed) {
                    holder.callDirection.setImageResource(R.drawable.call_status_missed);
                } else {
                    holder.callDirection.setImageResource(R.drawable.call_status_incoming);
                }
            } else {
                address = log.getTo();
                holder.callDirection.setImageResource(R.drawable.call_status_outgoing);
            }

            LinphoneContact c = ContactsManager.getInstance().findContactFromAddress(address);
            String displayName = null;
            final String sipUri = address.asString();
            if (c != null) {
                displayName = c.getFullName();
                LinphoneUtils.setThumbnailPictureFromUri(getActivity(), holder.contactPicture, c.getThumbnailUri());
            } else {
                holder.contactPicture.setImageBitmap(ContactsManager.getInstance().getDefaultAvatarBitmap());
            }

            if (displayName == null) {
                holder.contact.setText(LinphoneUtils.getAddressDisplayName(sipUri));
            } else {
                holder.contact.setText(displayName);
            }

            if (isEditMode) {
                holder.select.setVisibility(View.VISIBLE);
                holder.select.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                        historyList.setItemChecked(position, b);
                        if(getNbItemsChecked() == getCount()){
                            deselectAll.setVisibility(View.VISIBLE);
                            selectAll.setVisibility(View.GONE);
                            enabledDeleteButton(true);
                        } else {
                            if(getNbItemsChecked() == 0){
                                deselectAll.setVisibility(View.GONE);
                                selectAll.setVisibility(View.VISIBLE);
                                enabledDeleteButton(false);
                            } else {
                                deselectAll.setVisibility(View.GONE);
                                selectAll.setVisibility(View.VISIBLE);
                                enabledDeleteButton(true);
                            }
                        }
                    }
                });
                holder.detail.setVisibility(View.INVISIBLE);
                if(historyList.isItemChecked(position)) {
                    holder.select.setChecked(true);
                } else {
                    holder.select.setChecked(false);
                }
            } else {
                holder.select.setVisibility(View.GONE);
                holder.detail.setVisibility(View.VISIBLE);
                holder.detail.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (LinphoneActivity.isInstanciated()) {
                            LinphoneActivity.instance().displayHistoryDetail(sipUri, log);
                        }
                    }
                });
            }
            return view;
        }
    }
}

HistoryListFragment代码分析

ListView获取数据

# call_logs.c 通过Sqlite3获取数据
const bctbx_list_t *linphone_core_get_call_history(LinphoneCore *lc) {
    char *buf;
    uint64_t begin,end;
    bctbx_list_t *result = NULL;

    if (!lc || lc->logs_db == NULL) return NULL;

    if (lc->max_call_logs != LINPHONE_MAX_CALL_HISTORY_UNLIMITED){
        buf = sqlite3_mprintf("SELECT * FROM call_history ORDER BY id DESC LIMIT %i", lc->max_call_logs);
    }else{
        buf = sqlite3_mprintf("SELECT * FROM call_history ORDER BY id DESC");
    }

    begin = ortp_get_cur_time_ms();
    linphone_sql_request_call_log(lc->logs_db, buf, &result);
    end = ortp_get_cur_time_ms();
    ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin));
    sqlite3_free(buf);

    if (lc->call_logs) {
        copy_user_data_from_existing_logs(lc->call_logs, result);
    }

    lc->call_logs = bctbx_list_free_with_data(lc->call_logs, (void (*)(void*))linphone_call_log_unref);
    lc->call_logs = result;

    return lc->call_logs;
}

ListView的显示以及设置

利用

CallLogs数据的删除

// LinphoneManager.getLc().removeCallLog(log);
# call_logs.c
void linphone_core_delete_call_history(LinphoneCore *lc) {
    char *buf;

    if (!lc || lc->logs_db == NULL) return ;

    buf = sqlite3_mprintf("DELETE FROM call_history");
    linphone_sql_request_generic(lc->logs_db, buf);
    sqlite3_free(buf);
}

CallLogs数据的增加

#call_logs.c
void linphone_core_store_call_log(LinphoneCore *lc, LinphoneCallLog *log) {
    if (lc && lc->logs_db){
        char *from, *to;
        char *buf;

        from = linphone_address_as_string(log->from);
        to = linphone_address_as_string(log->to);
        buf = sqlite3_mprintf("INSERT INTO call_history VALUES(NULL,%Q,%Q,%i,%i,%lld,%lld,%i,%i,%f,%Q,%Q);",
                        from,
                        to,
                        log->dir,
                        log->duration,
                        (int64_t)log->start_date_time,
                        (int64_t)log->connected_date_time,
                        log->status,
                        log->video_enabled ? 1 : 0,
                        log->quality,
                        log->call_id,
                        log->refkey
                    );
        linphone_sql_request_generic(lc->logs_db, buf);
        sqlite3_free(buf);
        ms_free(from);
        ms_free(to);

        log->storage_id = (unsigned int)sqlite3_last_insert_rowid(lc->logs_db);
    }

    if (lc) {
        lc->call_logs = bctbx_list_prepend(lc->call_logs, linphone_call_log_ref(log));
    }
}


好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695