【问题标题】:List Adapter setting - How can I not to repeat the list item layout resource?列表适配器设置 - 如何不重复列表项布局资源?
【发布时间】:2012-03-02 10:17:06
【问题描述】:

我用 ArrayAdapter 制作了一个 ListView。有用。但是我不得不两次为项目布局放置资源 id:在适配器定义和 getView 中,在 View 参数为空的情况下。

// --------------------------------------------here is the FIRST use
lvShows.setAdapter(new ArrayAdapter<TvShow>(this, R.layout.show_row, allKnownShows) {
    @Override
    public View getView(int position, final View rowView, ViewGroup parent) {
        LinearLayout showView;
        if (rowView == null) {

            // --------------------------------- here is the SECOND use
            showView = (LinearLayout) inflater.inflate(R.layout.show_row, parent, false);
        }
        else {
            showView = (LinearLayout) rowView;
        }
        ((TextView) showView.getChildAt(0)).setText(time));
        ((TextView) showView.getChildAt(1)).setText(name);
        return showView;
    }
});

当然,这种风格令人厌恶。能否请您指教,我的理解有什么问题,我怎样才能只使用一次资源?

如果创建一个新的 ArrayAdapter 我正在设置布局 id,它应该知道它并以某种方式使用。我怎么能达到它?或者更好的是,我希望适配器自动创建项目视图。再说一遍 - 我该如何使用它?

ArrayAdapter 在创建新资源时如何处理我们提供给它的资源?它的所有构造函数都获取项目资源,我们管理此资源并“手动”对其进行膨胀。这不是有效的方法。

【问题讨论】:

  • 谢谢。我已经有工作代码。我不想为美丽付出太多。由于其他原因,我将在稍后尝试使用此确切列表的基本适配器,可能在一两个月内,但现在我想知道一些在列表中显示复杂项目的简单而正确的方法。 ArrayAdapter 似乎是最简单的。

标签: android listview android-arrayadapter android-resources


【解决方案1】:

您可以覆盖 ArrayAdapter 构造函数并调用 super :

public ArrayAdapter<T>(Context context, TheDataType data) {
   super(context, R.layout.show_row, data);
 }

并将 id 存储在 ArrayAdapter 成员变量中。它避免适配器“用户”知道适配器所需的视图是什么。

或者您可以使用 BaseAdapter。

【讨论】:

  • 当然可以。但是请注意,在制作新的 ArrayAdapter 时,我 am 已经设置了项目布局 ID。做什么的?您正在将 R.layout.show_row 放入超级调用中。干什么用的?
  • 因为在调用构造函数时不需要指定它:new TheArrayAdapter&lt;TvShow&gt;(this, allKnownShows);。适配器只知道他需要使用哪个资源
  • 不是“只有这样”——我已经找到了解决方案。无论如何,感谢您的尝试和 +1。
【解决方案2】:

我查看了 ArrayAdapter 的源代码,它已经完成了关于视图创建的所有这些工作:

// citation from public class ArrayAdapter<T>
private View createViewFromResource(int position, View convertView, ViewGroup parent,
        int resource) {
    View view;
    TextView text;
    if (convertView == null) {
        view = mInflater.inflate(resource, parent, false);
    } else {
        view = convertView;
    }

所以,我们应该简单地使用它:

lvShows.setAdapter(new ArrayAdapter<TvShow>(this, 
                                            R.layout.show_row, 
                                            R.id.nameField, 
                                            allKnownShows){
public View getView(int position, final View convertView, ViewGroup parent) {
    LinearLayout showView = (LinearLayout) super.getView(position,  convertView, parent);

    setAnythingForItem(showView);

    return showView;
}

注意:我们改变了构造函数!

ArrayAdapter 允许使用非 TextView 项目布局。但如果不是 TextView 本身,它应该有一个,并且这个非常内部的 TextView 字段的 id 应该作为第三个参数提供给构造函数。 ArrayAdapter 需要设置它,如果连接到它的数组具有 String 元素,则在此处写入 Strings。

它总是需要一个 TextView,即使它实际上并不需要它,如果数组由对象组成,而不是字符串。否则,它会检查项目布局是否为 TextView,如果不是,则会引发错误。

【讨论】:

  • 有趣的是,它根本不在 SO 上,正如我现在所看到的。每个人都会记住资源 ID,并在以后“手动”扩充。
  • 所以适配器需要有一个TextView,它有点限制,因此在所有情况下都不起作用
  • 不,看来,我解释得很糟糕。对不起我的英语,我会尝试重写。
  • 已编辑。我认为,它很少真正受到限制,因为很少有没有 TextView 字段的项目布局。这一切都在我的代码中运行。
  • 好的,知道了。所以如果数组中包含字符串,那么视图需要或者要有TextView,对吧?
猜你喜欢
  • 1970-01-01
  • 2022-01-05
  • 1970-01-01
  • 2015-10-22
  • 1970-01-01
  • 1970-01-01
  • 2013-10-28
  • 1970-01-01
  • 2015-11-24
相关资源
最近更新 更多