Improve scrolling speed in lists

This commit is contained in:
Sylvain Berfini 2016-08-08 14:12:16 +02:00
parent 98d2958a44
commit 7c5fa67f43
6 changed files with 229 additions and 117 deletions

View file

@ -387,7 +387,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
CheckBox deleteChatBubble = (CheckBox) v.findViewById(R.id.delete_message); CheckBox deleteChatBubble = (CheckBox) v.findViewById(R.id.delete_message);
if(isEditMode) { if (isEditMode) {
deleteChatBubble.setVisibility(View.VISIBLE); deleteChatBubble.setVisibility(View.VISIBLE);
if (message.isOutgoing()) { if (message.isOutgoing()) {
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
@ -1043,6 +1043,16 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
} }
class SearchContactsListAdapter extends BaseAdapter { class SearchContactsListAdapter extends BaseAdapter {
private class ViewHolder {
public TextView name;
public TextView address;
public ViewHolder(View view) {
name = (TextView) view.findViewById(R.id.contact_name);
address = (TextView) view.findViewById(R.id.contact_address);
}
}
private List<ContactAddress> contacts; private List<ContactAddress> contacts;
private LayoutInflater mInflater; private LayoutInflater mInflater;
@ -1093,24 +1103,26 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
public View getView(int position, View convertView, ViewGroup parent) { public View getView(int position, View convertView, ViewGroup parent) {
View view = null; View view = null;
ContactAddress contact; ContactAddress contact;
ViewHolder holder = null;
do { do {
contact = getItem(position); contact = getItem(position);
} while (contact == null); } while (contact == null);
if (convertView != null) { if (convertView != null) {
view = convertView; view = convertView;
holder = (ViewHolder) view.getTag();
} else { } else {
view = mInflater.inflate(R.layout.search_contact_cell, parent, false); view = mInflater.inflate(R.layout.search_contact_cell, parent, false);
holder = new ViewHolder(view);
view.setTag(holder);
} }
final String a = contact.address; final String a = contact.address;
LinphoneContact c = contact.contact; LinphoneContact c = contact.contact;
TextView name = (TextView) view.findViewById(R.id.contact_name); holder.name.setText(c.getFullName());
name.setText(c.getFullName()); holder.address.setText(a);
TextView address = (TextView) view.findViewById(R.id.contact_address);
address.setText(a);
view.setOnClickListener(new OnClickListener() { view.setOnClickListener(new OnClickListener() {
@Override @Override

View file

@ -30,6 +30,7 @@ import org.linphone.mediastream.Log;
import android.app.Dialog; import android.app.Dialog;
import android.app.Fragment; import android.app.Fragment;
import android.graphics.Bitmap;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.os.Bundle; import android.os.Bundle;
import android.view.ContextMenu; import android.view.ContextMenu;
@ -117,15 +118,16 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
} }
} }
private void removeChatsConversation(){ private void removeChatsConversation() {
int size = chatList.getAdapter().getCount(); int size = chatList.getAdapter().getCount();
for(int i=0; i<size; i++) { for (int i = 0; i < size; i++) {
if(chatList.isItemChecked(i)){ if (chatList.isItemChecked(i)) {
View item = chatList.getAdapter().getView(i, null, null); String sipUri = chatList.getAdapter().getItem(i).toString();
if(item != null) { if (sipUri != null) {
LinphoneChatRoom chatroom = LinphoneManager.getLc().getOrCreateChatRoom(item.getTag().toString()); LinphoneChatRoom chatroom = LinphoneManager.getLc().getOrCreateChatRoom(sipUri);
if (chatroom != null) if (chatroom != null) {
chatroom.deleteHistory(); chatroom.deleteHistory();
}
} }
} }
} }
@ -241,7 +243,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
if (info == null || info.targetView == null) { if (info == null || info.targetView == null) {
return false; return false;
} }
String sipUri = (String) info.targetView.getTag(); String sipUri = chatList.getAdapter().getItem(info.position).toString();
LinphoneActivity.instance().removeFromChatList(sipUri); LinphoneActivity.instance().removeFromChatList(sipUri);
mConversations = LinphoneActivity.instance().getChatList(); mConversations = LinphoneActivity.instance().getChatList();
@ -331,7 +333,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
@Override @Override
public void onItemClick(AdapterView<?> adapter, View view, int position, long id) { public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
String sipUri = (String) view.getTag(); String sipUri = chatList.getAdapter().getItem(position).toString();
if (LinphoneActivity.isInstanciated() && !isEditMode) { if (LinphoneActivity.isInstanciated() && !isEditMode) {
LinphoneActivity.instance().displayChat(sipUri); LinphoneActivity.instance().displayChat(sipUri);
@ -339,7 +341,24 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
} }
class ChatListAdapter extends BaseAdapter { class ChatListAdapter extends BaseAdapter {
private class ViewHolder {
public TextView lastMessageView;
public TextView date;
public TextView displayName;
public TextView unreadMessages;
public CheckBox select;
public ImageView contactPicture;
public ViewHolder(View view) {
lastMessageView = (TextView) view.findViewById(R.id.lastMessage);
date = (TextView) view.findViewById(R.id.date);
displayName = (TextView) view.findViewById(R.id.sipUri);
unreadMessages = (TextView) view.findViewById(R.id.unreadMessages);
select = (CheckBox) view.findViewById(R.id.delete_chatroom);
contactPicture = (ImageView) view.findViewById(R.id.contact_picture);
}
}
ChatListAdapter() {} ChatListAdapter() {}
public int getCount() { public int getCount() {
@ -347,7 +366,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
} }
public Object getItem(int position) { public Object getItem(int position) {
return position; return mConversations.get(position);
} }
public long getItemId(int position) { public long getItemId(int position) {
@ -356,21 +375,23 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
public View getView(final int position, View convertView, ViewGroup parent) { public View getView(final int position, View convertView, ViewGroup parent) {
View view = null; View view = null;
ViewHolder holder = null;
String sipUri = mConversations.get(position);
if (convertView != null) { if (convertView != null) {
view = convertView; view = convertView;
holder = (ViewHolder) view.getTag();
} else { } else {
view = mInflater.inflate(R.layout.chatlist_cell, parent, false); view = mInflater.inflate(R.layout.chatlist_cell, parent, false);
holder = new ViewHolder(view);
view.setTag(holder);
} }
String sipUri = mConversations.get(position);
view.setTag(sipUri);
LinphoneAddress address; LinphoneAddress address;
try { try {
address = LinphoneCoreFactory.instance().createLinphoneAddress(sipUri); address = LinphoneCoreFactory.instance().createLinphoneAddress(sipUri);
} catch (LinphoneCoreException e) { } catch (LinphoneCoreException e) {
Log.e("Chat view cannot parse address",e); Log.e("Chat view cannot parse address", e);
return view; return view;
} }
@ -378,57 +399,55 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
String message = ""; String message = "";
Long time; Long time;
TextView lastMessageView = (TextView) view.findViewById(R.id.lastMessage);
TextView date = (TextView) view.findViewById(R.id.date);
TextView displayName = (TextView) view.findViewById(R.id.sipUri);
TextView unreadMessages = (TextView) view.findViewById(R.id.unreadMessages);
CheckBox select = (CheckBox) view.findViewById(R.id.delete_chatroom);
ImageView contactPicture = (ImageView) view.findViewById(R.id.contact_picture);
LinphoneChatRoom chatRoom = LinphoneManager.getLc().getChatRoom(address); LinphoneChatRoom chatRoom = LinphoneManager.getLc().getChatRoom(address);
int unreadMessagesCount = chatRoom.getUnreadMessagesCount(); int unreadMessagesCount = chatRoom.getUnreadMessagesCount();
LinphoneChatMessage[] history = chatRoom.getHistory(1); LinphoneChatMessage[] history = chatRoom.getHistory(1);
LinphoneChatMessage msg = history[0]; LinphoneChatMessage msg = history[0];
if(msg.getFileTransferInformation() != null || msg.getExternalBodyUrl() != null || msg.getAppData() != null ){ if(msg.getFileTransferInformation() != null || msg.getExternalBodyUrl() != null || msg.getAppData() != null ){
lastMessageView.setBackgroundResource(R.drawable.chat_file_message); holder.lastMessageView.setBackgroundResource(R.drawable.chat_file_message);
time = msg.getTime(); time = msg.getTime();
date.setText(LinphoneUtils.timestampToHumanDate(getActivity(),time,getString(R.string.messages_list_date_format))); holder.date.setText(LinphoneUtils.timestampToHumanDate(getActivity(),time,getString(R.string.messages_list_date_format)));
lastMessageView.setText(""); holder.lastMessageView.setText("");
} else if (msg.getText() != null && msg.getText().length() > 0 ){ } else if (msg.getText() != null && msg.getText().length() > 0 ){
message = msg.getText(); message = msg.getText();
lastMessageView.setBackgroundResource(0); holder.lastMessageView.setBackgroundResource(0);
time = msg.getTime(); time = msg.getTime();
date.setText(LinphoneUtils.timestampToHumanDate(getActivity(),time,getString(R.string.messages_list_date_format))); holder.date.setText(LinphoneUtils.timestampToHumanDate(getActivity(),time,getString(R.string.messages_list_date_format)));
lastMessageView.setText(message); holder.lastMessageView.setText(message);
} }
displayName.setSelected(true); // For animation holder.displayName.setSelected(true); // For animation
displayName.setText(contact == null ? LinphoneUtils.getAddressDisplayName(address) : contact.getFullName()); holder.displayName.setText(contact == null ? LinphoneUtils.getAddressDisplayName(address) : contact.getFullName());
if (contact != null) { if (contact != null) {
LinphoneUtils.setImagePictureFromUri(view.getContext(), contactPicture, contact.getPhotoUri(), contact.getThumbnailUri()); Bitmap photo = contact.getPhoto();
if (photo != null) {
holder.contactPicture.setImageBitmap(photo);
} else {
LinphoneUtils.setImagePictureFromUri(getActivity(), holder.contactPicture, contact.getPhotoUri(), contact.getThumbnailUri());
}
} else { } else {
contactPicture.setImageResource(R.drawable.avatar); holder.contactPicture.setImageResource(R.drawable.avatar);
} }
if (unreadMessagesCount > 0) { if (unreadMessagesCount > 0) {
unreadMessages.setVisibility(View.VISIBLE); holder.unreadMessages.setVisibility(View.VISIBLE);
unreadMessages.setText(String.valueOf(unreadMessagesCount)); holder.unreadMessages.setText(String.valueOf(unreadMessagesCount));
if(unreadMessagesCount > 99){ if (unreadMessagesCount > 99) {
unreadMessages.setTextSize(12); holder.unreadMessages.setTextSize(12);
} }
displayName.setTypeface(null, Typeface.BOLD); holder.displayName.setTypeface(null, Typeface.BOLD);
} else { } else {
unreadMessages.setVisibility(View.GONE); holder.unreadMessages.setVisibility(View.GONE);
displayName.setTypeface(null, Typeface.NORMAL); holder.displayName.setTypeface(null, Typeface.NORMAL);
} }
if (isEditMode) { if (isEditMode) {
unreadMessages.setVisibility(View.GONE); holder.unreadMessages.setVisibility(View.GONE);
select.setVisibility(View.VISIBLE); holder.select.setVisibility(View.VISIBLE);
select.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { holder.select.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) { public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
chatList.setItemChecked(position, b); chatList.setItemChecked(position, b);
@ -450,13 +469,13 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
} }
}); });
if(chatList.isItemChecked(position)) { if(chatList.isItemChecked(position)) {
select.setChecked(true); holder.select.setChecked(true);
} else { } else {
select.setChecked(false); holder.select.setChecked(false);
} }
} else { } else {
if (unreadMessagesCount > 0) { if (unreadMessagesCount > 0) {
unreadMessages.setVisibility(View.VISIBLE); holder.unreadMessages.setVisibility(View.VISIBLE);
} }
} }
return view; return view;

View file

@ -30,6 +30,7 @@ import org.linphone.core.PresenceActivityType;
import android.app.Dialog; import android.app.Dialog;
import android.app.Fragment; import android.app.Fragment;
import android.graphics.Bitmap;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
@ -416,6 +417,28 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
} }
class ContactsListAdapter extends BaseAdapter implements SectionIndexer { class ContactsListAdapter extends BaseAdapter implements SectionIndexer {
private class ViewHolder {
public CheckBox delete;
public ImageView linphoneFriend;
public TextView name;
public LinearLayout separator;
public TextView separatorText;
public ImageView contactPicture;
public TextView organization;
public ImageView friendStatus;
public ViewHolder(View view) {
delete = (CheckBox) view.findViewById(R.id.delete);
linphoneFriend = (ImageView) view.findViewById(R.id.friendLinphone);
name = (TextView) view.findViewById(R.id.name);
separator = (LinearLayout) view.findViewById(R.id.separator);
separatorText = (TextView) view.findViewById(R.id.separator_text);
contactPicture = (ImageView) view.findViewById(R.id.contact_picture);
organization = (TextView) view.findViewById(R.id.contactOrganization);
friendStatus = (ImageView) view.findViewById(R.id.friendStatus);
}
}
private List<LinphoneContact> contacts; private List<LinphoneContact> contacts;
String[] sections; String[] sections;
ArrayList<String> sectionsList; ArrayList<String> sectionsList;
@ -461,58 +484,57 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
LinphoneContact contact = (LinphoneContact) getItem(position); LinphoneContact contact = (LinphoneContact) getItem(position);
if (contact == null) return null; if (contact == null) return null;
ViewHolder holder = null;
if (convertView != null) { if (convertView != null) {
view = convertView; view = convertView;
holder = (ViewHolder) view.getTag();
} else { } else {
view = mInflater.inflate(R.layout.contact_cell, parent, false); view = mInflater.inflate(R.layout.contact_cell, parent, false);
holder = new ViewHolder(view);
view.setTag(holder);
} }
CheckBox delete = (CheckBox) view.findViewById(R.id.delete);
ImageView linphoneFriend = (ImageView) view.findViewById(R.id.friendLinphone);
TextView name = (TextView) view.findViewById(R.id.name); holder.name.setText(contact.getFullName());
name.setText(contact.getFullName());
LinearLayout separator = (LinearLayout) view.findViewById(R.id.separator);
TextView separatorText = (TextView) view.findViewById(R.id.separator_text);
if (getPositionForSection(getSectionForPosition(position)) != position) { if (getPositionForSection(getSectionForPosition(position)) != position) {
separator.setVisibility(View.GONE); holder.separator.setVisibility(View.GONE);
} else { } else {
separator.setVisibility(View.VISIBLE); holder.separator.setVisibility(View.VISIBLE);
String fullName = contact.getFullName(); String fullName = contact.getFullName();
if (fullName != null && !fullName.isEmpty()) { if (fullName != null && !fullName.isEmpty()) {
separatorText.setText(String.valueOf(fullName.charAt(0))); holder.separatorText.setText(String.valueOf(fullName.charAt(0)));
} }
} }
if (contact.isInLinphoneFriendList()) { if (contact.isInLinphoneFriendList()) {
linphoneFriend.setVisibility(View.VISIBLE); holder.linphoneFriend.setVisibility(View.VISIBLE);
} else { } else {
linphoneFriend.setVisibility(View.GONE); holder.linphoneFriend.setVisibility(View.GONE);
} }
ImageView icon = (ImageView) view.findViewById(R.id.contact_picture);
if (contact.hasPhoto()) { if (contact.hasPhoto()) {
LinphoneUtils.setImagePictureFromUri(getActivity(), icon, contact.getPhotoUri(), contact.getThumbnailUri()); Bitmap photo = contact.getPhoto();
} else if (contact.getPhotoUri() != null) { if (photo != null) {
icon.setImageURI(contact.getPhotoUri()); holder.contactPicture.setImageBitmap(photo);
} else {
LinphoneUtils.setImagePictureFromUri(getActivity(), holder.contactPicture, contact.getPhotoUri(), contact.getThumbnailUri());
}
} else { } else {
icon.setImageResource(R.drawable.avatar); holder.contactPicture.setImageResource(R.drawable.avatar);
} }
TextView organization = (TextView) view.findViewById(R.id.contactOrganization);
boolean isOrgVisible = getResources().getBoolean(R.bool.display_contact_organization); boolean isOrgVisible = getResources().getBoolean(R.bool.display_contact_organization);
String org = contact.getOrganization(); String org = contact.getOrganization();
if (org != null && !org.isEmpty() && isOrgVisible) { if (org != null && !org.isEmpty() && isOrgVisible) {
organization.setText(org); holder.organization.setText(org);
organization.setVisibility(View.VISIBLE); holder.organization.setVisibility(View.VISIBLE);
} else { } else {
organization.setVisibility(View.GONE); holder.organization.setVisibility(View.GONE);
} }
if (isEditMode) { if (isEditMode) {
delete.setVisibility(View.VISIBLE); holder.delete.setVisibility(View.VISIBLE);
delete.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { holder.delete.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) { public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
contactsList.setItemChecked(position, b); contactsList.setItemChecked(position, b);
@ -534,29 +556,28 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
} }
}); });
if (contactsList.isItemChecked(position)) { if (contactsList.isItemChecked(position)) {
delete.setChecked(true); holder.delete.setChecked(true);
} else { } else {
delete.setChecked(false); holder.delete.setChecked(false);
} }
} else { } else {
delete.setVisibility(View.GONE); holder.delete.setVisibility(View.GONE);
} }
ImageView friendStatus = (ImageView) view.findViewById(R.id.friendStatus);
LinphoneFriend[] friends = LinphoneManager.getLc().getFriendList(); LinphoneFriend[] friends = LinphoneManager.getLc().getFriendList();
if (!ContactsManager.getInstance().isContactPresenceDisabled() && friends != null) { if (!ContactsManager.getInstance().isContactPresenceDisabled() && friends != null) {
friendStatus.setVisibility(View.VISIBLE); holder.friendStatus.setVisibility(View.VISIBLE);
PresenceActivityType presenceActivity = friends[0].getPresenceModel().getActivity().getType(); PresenceActivityType presenceActivity = friends[0].getPresenceModel().getActivity().getType();
if (presenceActivity == PresenceActivityType.Online) { if (presenceActivity == PresenceActivityType.Online) {
friendStatus.setImageResource(R.drawable.led_connected); holder.friendStatus.setImageResource(R.drawable.led_connected);
} else if (presenceActivity == PresenceActivityType.Busy) { } else if (presenceActivity == PresenceActivityType.Busy) {
friendStatus.setImageResource(R.drawable.led_error); holder.friendStatus.setImageResource(R.drawable.led_error);
} else if (presenceActivity == PresenceActivityType.Away) { } else if (presenceActivity == PresenceActivityType.Away) {
friendStatus.setImageResource(R.drawable.led_inprogress); holder.friendStatus.setImageResource(R.drawable.led_inprogress);
} else if (presenceActivity == PresenceActivityType.Offline) { } else if (presenceActivity == PresenceActivityType.Offline) {
friendStatus.setImageResource(R.drawable.led_disconnected); holder.friendStatus.setImageResource(R.drawable.led_disconnected);
} else { } else {
friendStatus.setImageResource(R.drawable.call_quality_indicator_0); holder.friendStatus.setImageResource(R.drawable.call_quality_indicator_0);
} }
} }

View file

@ -31,6 +31,7 @@ import org.linphone.core.LinphoneCallLog.CallStatus;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Dialog; import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle; import android.os.Bundle;
import android.app.Fragment; import android.app.Fragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@ -349,6 +350,22 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
} }
class CallHistoryAdapter extends BaseAdapter { 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) { CallHistoryAdapter(Context aContext) {
} }
@ -401,23 +418,20 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
public View getView(final int position, View convertView, ViewGroup parent) { public View getView(final int position, View convertView, ViewGroup parent) {
View view = null; View view = null;
ViewHolder holder; ViewHolder holder = null;
if (convertView != null) { if (convertView != null) {
view = convertView; view = convertView;
holder = (ViewHolder) view.getTag(); holder = (ViewHolder) view.getTag();
} else { } else {
view = mInflater.inflate(R.layout.history_cell, parent,false); view = mInflater.inflate(R.layout.history_cell, parent,false);
holder = new ViewHolder(); holder = new ViewHolder(view);
holder.contact = (TextView) view.findViewById(R.id.sip_uri); view.setTag(holder);
holder.detail = (ImageView) view.findViewById(R.id.detail);
holder.select = (CheckBox) view.findViewById(R.id.delete);
holder.callDirection = (ImageView) view.findViewById(R.id.icon);
holder.contactPicture = (ImageView) view.findViewById(R.id.contact_picture);
} }
final LinphoneCallLog log = mLogs.get(position); final LinphoneCallLog log = mLogs.get(position);
long timestamp = log.getTimestamp(); long timestamp = log.getTimestamp();
final LinphoneAddress address; LinphoneAddress address;
holder.contact.setSelected(true); // For automated horizontal scrolling of long texts holder.contact.setSelected(true); // For automated horizontal scrolling of long texts
@ -457,9 +471,18 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
LinphoneContact c = ContactsManager.getInstance().findContactFromAddress(address); LinphoneContact c = ContactsManager.getInstance().findContactFromAddress(address);
String displayName = null; String displayName = null;
final String sipUri = address.asString(); final String sipUri = address.asString();
if(c != null){ if (c != null) {
displayName = c.getFullName(); displayName = c.getFullName();
LinphoneUtils.setImagePictureFromUri(view.getContext(),holder.contactPicture,c.getPhotoUri(),c.getThumbnailUri()); if (c.hasPhoto()) {
Bitmap photo = c.getPhoto();
if (photo != null) {
holder.contactPicture.setImageBitmap(photo);
} else {
LinphoneUtils.setImagePictureFromUri(getActivity(), holder.contactPicture, c.getPhotoUri(), c.getThumbnailUri());
}
} else {
LinphoneUtils.setImagePictureFromUri(getActivity(), holder.contactPicture, c.getPhotoUri(), c.getThumbnailUri());
}
} else { } else {
holder.contactPicture.setImageResource(R.drawable.avatar); holder.contactPicture.setImageResource(R.drawable.avatar);
} }
@ -469,7 +492,6 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
} else { } else {
holder.contact.setText(displayName); holder.contact.setText(displayName);
} }
//view.setTag(sipUri);
if (isEditMode) { if (isEditMode) {
holder.select.setVisibility(View.VISIBLE); holder.select.setVisibility(View.VISIBLE);
@ -512,16 +534,7 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On
} }
}); });
} }
view.setTag(holder);
return view; return view;
} }
} }
static class ViewHolder {
TextView contact;
ImageView detail;
CheckBox select;
ImageView callDirection;
ImageView contactPicture;
}
} }

View file

@ -18,6 +18,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
package org.linphone; package org.linphone;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -38,8 +40,10 @@ import android.content.ContentResolver;
import android.content.ContentUris; import android.content.ContentUris;
import android.content.ContentValues; import android.content.ContentValues;
import android.database.Cursor; import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri; import android.net.Uri;
import android.provider.ContactsContract; import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.provider.ContactsContract.CommonDataKinds; import android.provider.ContactsContract.CommonDataKinds;
public class LinphoneContact implements Serializable, Comparable<LinphoneContact> { public class LinphoneContact implements Serializable, Comparable<LinphoneContact> {
@ -55,6 +59,7 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
private transient ArrayList<ContentProviderOperation> changesToCommit; private transient ArrayList<ContentProviderOperation> changesToCommit;
private transient ArrayList<ContentProviderOperation> changesToCommit2; private transient ArrayList<ContentProviderOperation> changesToCommit2;
private boolean hasSipAddress; private boolean hasSipAddress;
private Bitmap photoBitmap, thumbnailBitmap;
public LinphoneContact() { public LinphoneContact() {
addresses = new ArrayList<LinphoneNumberOrAddress>(); addresses = new ArrayList<LinphoneNumberOrAddress>();
@ -66,6 +71,19 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
hasSipAddress = false; hasSipAddress = false;
} }
@Override
protected void finalize() throws Throwable {
if (photoBitmap != null) {
photoBitmap.recycle();
photoBitmap = null;
}
if (thumbnailBitmap != null) {
thumbnailBitmap.recycle();
thumbnailBitmap = null;
}
super.finalize();
}
@Override @Override
public int compareTo(LinphoneContact contact) { public int compareTo(LinphoneContact contact) {
String fullName = getFullName(); String fullName = getFullName();
@ -167,21 +185,62 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
} }
public void setPhotoUri(Uri uri) { public void setPhotoUri(Uri uri) {
if (uri.equals(photoUri)) return;
photoUri = uri; photoUri = uri;
if (photoBitmap != null) {
photoBitmap.recycle();
}
try {
photoBitmap = MediaStore.Images.Media.getBitmap(ContactsManager.getInstance().getContentResolver(), photoUri);
} catch (FileNotFoundException e) {
Log.e(e);
} catch (IOException e) {
Log.e(e);
}
} }
public Uri getPhotoUri() { public Uri getPhotoUri() {
return photoUri; return photoUri;
} }
public Bitmap getPhotoBitmap() {
return photoBitmap;
}
public void setThumbnailUri(Uri uri) { public void setThumbnailUri(Uri uri) {
if (uri.equals(thumbnailUri)) return;
thumbnailUri = uri; thumbnailUri = uri;
if (thumbnailBitmap != null) {
thumbnailBitmap.recycle();
}
try {
thumbnailBitmap = MediaStore.Images.Media.getBitmap(ContactsManager.getInstance().getContentResolver(), thumbnailUri);
} catch (FileNotFoundException e) {
Log.e(e);
} catch (IOException e) {
Log.e(e);
}
} }
public Uri getThumbnailUri() { public Uri getThumbnailUri() {
return thumbnailUri; return thumbnailUri;
} }
public Bitmap getThumbnailBitmap() {
return thumbnailBitmap;
}
public Bitmap getPhoto() {
if (photoBitmap != null) {
return photoBitmap;
} else if (thumbnailBitmap != null) {
return thumbnailBitmap;
}
return null;
}
public void setPhoto(byte[] photo) { public void setPhoto(byte[] photo) {
if (photo != null) { if (photo != null) {
if (isAndroidContact()) { if (isAndroidContact()) {

View file

@ -30,9 +30,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
@ -76,7 +74,6 @@ import org.linphone.tools.OpenH264DownloadHelper;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
@ -86,10 +83,6 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources; import android.content.res.Resources;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.AudioManager; import android.media.AudioManager;
import android.media.MediaPlayer; import android.media.MediaPlayer;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
@ -104,11 +97,6 @@ import android.preference.CheckBoxPreference;
import android.provider.Settings; import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException; import android.provider.Settings.SettingNotFoundException;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.Toast; import android.widget.Toast;
/** /**