Horizo​​ntalScrollView:带有getView()的CustomAdapter不会重用像ListView这样的convertViews

lon*_*ngi 3 android horizontalscrollview android-adapter

在我过去的一个项目中,我实施了一个"Time Picker Carousel".它基于a HorizontalScrollView.用户可以在滚动此视图时选择时间.时间值是从X的偏移量计算出来的HorizontalScrollView.

在此输入图像描述

我想在github上分享这个项目,但是在清理代码时我发现了一些糟糕的性能问题.

HorizontalScrollView填充了一个自定义的ArrayAdapter.在getView()使用HolderconvertView.我认为它可能在a中作为适配器工作ListView,因此只有可见项才会被渲染并重新使用,如果它们将被销毁.相反,所有项目都呈现!(在我的情况下是1008!)我自己添加它们(代码示例中为#1),但是即使我尝试添加更少,从删除(和回收)旧的逻辑不起作用,或者我错过了什么?

所以我的基本问题是:我需要更改什么才能使我的适配器表现得像ListView

  1. 我发现这个链接并尝试重写remove函数,但这从未被调用(不知何故逻辑,因为我只是添加)
  2. 在github上有一个很好的PagerAdapter示例,但不知怎的,我无法将其转换为ArrayAdapter<String>

欢迎任何想法,链接!

请不要建议使用ListView.我们决定使用HorizontalScrollView因为回调以及我们ListView在布局中已经拥有的事实.

Horizo​​ntalScrollView

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));   
    }
}
Run Code Online (Sandbox Code Playgroud)

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);    
}
Run Code Online (Sandbox Code Playgroud)

Sco*_*t W 15

我想也许你会混淆视图和适配器之间渲染的逻辑.使用适配器不会导致视图回收行为.实现视图回收行为的是它ListView本身及其父项AbsListView.适配器由所需ListView以正确地填充该被显示在屏幕上按照需要的意见,但视图来显示和何时以及如何再利用这些视图用于实际地选择逻辑不在适配器在所有.

如果您查看源代码HorizontalScrollView和for for ListView,您会发现它们有很大的不同.它们不同的方向不同.

因此,它的长短是你无法通过使用HorizontalScrollView甚至简单的后代获得你正在寻找的视图回收.如果你想要查看回收,你应该看看RecyclerView.