【问题标题】:Listview's getView() isn't working properly when using 2 different kinds of listitem使用 2 种不同的 listitem 时,Listview 的 getView() 无法正常工作
【发布时间】:2019-06-18 20:33:49
【问题描述】:

我有一个用于 Listview 的自定义 Array 适配器,我将它用于联系人,因为我希望 listview 更有条理,我想为联系人姓名的第一个字母添加标题 这是我目前的进度:

@NonNull
    @Override
    public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        View listItem = convertView;
        LinearLayout header = null;
        String preLabel = " ";
        char firstChar = ' ';
        final Contact c = Contacts.get(position);
        String label = c.name;
        if(position != 0) {//OOb prevention
            preLabel = Contacts.get(position - 1).name;
            firstChar = label.toUpperCase().charAt(0);
        }



        char preFirstChar = preLabel.toUpperCase().charAt(0);
        if (listItem == null) {
            //If its the 1st position or the 1st character of the name is different inflate the layout with a header, else inflate the other layout.
            if(position==0 || firstChar != preFirstChar) {

                listItem = LayoutInflater.from(mContext).inflate(R.layout.contacts_list_item, parent, false);
                header  = (LinearLayout) listItem.findViewById(R.id.section);
                setSection(header, label);
            }else{
                listItem = LayoutInflater.from(mContext).inflate(R.layout.contacts_list2, parent, false);
            }
        }//Etc etc

我认为添加更多代码与此无关,即使在我确定何时放置标题的逻辑错误的情况下,这也是一种奇怪的行为,因为当我向下滚动到当我向上滚动位置 0 没有标题时,视图不可见或被破坏。

如果我突然继续这样做,它会自行修复,现在第一个位置再次有一个标题,再次滚动,现在它没有为什么会发生这种情况? 适配器是否有另一种方法用于创建视图? 它是否尝试预测它将使用哪种布局来更快?

错误的视觉参考:

如您所见,位置 0(为简单起见,我将位置编号放在文本视图中,而不是联系人的姓名)在开始时有一个标题,在滚动一点后,它消失了,然后又重新出现.

【问题讨论】:

  • RecyclerView 在视图不可见时丢弃视图,并在再次可见时重新创建它,因此它就像基于您的滚动的动态加载。我认为你选择视图类型的方式可能没有优化,如果你做得更好,它可以更快地加载你的视图
  • listview是否使用recyclerview?
  • 对不起,我看错了你的评论
  • 做一个通用的 ListView 比添加联系人更好,然后在适配器上加载它之前,添加代表标题的字符串,然后在 getView 中检查是否该位置是 String 类型或 Contact 类型以扩展您的相应视图。 Idk,我仍然认为您正在做的这种方式没有优化
  • 我只是在夸大不同的布局。但即使这根本不是最优的,我也可以改变它,但我的问题仍然存在,为什么会发生这种情况?它是一个错误吗?有什么我不知道的原因吗?

标签: android android-listview android-arrayadapter custom-arrayadapter


【解决方案1】:

当您滚动并且视图离开可见区域时,ListView 将为列表中的其他位置重新使用相同的膨胀视图。

因此,如果您的 getView 方法中有逻辑,有时可能会膨胀 R.layout.a,有时会膨胀 R.layout.b,这可能会导致麻烦,因为您可能会得到一个 convertView,您需要重新使用它是 a 类型的,但对于列表中的这个特定位置,您需要 b 类型的视图。

解决方案是使用ViewTypes,这是你如何告诉ListView你有两种不同类型的布局,然后它知道它什么时候可以回收某个类型以及使用哪个View

基本上你应该返回覆盖getViewTypeCount()并返回2(你有两种布局),并将检查我们是否需要标题的逻辑移动到getItemViewType(int position)

请看这里:Android ListView with different layouts for each row

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多