【问题标题】:android listview viewholder. when to use it, and when not toandroid 列表视图视图。何时使用,何时不使用
【发布时间】:2013-11-25 18:27:08
【问题描述】:

我有一个带有自定义列表适配器的 ListView。在 getView() 方法中,我正在使用 ListView14.java 的 API 演示中所示的 ViewHolder '模式'。当我第一次渲染列表时,它似乎加载正确。但是,我遇到的问题是,当我滚动列表时,我看到列表的数据显示在错误的行中(例如,应该在第 10 行中的 TextView 显示在第 2 行中)。但是,当我不使用 viewholder,而是每次都调用 findViewById() 时,列表视图会正确呈现。

【问题讨论】:

    标签: android listview listviewitem


    【解决方案1】:

    但是,我遇到的问题是 当我滚动列表时,我 看到列表的数据显示 在错误的行中(即 TextView 应该在第 10 行出现 例如在第 2 行)。

    很可能,您不正确地回收了行,因此您正在操作的 ViewHolders 不是您要返回的行的正确值。

    Here is a free excerpt 来自我的一本书,其中详细介绍了行回收 - 也许它会帮助您确定哪里出了问题。

    【讨论】:

      【解决方案2】:
      • 我遇到了同样的问题
      • 使用以下技术解决
      • 原因:适配器未经常加载。
      • 在您的自定义适配器类中使用访问说明符添加 ViewHolder

        private static class ViewHolder {
        
                protected TextView itemName;
        
            }
        

      获取查看方法

          @Override
      
              public View getView(int position, View view, ViewGroup viewGroup) {
      
                  // create a ViewHolder reference
                  ViewHolder holder;
      
                  //check to see if the reused view is null or not, if is not null then reuse it
                  if (view == null) {
                      holder = new ViewHolder();
      
                      view = mLayoutInflater.inflate(R.layout.list_item, null);
                      holder.itemName = (TextView) view.findViewById(R.id.list_item_text_view);
      
                      // the setTag is used to store the data within this view
                      view.setTag(holder);
                  } else {
                      // the getTag returns the viewHolder object set as a tag to the view
                      holder = (ViewHolder)view.getTag();
                  }
          // now Use Holder object toget Idss 
      
          holder.itemName.setText(" sample text based on position ");
          }
      

      重要:我们不应该为视图对象设置任何标签,除了 Viewholder 对象

      【讨论】:

        【解决方案3】:

        所以我想我在这里发现了真正的问题。当您为每一行动态设置布局参数时,您需要确保针对所有条件执行此操作。我的问题是,如果它是第一行,我设置了一个布局参数(如填充或边距等),但如果它是中间行,我没有明确设置这些参数,认为它只会使用膨胀的东西由视图充气机。这解释了为什么当我每次都放大视图时它会起作用。这是之前和之后:

        之前:

        if (position == 0) {
        
                    layoutParams.topMargin = uiHelper.getDip(15.0f);
                    layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP,
                            RelativeLayout.TRUE);
                    holder.actionMenu.setLayoutParams(layoutParams);
        
                    holder.contentLayout.setBackgroundResource(R.drawable.top_row);
        
                } else if (position == posts.size() - 1) {
                    holder.contentLayout
                            .setBackgroundResource(R.drawable.bottom_row);
        
                    holder.contentLayout.setPadding(holder.contentLayout
                            .getPaddingLeft(),
                            holder.contentLayout.getPaddingTop(),
                            holder.contentLayout.getPaddingRight(),
                            holder.contentLayout.getPaddingBottom() +  uiHelper.getDip(10.0f));
        
                } else {
                    holder.contentLayout
                            .setBackgroundResource(R.drawable.inner_row);
                }
        

        之后:`

                    layoutParams.topMargin = uiHelper.getDip(10.0f);
                holder.contentLayout.setPadding(holder.contentLayout
                        .getPaddingLeft(),
                        holder.contentLayout.getPaddingTop(),
                        holder.contentLayout.getPaddingRight(),
                        uiHelper.getDip(10.0f));
                if (position == 0) {
        
                    layoutParams.topMargin = uiHelper.getDip(15.0f);
                    layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP,
                            RelativeLayout.TRUE);
        
                    holder.contentLayout.setBackgroundResource(R.drawable.top_row);
        
                } else if (position == posts.size() - 1) {
                    holder.contentLayout
                            .setBackgroundResource(R.drawable.bottom_row);
        
                    holder.contentLayout.setPadding(holder.contentLayout
                            .getPaddingLeft(),
                            holder.contentLayout.getPaddingTop(),
                            holder.contentLayout.getPaddingRight(),
                            uiHelper.getDip(20.0f));
        
                } else {
        
                    holder.contentLayout
                            .setBackgroundResource(R.drawable.inner_row);
        
                }
        
                holder.actionMenu.setLayoutParams(layoutParams);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-05-21
          • 2010-12-01
          • 2015-12-03
          • 1970-01-01
          • 2011-11-03
          • 1970-01-01
          • 2010-10-12
          相关资源
          最近更新 更多