【问题标题】:Android ListView Adapter Crash issue/DuplicatesAndroid ListView 适配器崩溃问题/重复
【发布时间】:2015-11-24 03:42:12
【问题描述】:

我基本上是在尝试通过同一个 ListView 适配器显示多个视图。但是,适配器最终会生成多个重复项,有时还会使用 NullPointer 崩溃。我的猜测是我实现的适配器都错了。这是我的完整代码:

该项目可以是照片文字

适配器

 public class FeedAdapter extends BaseAdapter {

        static private Activity activity;
        private static LayoutInflater inflater = null;
        ArrayList<ActivityTable> actList = new ArrayList<ActivityTable>();
        Holder holder;

    public FeedAdapter(Activity a, ArrayList<ActivityTable> actList) {
            activity = a;
            this.actList = actList;
        }

    public View getView(int position, View convertView, ViewGroup parent) {

            Holder holder;

            final ActivityTable act = actList.get(position);
    inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

     if (convertView == null) {

                if (act.getType().equals("text")) {

                    convertView = inflater.inflate(R.layout.feed_single_text, null);
                    holder = new Holder();

                    //More code that Set the caption to the holder
                    convertView.setTag(holder);

                }

                if (act.getType().equals("photo")) {

                    convertView = inflater.inflate(R.layout.feed_single_picture, parent, false);
                    holder = new Holder();
                    holder.media = (ImageView) convertView.findViewById(R.id.postphoto);
                    //More code that Set the photo to the holder
                    convertView.setTag(holder);
                }

            } else {

                holder = (Holder) convertView.getTag();

            }

         return convertView;
    }


    public static class Holder {
           ImageView media;
           TextView caption;
    }
}

我是否以错误的方式在同一个适配器中膨胀多个视图?谁能指出错误?

【问题讨论】:

  • 你能贴出你为每一行设置数据的代码吗?我的意思是“返回转换视图”上方和else{...} 下方的代码
  • 当有更好的选择时,你为什么还要使用ListView?您在维护旧代码吗?
  • @AvinashR 有什么更好的选择?
  • @PhanVănLinh 即使没有设置数据,我也会得到重复的行
  • 请发布错误堆栈。不知道这些人如何发布答案的错误?

标签: java android listview android-listview


【解决方案1】:

每行有 2 个不同的布局,所以我认为你应该添加

@Override
public int getViewTypeCount() {
    return 2;
}

到您的列表视图适配器
在您的代码中,尝试在适配器的构造函数中初始化您的 LayoutInflater

public FeedAdapter(Activity a, ArrayList<ActivityTable> actList) {
    ...
    inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}  

你还应该优化你的 ListView 性能

Here is my experience

【讨论】:

  • 仍然给了我重复的视图,伙计。然后我将求助于使用 RecyclerView
【解决方案2】:

把这三个做好就好了。

@Override
public int getCount() {
    return actList().size();
}

@Override
public Object getItem(int position) {
    return actList().get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

这是重要的部分, 首先你必须告诉适配器有多少类型, 然后你必须告诉适配器如何确定类型。

这里我告诉 type View Type = 2

@Override
public int getViewTypeCount() {
    return 2;
}

在这里我告诉适配器我如何将类型号放入数组中 我使用 setType = 0 ||设置类型 = 1 个人偏好:我喜欢使用 int 而不是 String

@Override
public int getItemViewType(int position) {
    return act.get(position).getType();
}

然后在 getView 上

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    View v = convertView;
    int listViewItemType = getItemViewType(position);
    if (v == null) {
        ..whatevever you doing to make v not null
    }

    if (listViewItemType == 0) {
        //Do something    
    }else if(listViewItemType == 1){
       // Do something different 
    }
    return v;
}

【讨论】:

    【解决方案3】:

    是的,您会得到重复的项目,因为 Convertview 正在重用。一旦convertview被创建,如果你滚动使用该视图。

    所以最好使用单一布局并同时使用图像和文本。基于类型隐藏任何一个。

    【讨论】:

    • 对每个项目使用 setVisibility 与使用两个不同的视图一样糟糕。如果您必须添加 5 个文本框并且您必须隐藏 5 个文本框,那么祝您以后使用一个视图好运。我不敢相信这是一个正确的答案。 @earthling 最佳实践是使用我的答案作为 adpater 的逻辑来识别两个视图之间的差异,然后使用 view Holder,我看到你在代码中使用 view Holder。你应该能理解。
    【解决方案4】:

    xml文件

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <ImageView
        android:id="@+id/ImgFeed"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    
    <TextView
        android:id="@+id/txtCaption"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    
    </LinearLayout>
    

    试试这个,你使用的是 TextView 的 ImageView

    public View getView(int position, View convertView, ViewGroup parent) {
    
            Holder holder;
    
            final ActivityTable act = actList.get(position);
            inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            if (convertView == null) {
            convertView = inflater.inflate(R.layout.feed_layout, null);
            holder = new Holder();
            holder.caption = (TextView) convertView.findViewById(R.id.txtCaption);
            holder.media = (ImageView) convertView.findViewById(R.id.ImgFeed);
                if (act.getType().equals("text")) {
                    holder.media.setVisibility(View.GONE)
                }
    
                else if (act.getType().equals("photo")) {
                    holder.caption.setVisibility(View.GONE)             
                }
                convertView.setTag(holder);
    
            } else {
    
                holder = (Holder) convertView.getTag();
    
            }
    
         return convertView;
    }
    

    【讨论】:

    • 你能澄清你的解决方案吗?我看不出有什么区别?
    • holdor.caption 是 textview,您在 getview 中将其用作 imageview
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多