其他分享
首页 > 其他分享> > android – Horizo​​ntalScrollView:带getView()的CustomAdapter不重用像ListView这样的convertViews

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

作者:互联网

在我过去的一个项目中,我实施了一个“Time Picker Carousel”.它基于Horizo​​ntalScrollView.用户可以在滚动此视图时选择时间.时间值是根据Horizo​​ntalScrollView的X-Offset计算的.

 

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

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

所以我的基本问题是:我需要更改什么才能让我的适配器像ListView一样?

>我发现this so link并尝试覆盖删除功能,但这从未被调用(不知何故逻辑,因为我只是添加)
>在github有一个很好的PagerAdapter example,但不知怎的,我无法将其转换为ArrayAdapter< String>

欢迎任何想法,链接!

请不要建议使用ListView.我们决定使用Horizo​​ntalScrollView因为回调以及我们在布局中已经有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));   
    }
}

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);    
}

解决方法:

我想也许你会混淆视图和适配器之间渲染的逻辑.使用适配器不会导致视图回收行为. ListView本身及其父级AbsListView实现了视图回收行为. ListView需要适配器才能正确填充屏幕上显示的视图,但实际上选择显示哪些视图以及何时以及如何回收这些视图的逻辑根本不在适配器中.

如果你看一下HorizontalScrollViewListView的源代码,你会发现它们是截然不同的.它们不同的方向不同.

因此,它的长短之处在于,您将无法通过使用Horizo​​ntalScrollView甚至是简单的后代来获取您正在寻找的视图回收.如果您想要查看回收,请查看RecyclerView.

标签:android,android-adapter,horizontalscrollview
来源: https://codeday.me/bug/20190712/1443670.html