In one of my past projects I implemented a "Time Picker Carousel". It is based on a HorizontalScrollView
. The user can pick a time while scrolling this view. The time value is calculated from the X-Offset of the HorizontalScrollView
.
I wanted to share this project at github, but while cleaning up the code I realized some bad performance issue.
The HorizontalScrollView
is populated with a custom ArrayAdapter
. The getView()
uses a Holder
for the convertView
. I thought it might work as an adapter within a ListView
, so only the visible items are rendered and reused if they will be destroyed. Instead, all items are rendered!!! (in my case 1008!) I add them myself (#1 in Code example), but even if I try to add less, the logic from remove (and recycle) old ones doesn't work, or did I miss something?
So my basic question is: What do I have to change to make my adapter behave like ListView
?
- I found this so link and tried overriding
remove
function, but this is never called (somehow logic, because i am only adding) - There's a good PagerAdapter example at github, but somehow I cannot translate this to
ArrayAdapter<String>
Any thoughts, links are welcome!
And please don't suggest using ListView
instead. We decided to use HorizontalScrollView
because of callbacks and the fact we already have a ListView
in the layout.
HorizontalScrollView
InfiniteTimeScrubberHorizontalView extends HorizontalScrollView{
...
public void setAdapter(Context context, TimeScrubberListAdapter mAdapter) {
this.mAdapter = mAdapter;
try {
fillViewWithAdapter(mAdapter);
} catch (ZeroChildException e) {
e.printStackTrace();
}
}
private void fillViewWithAdapter(TimeScrubberListAdapter mAdapter) {
//...
ViewGroup parent = (ViewGroup) getChildAt(0);
parent.removeAllViews();
for (int i = 0; i < mAdapter.getCount(); i++) {
//#1: Here: ALL views are added
parent.addView(mAdapter.getView(i, null, parent));
}
}
Adpater
public class TimeScrubberListAdapter extends ArrayAdapter<String> {
//...
private ArrayList<String> list; //list from 0:00,0:30...23:00,23:30
final static int MAXIMUM_DAYS = 21
@Override
public int getCount() {
return list.size() * MAXIMUM_DAYS;
}
@Override
public String getItem(int position) {
return list.get(position % list.size());
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
RelativeLayout layout;
if (convertView == null) {
layout = (RelativeLayout) View.inflate(context, layoutId, null);
holder = new Holder();
holder.title = (TextView) layout.findViewById(R.id.epg_item_text);
layout.setTag(holder);
} else {
layout = (RelativeLayout) convertView;
view = layout;
holder = (Holder) layout.getTag();
}
layout.setLayoutParams(mLP);
String timeValue = getItem(position);
holder.title.setText(timeValue);
return layout;
}
//...
@Override
public void remove(String object) {
//not called...some how logic, because i do not remove an item
super.remove(object);
}