linphone-去掉HistoryListFragment界面
来源:互联网 发布:大型分析仪器仿真软件 编辑:程序博客网 时间:2024/05/20 17:40
说明
HistoryListFragment界面包括:
1. 拨打电话记录
2. 未接听记录
3. 修改记录
看图
HistoryListFragment主界面
修改拨打记录界面
好,开始去掉这个界面
需要分析的点
- 每次拨打记录是怎样形成的。
- 记录还可以分日期显示一组。
- 没有接到的电话是怎样记录的
- 就该记录时,那个工具栏是怎样变化的。
- 编辑时如何做到全选。
- 编辑时的删除命令。
界面完整代码
<?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>
界面部分代码分析心得
- 按钮使用ImageView标签。
- 此部分所有的逻辑,其实全部在这个布局中。使用的时候显示,不使用的时候使其消失。得到了现在的逻辑。
- 多选,就是重新设置了一下ListView, 将Checkbox显示出来。
HistoryListFragment
package org.linphone;/*HistoryListFragment.javaCopyright (C) 2015 Belledonne Communications, Grenoble, FranceThis program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, 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.cvoid 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.cvoid 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 0
- linphone-去掉HistoryListFragment界面
- linphone-去掉linphone的ContactsListFragment联系人界面
- linphone-去掉About界面(一)
- linphone-去掉About界面(二)
- linphone-去掉ChatListFragment聊天界面
- linphone-去掉蓝牙功能
- linphone
- linphone
- linphone
- linphone
- linphone-linphone视频时退到后台如何返回到视频界面
- 如何去掉Android界面TitleBar
- 如何去掉tomcat管理界面
- [Linphone Android]Linphone介绍
- linphone-3.9.1 无界面版在openwrt上的移植
- 去掉水晶报表的数据库验证界面
- xp系统中去掉用户登录界面
- 如何去掉WIN7系统用户登陆界面
- PCA算法理解
- Reverse String II
- Java 阻塞队列实现原理分析
- tar
- Java经典算法四十例编程详解+程序实例
- linphone-去掉HistoryListFragment界面
- 解决Myeclipse在调试(debug)时无法显示变量值问题
- android:configChanges属性总结(横竖屏切换)
- 自定义键盘实现
- ipv6的表示、ipv6与ipv4之间的转换、ipv6地址大小判定
- 聊聊分布式事务
- 字符串扩展(java)
- 解决JSP中文乱码问题
- RestEasy简介