Reputation: 886
I am currently working on a ListView
that contains around 80 to 100 items (TextViews
). I don't think it is too much content, but when i scroll (with fingers) the ListView
is bobbing or laging. However, when I use the "fast-scroll-button" - that thing on the right of the ListView
- the scrolling appears very consistent and smooth.
Did anyone have the same problem? I tested the ListView
on my HTC Sensation.
Here is my ListView code:
<ListView
android:id="@+id/list_view"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:scrollingCache="true">
</ListView>
And the Java code:
adptr = new ArrayAdapter<String>(iF, R.layout.list_item, showing) {
@Override
public View getView(int position, View convertView, ViewGroup grp) {
LinearLayout lin = new LinearLayout(this.getContext());
lin.setOrientation(LinearLayout.HORIZONTAL);
// Icon
ImageView v = new ImageView(this.getContext());
// v.setBackgroundDrawable(iF.getResources().getDrawable(R.drawable.cube_icon));
// Text
TextView txt = new TextView(this.getContext());
txt.setTextSize(Float.valueOf(prefs.getString("pref_txtSize", "12")));
txt.setPadding(10, 10, 10, 10);
txt.setText(this.getItem(position));
txt.setTextColor(getLineColor(position));
// Shortcut
LinearLayout shortLin = new LinearLayout(this.getContext());
shortLin.setGravity(Gravity.RIGHT);
LayoutParams par = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
shortLin.setLayoutParams(par);
TextView s = new TextView(this.getContext());
s.setTextSize(Float.valueOf(prefs.getString("pref_txtSize", "12")));
s.setWidth(iF.getResources().getDimensionPixelSize(R.dimen.shortcutWidth));
s.setPadding(10, 10, 10, 10);
s.setText(getShortcut(position));
shortLin.addView(s);
// Return
txt.invalidate();
v.invalidate();
s.invalidate();
lin.addView(v);
lin.addView(txt);
lin.addView(shortLin);
return lin;
}
};
As you can see, I made a customized ListView
. The ArrayAdapter
will be added in a different method (not shown here).
Thanks in advance
Adrian
Upvotes: 0
Views: 2184
Reputation: 886
Finally, I came up with this solution:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) iF.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.list_item, parent, false);
holder = new ViewHolder();
holder.title = (TextView) view.findViewById(R.id.item_text);
holder.shortcut = (TextView) view.findViewById(R.id.item_short);
holder.title.setId(1);
holder.shortcut.setId(2);
holder.title.setText(getItem((position)));
holder.shortcut.setText(getShortcut(position));
holder.title.setTextSize(Float.valueOf(prefs.getString("pref_txtSize", "12")));
holder.shortcut.setTextSize(Float.valueOf(prefs.getString("prefs_txtSize", "12")));
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
TextView title = (TextView) convertView.findViewById(1);
title.setText(getItem(position));
TextView shortcut = (TextView) convertView.findViewById(2);
shortcut.setText(getShortcut(position));
}
return view;
}
I am really happy right now that it worked. It is 00:33, so I think I go to bed now. Enough work for today (yesterday :)
Thanks for all the support
Upvotes: 0
Reputation: 8176
You're creating every View
element for your list dynamically every time you pull a view. That's possibly the most inefficient mechanism ever :).
As a first step, see if you can layout your view in XML. Makes things easier to manage.
Even if you don't do that, use the convertView
parameter. Its sole reason for existence is to keep you from having to reallocate views if possible. If convertView
is non-null, it has all the views you created in a previous invocation of getView()
. All you have to do is fill in the appropriate information in each view (essentially, in your case, the setText()
calls). If convertView
is null, create your views.
Also, don't invalidate()
. At a minimum, without the XML layout, here's a rewritten version that should be a bit faster.
@Override
public View getView(int position, View convertView, ViewGroup grp) {
if(convertView == null) {
LinearLayout lin = new LinearLayout(this.getContext());
lin.setOrientation(LinearLayout.HORIZONTAL);
// Icon
ImageView v = new ImageView(this.getContext());
// v.setBackgroundDrawable(iF.getResources().getDrawable(R.drawable.cube_icon));
// Text
TextView txt = new TextView(this.getContext());
txt.setId(1);
txt.setTextSize(Float.valueOf(prefs.getString("pref_txtSize", "12")));
txt.setPadding(10, 10, 10, 10);
txt.setTextColor(getLineColor(position));
// Shortcut
LinearLayout shortLin = new LinearLayout(this.getContext());
shortLin.setGravity(Gravity.RIGHT);
LayoutParams par = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
shortLin.setLayoutParams(par);
TextView s = new TextView(this.getContext());
s.setId(2);
s.setTextSize(Float.valueOf(prefs.getString("pref_txtSize", "12")));
s.setWidth(iF.getResources().getDimensionPixelSize(R.dimen.shortcutWidth));
s.setPadding(10, 10, 10, 10);
shortLin.addView(s);
lin.addView(v);
lin.addView(txt);
lin.addView(shortLin);
}
TextView txt = (TextView)convertView.findViewById(1);
txt.setText(this.getItem(position));
TextView txt = (TextView)convertView.findViewById(2);
txt.setText(getShortcut(position));
return lin;
}
Again, not the best way or a best practice, but this should work.
Upvotes: 2
Reputation: 814
Do you remember about cache?
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater
.inflate(R.layout.list_view_home_item, parent, false);
holder = new ViewHolder();
holder.title = (TextView) view
.findViewById(R.id.textView);
holder.title.setText("blah");
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
return view;
and
static class ViewHolder {
TextView title;
}
?
Upvotes: 4