Reputation: 583
I hope anyone can help me with the ListView problem I got.I have been slamming my head against a iron wall yesterday because i could not figure out what the problem was. It's not originally my project which makes it even harder.
I got a listview where I wanna load rows of contacts in. On the left side of each row I wanna (Down)load an Image async. For this i am using the following ArrayAdapter and ListItem layout, please ignore the deprecated functions.
Here is a video http://www.youtube.com/watch?v=aMqI9_y3pag&feature=youtu.be
PROBLEM: Whenever the list loads all the images get loaded over each other and after that beeing placed in the correct spot. It looks really glitchy and even though it responds quick and all it looks horrible. I added a counter in my arrayadapter to count the times getView gets called.
Hopefully someone can help me!
ArrayAdapter
public class ChatContactListArrayAdapter extends ArrayAdapter<ChatContact>{
private Context context;
private ArrayList<ChatContact> chatContacts;
public static DiskImageLoaderHelper diskImageLoader;
public int count = 0;
public ChatContactListArrayAdapter(Context context, int resource, ArrayList<ChatContact> chatContacts) {
super(context, resource, chatContacts);
this.chatContacts = chatContacts;
this.context = context;
diskImageLoader = new DiskImageLoaderHelper(context, "ChatListImages", (1024 * 1024 * 10), CompressFormat.JPEG, 90);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
count++;
Log.e(DebugHelper.TAG_DEBUG, "Count: " + count + " Position: " + position);
ChatContact chatContact = chatContacts.get(position);
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.chat_contact_list_row, null);
}
ImageView contactImageView = (ImageView) view.findViewById(R.id.contact_image);
if (chatContact.Picture != null) {
BitmapWorkerTask bitmapWorker = new BitmapWorkerTask(contactImageView, diskImageLoader);
bitmapWorker.execute(chatContact.Picture);
} else {
contactImageView.setVisibility(View.INVISIBLE);
}
TextView fromTextView = (TextView) view.findViewById(R.id.fromName);
fromTextView.setText(chatContact.Name);
Boolean l_blToMe = false;
if (chatContact.From == chatContact.Id) {
l_blToMe = true;
}
LinearLayout chatContactRow = (LinearLayout) view.findViewById(R.id.chatContactRow);
ImageView imageViewStatusMessage = (ImageView) view.findViewById(R.id.lastMessageStatusImg);
TextView lastMessage = (TextView) view.findViewById(R.id.lastMessage);
if (CommonUtilities.isNullOrEmpty(chatContact.Message) && !CommonUtilities.isNullOrEmpty(chatContact.MessageId)) {
lastMessage.setText("<afbeelding>");
} else {
lastMessage.setText(chatContact.Message);
}
imageViewStatusMessage.setImageResource(0);
if (!CommonUtilities.isNullOrEmpty(chatContact.Received)) {
imageViewStatusMessage.setImageDrawable(context.getResources().getDrawable(R.drawable.chat_double_check));
chatContactRow.setBackgroundColor(Color.parseColor("#F2F2F2"));
lastMessage.setTypeface(null, Typeface.NORMAL);
} else if (!CommonUtilities.isNullOrEmpty(chatContact.Sent) && !l_blToMe) {
imageViewStatusMessage.setImageDrawable(context.getResources().getDrawable(R.drawable.chat_single_check));
chatContactRow.setBackgroundColor(Color.parseColor("#F2F2F2"));
lastMessage.setTypeface(null, Typeface.NORMAL);
} else if (!CommonUtilities.isNullOrEmpty(chatContact.Sent) && l_blToMe) {
imageViewStatusMessage.setImageDrawable(context.getResources().getDrawable(R.drawable.chat_arrow));
chatContactRow.setBackgroundColor(Color.parseColor("#F4E0CC"));
lastMessage.setTypeface(null, Typeface.BOLD);
} else {
imageViewStatusMessage.setVisibility(View.INVISIBLE);
}
TextView receivedDate = (TextView) view.findViewById(R.id.receivedDate);
if (!CommonUtilities.isNullOrEmpty(chatContact.Sent) && CommonUtilities.isNullOrEmpty(chatContact.Received)) {
try {
SimpleDateFormat l_dbDateFormatter = new SimpleDateFormat("yyyyMMddHHmmss");
Date l_dOrgDate = (Date) l_dbDateFormatter.parse(chatContact.Sent);
SimpleDateFormat l_showDateFormatter = new SimpleDateFormat("dd-MM-yyyy HH:mm");
String newDateStr = l_showDateFormatter.format(l_dOrgDate);
receivedDate.setText(newDateStr);
} catch (ParseException e) {
Log.e(DebugHelper.TAG_ERROR, "ChatContactListAdapter::" + e.toString());
// ACRA.getErrorReporter().handleSilentException(e);
}
} else if (!CommonUtilities.isNullOrEmpty(chatContact.Received)) {
try {
SimpleDateFormat l_dbDateFormatter = new SimpleDateFormat(
"yyyyMMddHHmmss");
Date l_dOrgDate = (Date) l_dbDateFormatter.parse(chatContact.Received);
SimpleDateFormat l_showDateFormatter = new SimpleDateFormat(
"dd-MM-yyyy HH:mm");
String newDateStr = l_showDateFormatter.format(l_dOrgDate);
receivedDate.setText(newDateStr);
} catch (ParseException e) {
Log.e(DebugHelper.TAG_ERROR, "ChatContactListAdapter::" + e.toString());
// ACRA.getErrorReporter().handleSilentException(e);
}
} else {
receivedDate.setVisibility(View.INVISIBLE);
}
return view;
}
@Override
public void clear() {
count = 0;
super.clear();
}
class BitmapWorkerTask extends AsyncTask<String, Void, Drawable> {
private final WeakReference<ImageView> contactImageView;
private DiskImageLoaderHelper diskImageLoader;
public BitmapWorkerTask(ImageView imageView, DiskImageLoaderHelper diskImageLoader) {
this.contactImageView = new WeakReference<ImageView>(imageView);
this.diskImageLoader = diskImageLoader;
}
@Override
protected Drawable doInBackground(String... params) {
String imageUrl = params[0];
Bitmap bitmap = null;
if (!diskImageLoader.containsKey(CommonUtilities.filePathToCacheKey(imageUrl, false)) || false) {
bitmap = CommonUtilities.getCroppedBitmap(CommonUtilities.createBitmapFromImageLocation(CommonUtilities.mStrBasePath + imageUrl), 50);
if(bitmap != null) {
diskImageLoader.put(CommonUtilities.filePathToCacheKey(imageUrl, true), bitmap);
}
} else {
bitmap = diskImageLoader.getBitmap(CommonUtilities.filePathToCacheKey(imageUrl, false));
}
return new BitmapDrawable(context.getResources(), bitmap);
}
@Override
protected void onPostExecute(Drawable drawable) {
ImageView view = contactImageView.get();
if (view != null && drawable != null) {
view.setBackgroundDrawable(drawable);
// contactImageView.setImageBitmap(bitmap);
view.setImageDrawable(context.getResources().getDrawable(R.drawable.image_round_overlay_grey));
}
}
}
}
ListViewItem Layout
<?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="wrap_content"
android:background="@drawable/chat_contact_list_selector"
android:orientation="horizontal"
android:id="@+id/chatContactRow" >
<ImageView
android:id="@+id/contact_image"
android:layout_width="55dp"
android:layout_height="55dp"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:layout_marginLeft="5dp"
android:src="@drawable/image_round_overlay_grey"/>
<LinearLayout
android:id="@+id/TextualHolder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:baselineAligned="false">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:baselineAligned="false">
<TextView
android:id="@+id/fromName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:layout_marginTop="10dp"
android:paddingBottom="10dip"
android:textColor="#222222"
android:ellipsize="end"
android:singleLine="true"
android:textSize="18sp" />
<TextView
android:id="@+id/receivedDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="15dp"
android:layout_marginTop="10dp"
android:layout_alignParentRight="true"
android:paddingBottom="10dip"
android:textColor="#777777"
android:textSize="10sp"
android:textStyle="bold" />
</RelativeLayout>
<LinearLayout
android:id="@+id/statusMessageHolder"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginLeft="10dip"
android:paddingBottom="10dip" >
<ImageView
android:id="@+id/lastMessageStatusImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical" />
<TextView
android:id="@+id/lastMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#777777"
android:textSize="15sp"
android:ellipsize="end"
android:singleLine="true"
android:textStyle="bold"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
OnCreate in my sherlockFragment
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
context = getActivity().getApplicationContext();
mLvContactList = (ListView) getView().findViewById(R.id.listContacts);
if(mDbDataBase == null)
mDbDataBase = nl.w3s.hulpverlener.JohelpenApplication.mDbDataBase;
if(mCurDB == null)
mCurDB = nl.w3s.hulpverlener.JohelpenApplication.mCurDB;
mCursor = mCurDB.query(mTblChatContacts.mTable, mDbDataBase.dbFieldsToString(mTblChatContacts.mFields), null, null, null, null, null);
chatContacts = CommonUtilities.getContactsFromCursor(mCursor);
mCursor.close();
chatContactArrayAdapter = new ChatContactListArrayAdapter(getActivity(), R.layout.chat_contact_list_row, chatContacts);
mLvContactList.setAdapter(chatContactArrayAdapter);
mLvContactList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent,
final View view, int position, long id) {
ChatContact chatContact = (ChatContact) parent.getItemAtPosition(position);
ChatFragment chatFragment = new ChatFragment(chatContact.Id);
mMainObject.switchContent(chatFragment, true);
}
});
getSherlockActivity().getSupportActionBar().setIcon(R.drawable.icon_ab_chat);
getSherlockActivity().getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
MainActivity.mMenuLayout = -1;
getSherlockActivity().invalidateOptionsMenu();
setStatusMessage();
mMainObject.setTitle(mTitle);
}
Upvotes: 3
Views: 1118
Reputation: 747
I just spent several hours trying to figure out why this was happening for my list view when I was asynchronously loading images for each row. It turns out that the list view has to have "match_parent" for the width and height set in the XML. Truly strange and weird bug.
Upvotes: 1
Reputation: 109237
Actually main problem is you didn't add else condition statement in most of your if
condition statements in getView()
method of custom adapter.
Like,
put else
here
if (chatContact.Picture != null) {
BitmapWorkerTask bitmapWorker = new BitmapWorkerTask(contactImageView, diskImageLoader);
bitmapWorker.execute(chatContact.Picture);
}
else
{
contactImageView.setImageResource(R.id.icon); // only for your reference.. add default image
}
Add else
statement in your all if-else if
statement for list item row views. Either make them gone in visibility or assign blank text or default images.
Update: As I doubt this scenario because of reference view of list row.
remove this code,
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.chat_contact_list_row, null);
}
Just use,
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.chat_contact_list_row, null);
Upvotes: 3