Reputation: 303
Folks.
I've a problem with my listview. I used the ViewHolder to optimize the performance but i still get some listview lagging. Can you please advice ?
This is my ListView XML
<ListView
android:id="@+id/list1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="@android:color/transparent"
android:dividerHeight="10dp"
android:fadingEdge="none"
android:fastScrollEnabled="true"
android:headerDividersEnabled="false"
android:listSelector="@android:color/transparent"
android:scrollingCache="false" />
Also This is my Custom SimplecursorAdapter with ViewHolder implemented for recycling
public class AlternateRowCursorAdapter extends SimpleCursorAdapter {
int layoutn;
LayoutInflater mInflater;
SQLiteDatabase mDb;
MyDbHelper mHelper;
private final Cursor mCursor;
private final int mLayout;
private final LayoutInflater mLayoutInflater;
private final Context mContext;
public static final String TABLE_NAME = "MSGS";
public AlternateRowCursorAdapter(Context context, int layout, Cursor c,
String[] from, int[] to) {
super(context, R.layout.listtype, c, from, to);
this.mContext = context;
this.mCursor = c;
this.mLayout = layout;
this.mLayoutInflater = LayoutInflater.from(context);
}
private final class ViewHolder {
public TextView Title;
public ImageView one, two, three, four, five, six, seven, zina;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (mCursor.moveToPosition(position)) {
final ViewHolder viewHolder;
if (convertView == null) {
convertView = mLayoutInflater.inflate(mLayout, parent, false);
viewHolder = new ViewHolder();
viewHolder.Title = (TextView) convertView
.findViewById(R.id.Sandtit);
viewHolder.one = (ImageView) convertView
.findViewById(R.id.imageView5);
viewHolder.two = (ImageView) convertView
.findViewById(R.id.imageView4);
viewHolder.three = (ImageView) convertView
.findViewById(R.id.ImageView03);
viewHolder.four = (ImageView) convertView
.findViewById(R.id.ImageView02);
viewHolder.five = (ImageView) convertView
.findViewById(R.id.imageView1);
viewHolder.six = (ImageView) convertView
.findViewById(R.id.ImageView06);
viewHolder.seven = (ImageView) convertView
.findViewById(R.id.ImageView01);
viewHolder.zina = (ImageView) convertView
.findViewById(R.id.imageView2);
convertView.setTag(viewHolder);
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
final String Title, SandID, MsgID, MsgFav;
Title = mCursor.getString(2);
SandID = mCursor.getString(1);
MsgID = mCursor.getString(0);
MsgFav = mCursor.getString(4);
Typeface tf = Typeface.createFromAsset(mContext.getAssets(),
"fonts/khalaadsara.ttf");
viewHolder.Title.setText(Title);
viewHolder.Title.setTypeface(tf);
try {
mHelper = new MyDbHelper(mContext);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (MsgFav.contentEquals("YES")) {
viewHolder.one.setImageResource(R.drawable.favorpress);
} else {
viewHolder.one.setImageResource(R.drawable.favornorm);
}
mDb = mHelper.getWritableDatabase();
viewHolder.one.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (MsgFav.contentEquals("NO")) {
ContentValues args = new ContentValues();
args.put(mHelper.COL_MsgFavor, "YES");
mDb.update(TABLE_NAME, args, "_id = ?",
new String[] { MsgID });
viewHolder.one.setImageResource(R.drawable.favorpress);
Toast.makeText(
mContext,
"تم إضافة الرسالة إلي الرسائل المفضلة بنجاح...",
9000).show();
notifyDataSetChanged();
mCursor.requery();
}
else {
ContentValues args = new ContentValues();
args.put(mHelper.COL_MsgFavor, "NO");
mDb.update(TABLE_NAME, args, "_id = ?",
new String[] { MsgID });
viewHolder.one.setImageResource(R.drawable.favornorm);
Toast.makeText(mContext,
"تم حذف الرسالة من الرسائل المفضلة بنجاح...",
9000).show();
notifyDataSetChanged();
mCursor.requery();
}
}
});
viewHolder.two.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent emailIntentt = new Intent(
android.content.Intent.ACTION_VIEW);
emailIntentt.setData(Uri.parse("sms:"));
String breaks = "\n";
emailIntentt.putExtra("sms_body", Title);
mContext.startActivity(emailIntentt);
}
});
viewHolder.three.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
viewHolder.Title.setTextSize(TypedValue.COMPLEX_UNIT_PX,
(viewHolder.Title.getTextSize() - 1f));
}
});
viewHolder.four.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent emailIntentt = new Intent(
android.content.Intent.ACTION_SEND);
String breaks = "\n";
String[] recipientss = new String[] {
"من فضلك...أدخل بريدك الأليكتروني", "", };
emailIntentt.putExtra(android.content.Intent.EXTRA_EMAIL,
recipientss);
emailIntentt.putExtra(android.content.Intent.EXTRA_SUBJECT,
"مسجات رمضان 2013");
emailIntentt.putExtra(android.content.Intent.EXTRA_TEXT,
breaks + Title);
emailIntentt.setType("text/plain");
mContext.startActivity(Intent.createChooser(emailIntentt,
"مشاركة بواسطة..."));
}
});
viewHolder.five.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
ClipboardManager ClipMan = (ClipboardManager) mContext
.getSystemService(Context.CLIPBOARD_SERVICE);
ClipMan.setText(Title);
Toast.makeText(mContext, "تم نسخ الرسالة بنجاح....", 9000)
.show();
}
});
viewHolder.six.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
viewHolder.Title.setTextSize(TypedValue.COMPLEX_UNIT_PX,
(viewHolder.Title.getTextSize() + 1f));
}
});
viewHolder.seven.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent waIntent = new Intent(Intent.ACTION_SEND);
if (waIntent != null)
{
waIntent.setType("text/plain");
String text = Title;
waIntent.setPackage("com.whatsapp");
waIntent.putExtra(Intent.EXTRA_TEXT, text);//
mContext.startActivity(Intent.createChooser(waIntent,
"مشاركة بواسطة..."));
}
}
});
}
return convertView;
}
}
Your Help is highly appreciated !
Upvotes: 0
Views: 903
Reputation: 3573
The getView()
method is going to be called EVERY time a new item in a list needs to be populated. Your doing WAY to much in that method to get smooth performance. I would refactor out anything that is not specifically needed to set up the layout and move it somewhere else so it doesnt get called all the time. Especially the listeners and database calls. They don't really need to be in there. Every time a new list item is created, 7 new listener objects are created... OUCH
You can either override onListItemClick()
in the Activity
or Fragment
your using so when the user click on a list item you can then do the needed work. Then you can use the position of the item clicked to determine what the user clicked on. This is the way I would suggest doing it.
OR
You can try to create an inner class for each listener you need and store them in an instance variable so they wont need to be instantiated every time a new list item is displayed. I would not suggest doing it this way however. Its a little stinky and it still might not get rid of the performance problems completely.
Upvotes: 1