Android ListView 适配器崩溃 issue/Duplicates

Android ListView Adapter Crash issue/Duplicates

我主要是想通过同一个 ListView 适配器显示多个视图。但是,适配器最终会生成多个重复项,有时还会因 NullPointer 而崩溃。我的猜测是我完全错误地实现了适配器。这是我的完整代码:

The item could either be a photo or a text.

适配器:

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

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

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>

尝试一下你使用的是 ImageView 而不是 TextView

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

每行有 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

有这3个就好了

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

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

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