Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/188.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 取消ListView';s回收商和/或清理回收商?_Android_Android Listview - Fatal编程技术网

Android 取消ListView';s回收商和/或清理回收商?

Android 取消ListView';s回收商和/或清理回收商?,android,android-listview,Android,Android Listview,我的应用程序中有一个列表视图,用于显示包含两种类型项目的列表。它当前的实现方式是,对于每种项类型,我都有两种不同的XML布局,我的适配器正确地报告了类型,并且在getView()方法中,我根据指定位置的类型膨胀适当的XML 问题是,在绝大多数情况下,项目列表的结构是,大多数类型1项目在开头,大多数类型2项目在结尾,因此通常在开始时您会看到大多数类型1项目,向下滚动,在某个时候您会开始看到类型2项目,它们会一直持续到列表的结尾 当我滚动到中点时,一切正常。在这一点上,对getView()的所有调用

我的应用程序中有一个列表视图,用于显示包含两种类型项目的列表。它当前的实现方式是,对于每种项类型,我都有两种不同的XML布局,我的适配器正确地报告了类型,并且在getView()方法中,我根据指定位置的类型膨胀适当的XML

问题是,在绝大多数情况下,项目列表的结构是,大多数类型1项目在开头,大多数类型2项目在结尾,因此通常在开始时您会看到大多数类型1项目,向下滚动,在某个时候您会开始看到类型2项目,它们会一直持续到列表的结尾

当我滚动到中点时,一切正常。在这一点上,对getView()的所有调用都作为convertView参数传递为null。这显然是有道理的。问题是ListView似乎在recycler中存储了所有以前的Type1视图,只要我一直向下滚动,我就不会使用它们,因为从现在开始,大多数视图都是Type2视图

视图非常复杂,上面有自定义的背景和位图,所以我在内存中有很多视图,我可能永远不会使用它们

我的问题有两个:

  • 我应该担心吗?现在我还没有遇到OOM异常,但我是否会遇到这些异常,或者ListView是否足够聪明,能够在资源紧张时“放弃”其中的一些视图

  • 如果我真的需要担心它,有没有办法明确地告诉ListView清除它的回收器,或者甚至以某种方式禁用它


  • 一个可能的解决方案是对两个布局使用相同的XML,其中有两个视图组,只需将其中一个视图组的可见性设置为GONE,但是,如果我不打算显示一个相当复杂的视图层次结构,那么它似乎是一种浪费。

    在中处理两种不同类型的子视图的一个建议是使用
    getViewTypeCount
    方法,并让适配器知道您实际使用了两种不同类型的视图

    listView按照每个视图类型维护每个回收器(在您的情况下,数字为2),因此您不必担心任何OOM异常,也不需要告诉listView清理其回收器

    如需更详细的说明, 检查:

    用于实现的代码段:

    public class SampleAdapter extends ArrayAdapter<String> {
    
        ...
    
        @Override
        public int getViewTypeCount() {
            return 2;
        }
    
        @Override
        public int getItemViewType(int position) {
            //the result must be in the range 0 to getViewTypeCount() - 1.
            if( position < 10 )
                return 0;
            else
                return 1;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            switch( getItemViewType(position) ){
                case 0:
                    //do something for type1 view.
                    break;
                case 1:
                    //do something for type2 view.
                    break;
            }
            return convertView;
        }
    }
    
    公共类SamdCapter扩展了ArrayAdapter{
    ...
    @凌驾
    public int getViewTypeCount(){
    返回2;
    }
    @凌驾
    public int getItemViewType(int位置){
    //结果必须在0到getViewTypeCount()的范围内-1。
    如果(位置<10)
    返回0;
    其他的
    返回1;
    }
    @凌驾
    公共视图getView(int位置、视图转换视图、视图组父视图){
    开关(getItemViewType(位置)){
    案例0:
    //对type1视图执行一些操作。
    打破
    案例1:
    //对type2视图执行一些操作。
    打破
    }
    返回视图;
    }
    }
    
    我应该担心吗

    不,因为用户完全可以向上滚动,从而返回到类型1行

    现在我还没有遇到OOM异常,但我是否会遇到这些异常,或者ListView是否足够聪明,能够在资源紧张时“放弃”其中的一些视图


    一旦您开始收到
    OutOfMemoryError
    消息,此
    ListView
    将不是您的问题。您只有这么多行
    视图
    结构,从内存消耗的角度来看,所有结构都应该非常便宜。

    如果只有两种视图类型,我就不会太担心了


    若你们想优化它,我建议不要有一个非常复杂的布局,而是使用自定义的
    视图
    ,自己绘制
    位图。任务稍微复杂一点,但通过中点时会带来更好的用户体验。

    我已经在使用getViewTypeCount()和getItemViewType()。问题是,当我滚动浏览列表的后半部分时,一些Type1视图仍然保存在recycler中。