【问题标题】:ListView with different layouts for each item每个项目具有不同布局的 ListView
【发布时间】:2014-01-22 13:03:25
【问题描述】:

我找到了这 2 个答案:https://stackoverflow.com/a/11787066/1489990 和 https://stackoverflow.com/a/18868395/1489990,我一直在尝试遵循这些答案来完成每个项目具有不同布局的列表视图。我的数组适配器如下所示:

public class MyArrayAdapter<T> extends ArrayAdapter<T> {
    LayoutInflater mInflater;
    int[] mLayoutResourceIds;

    public MyArrayAdapter(Context context, int[] textViewResourceId, List<T> objects) {
        super(context, textViewResourceId[0], objects);
        mInflater = (LayoutInflater)context.getSystemService (Context.LAYOUT_INFLATER_SERVICE);
        mLayoutResourceIds = textViewResourceId;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        LayoutInflater inflater = null;
        int type = getItemViewType(position);
        // instead of if else you can use a case
        if (row  == null) {
            if (type == TYPE_ITEM1) {
                //infalte layout of type1
                row = inflater.inflate(R.id.item1, parent, false); //*****************
            }
            if (type == TYPE_ITEM2) {
                //infalte layout of type2
            }  else {
                //infalte layout of normaltype
            }
        }
        return super.getView(position, convertView, parent);
    }

    @Override
    public int getItemViewType(int position) {
        if (position== 0){
            type = TYPE_ITEM1;
        } else if  (position == 1){
            type = TYPE_ITEM2;
        }
        else
        {
            type= TYPE_ITEM3 ;
        }
        return type;    //To change body of overridden methods use File | Settings | File Templates.
    }

    @Override
    public int getViewTypeCount() {
        return 3;    //To change body of overridden methods use File | Settings | File Templates.
    }
}

还有我的 onCreate:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    String[] array = new String[] {"one", "two", "three", "four", "five", "six"};
    List<String> list = new ArrayList<String>();
    Collections.addAll(list, array);

    ListView listView = new ListView(this);
    listView.setAdapter(new MyArrayAdapter<String>(this, new int[] {android.R.layout.simple_list_item_1, android.R.layout.simple_list_item_single_choice}, list));
    setContentView(listView);
}

这个问题是我的数组适配器中的行:

row = inflater.inflate(R.id.item1, parent, false);

给出错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.LayoutInflater.inflate(int, android.view.ViewGroup, boolean)' on a null object reference

我对 xml 布局的结构有点困惑。现在我有 1 个用于 listView 的 xml 和一个用于第一个列表布局的单独的 xml,我尝试在 1 个 xml 布局中制作它,但它仍然给出了空指针异常。我需要一些关于如何实现这一点的指导。谢谢

【问题讨论】:

    标签: java android xml listview


    【解决方案1】:

    您忘记正确初始化您的inflater。您将其显式设置为 null (LayoutInflater inflater = null;),因此在调用 inflater.inflate(R.id.item1, parent, false); 时,它会抛出 NPE。

    您是否希望使用您的 mInflater 变量?

     row = mInflater.inflate(R.id.item1, parent, false);
    

    但是我会去掉这个 mInflater 变量并直接在 getView 方法中执行此操作:

    public class MyArrayAdapter<T> extends ArrayAdapter<T> {
        int[] mLayoutResourceIds;
    
        public MyArrayAdapter(Context context, int[] textViewResourceId, List<T> objects) {
            super(context, textViewResourceId[0], objects);
            mLayoutResourceIds = textViewResourceId;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View row = convertView;
            int type = getItemViewType(position);
            // instead of if else you can use a case
            if (row  == null) {
                LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                if (type == TYPE_ITEM1) {
                    //infalte layout of type1
                    row = inflater.inflate(R.id.item1, parent, false); //*****************
                }
                if (type == TYPE_ITEM2) {
                    //infalte layout of type2
                }  else {
                    //infalte layout of normaltype
                }
            }
            return super.getView(position, row, parent);
        }
        /**
         * Other stuff 
         */
    }
    

    【讨论】:

    • 感谢它能够解决我的第一个问题。现在它已修复,我看到列表视图有一个、两个、三个......我更改了一行以包含我的布局 'listView.setAdapter(new MyArrayAdapter(this, new int[] {R.layout .item1,android.R.layout.simple_list_item_single_choice},列表));'但它给了我错误 java.lang.IllegalStateException: ArrayAdapter requires the resource ID to be a TextView
    • @ez4nick 我建议您用您的实际代码和错误消息提出另一个问题。这样解决问题会更简单。
    【解决方案2】:

    您的布局文件的名称是什么?是 item1.xml 吗?如果是这种情况,您需要将其称为 R.layout.item1

    row = mInflater.inflate(R.layout.item1, parent, false);

    您还在构造函数中创建了对 inflater 的引用,但随后在 getView 方法中将其设置为 null。使用 mInflator 并删除 inflator = null 行

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-12
      • 2011-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多