HorizontalScrollView: CustomAdapter with getView () does not use re-convertible items of type ListView

In one of my past projects, I implemented the Carousel of Time. It is based on HorizontalScrollView . The user can select the time by scrolling through this view. The time value is calculated from the X-offset of the HorizontalScrollView .

enter image description here

I wanted to share this project on github, but when clearing the code, I realized the problem with a bad indicator .

HorizontalScrollView populated with a custom ArrayAdapter . getView() uses Holder for convertView . I thought this could work as an adapter within a ListView , so only visible items are displayed and reused if they are destroyed. Instead, all items are displayed !!! (in my case, 1008!) I add them myself (# 1 in the sample code), but even if I try to add less, the logic from deleting (and reusing) old ones does not work or am I missing something?

So my main question is: What do I need to change to make my adapter behave like a ListView ?

  • I found this this link and tried to override the remove function, but it is never called (somehow logical, because I only add)
  • There is a good PagerAdapter example on github , but for some reason I can't translate this to an ArrayAdapter<String>

Any thoughts, links are welcome!

And please do not suggest using ListView instead. We decided to use HorizontalScrollView because of the callbacks and the fact that 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); } 
+3
android android-adapter horizontalscrollview
Oct 13 '14 at 13:48
source share
2 answers

I think maybe you are confusing where the logic is in rendering between View and Adapter. Using an adapter does not change the view mode. This is ListView itself, along with its parent AbsListView , which implements the behavior of the view's recirculation. An adapter is required by ListView to correctly fill in the Views that are displayed on the screen as needed, but the logic for actually choosing which views to display and when and how to process these views is not at all included in the adapter.

If you look at the source code of HorizontalScrollView and ListView , you will see that they are very different from each other. This is not the same thing in different orientations.

So the long and short of them is that you cannot get the revised version of the view you are looking for using HorizontalScrollView or even a simple descendant. If you want to view recycling, you should check out RecyclerView .

+14
Oct. 15 '14 at 13:49
source share

ScrollView stores all child views in memory, so a performance issue is common when used.

Why not use some open source HorizontalListView library. When searching, I got these two libraries, of which I used the first in one of my projects, and it worked smoothly without any memory problems.

These libraries are a horizontal implementation of ListView that does the recycling of items for you based on what views are visible on the screen. Scrollview is a poor choice for scrolling with scroll.

UPDATE . Now we have a RecyclerView from Android that supports horizontal scrolling and also applies a Viewholder template

+2
Oct. 20 '14 at 4:55
source share



All Articles