让自定义列表适配器正确膨胀多个线性布局

Posted

技术标签:

【中文标题】让自定义列表适配器正确膨胀多个线性布局【英文标题】:Getting Custom List Adapter to properly inflate multiple linear layouts 【发布时间】:2012-07-14 19:25:57 【问题描述】:

我对 android 有点陌生,正在尝试找出这些自定义列表适配器。所以我有一个扩展 BaseListActivity 的活动和一个类似的函数:

public void inflate()

    ArrayList<String> words = new ArrayList<String>();
    orders.add("hello");
    orders.add("world");

    wordsList = (ListView) findViewById(R.id.list);

    WordsAdapter adapter = new WordsAdapter(this, R.layout.single_word_container_item,words);
    wordsList.setAdapter(adapter);

然后我按如下方式实现我的自定义 WordsAdapter:

public class WordsAdapter extends ArrayAdapter<String>
    public Context context;
    public ArrayList<String> _words;

    //not sure the purpose of 'a' here
    public WordsAdapter(Context context, int a, ArrayList<String> words) 
        super(context, a, words);
        _words = words;
        this.context = context;
    


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

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View v = inflater.inflate(R.layout.single_word_container_item, null);
        TextView wordName = (TextView) findViewById(R.id.wordName);
        if(!_words.isEmpty())
            wordName.setText(_word.remove(0));
        

        return v;
    


从日志中我可以看出,从未调用过 getView。 'single_word_container_item' 只是一个 xml 文件,其布局我想多次膨胀。我不确定整个过程 - 我认为您在列表视图上设置了一个适配器,然后在该适配器中您负责显示每次实际显示的内容,那么我在这里做错了什么?目前,我在设置适配器时遇到了空指针异常,但之前它不会显示任何内容。日志显示它正在进入 WordsAdapter 构造函数,但随后死亡。提前感谢您的任何建议。

编辑:所以在我的 xml 中识别列表视图似乎有问题。

如果你使用:

ListView
android:id="@+id/android:list" OR android:id="@id/android:list"
android:layout_
android:layout_ 
ListView

使用时报错为空指针异常

但如果你将其定义为:

ListView
android:id="@+id/list"
android:layout_
android:layout_ 
ListView

您收到错误:07-15 19:18:50.240: E/AndroidRuntime(29842): Caused by: java.lang.RuntimeException: 您的内容必须有一个 id 属性为 'android.R.id.列表'

编辑:显然你不能扩展 listactivity 并调用 setcontentview()。由于我需要在列表视图之上的视图,我不想扩展列表活动,而是调用 setcontentview 并仅通过其 ID 引用列表。

现在我的错误是:

java.lang.IllegalStateException:适配器的内容发生了变化,但ListView没有收到通知。确保适配器的内容不是从后台线程修改的,而只是从 UI 线程修改的。

我尝试在 setAdapter() 之后调用 adapter.notifyDataSetChanged() ,但这似乎不起作用。我应该在其他地方调用它吗?

【问题讨论】:

你的代码混入了不同名称的变量,请上传更好的代码 由于您对此有一个注释:int a 通常被命名为 resourcelayout,它允许为您的行选择动态布局(在您的情况下,您可以硬编码 R.layout.single_word_container_item ,这将是您的a)。如果需要,您可以将其删除。 @ChenKinnrot 哪些变量混淆了? 【参考方案1】:

您的 getView() 方法有错误:

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

    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View v;
    if (convertView == null) 
       v = inflater.inflate(R.layout.single_word_container_item, null); 
     else 
       v = convertView;
    
    TextView wordName = (TextView) v.findViewById(R.id.wordName);

    // questionable logic
    if(!_words.isEmpty())
        wordName.setText(_word.remove(0));
    

    return v;

findViewById() 必须在行视图上调用。

再看看上面有问题的逻辑,你到底想干什么?如果您直接从适配器中删除列表视图对象,这将无法正常工作。

【讨论】:

嘿,感谢您的帮助,这完全有道理,但我相信还有其他问题。我更新了 getView() 以反映您的建议,但在尝试调用 setAdapter() 时仍然出现空指针异常,并且我的日志仍然显示 getView() 甚至没有被调用。究竟什么叫 getView() 呢?再次感谢。 那么您需要发布显示 NPE 发生位置的 logcat。当需要绘制列表视图的项目时,操作系统会调用 getView()。 抱歉添加了它..我不能从中得到太多。我猜它可能在 xml 中找不到对我的列表视图的引用。我读到您必须使用 id/list 创建一个明确的列表视图,这就是我正在做的,但可能在其上使用 findviewbyid 存在问题 删除行'wordName.setText(_word.remove(0));'它导致了崩溃。将其更改为类似 wordName.setText("abc");看看崩溃是否停止。 哇,我不敢相信原来是这样,非常感谢您的帮助【参考方案2】:

只需使用膨胀 val dialog = BottomSheetDialog(context,R.style.BottomSheetTheme) val view = inflate(context,R.layout.otpsent1layout,null) dialog.setContentView(view) dialog.show()

【讨论】:

以上是关于让自定义列表适配器正确膨胀多个线性布局的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能在 Android 的水平线性布局中添加超过 2 个元素?

java 膨胀线性布局

线性布局单击不起作用,我在做什么错?

android:如何平均划分线性布局元素

列表视图滚动时在屏幕底部隐藏线性布局

RecyclerView 网格布局