如何使用 ArrayAdapter<myClass>
Posted
技术标签:
【中文标题】如何使用 ArrayAdapter<myClass>【英文标题】:How to use ArrayAdapter<myClass> 【发布时间】:2011-01-16 23:07:59 【问题描述】:ArrayList<MyClass> myList = new ArrayList<MyClass>();
ListView listView = (ListView) findViewById(R.id.list);
ArrayAdapter<MyClass> adapter = new ArrayAdapter<MyClass>(this, R.layout.row,
to, myList.);
listView.setAdapter(adapter);
班级:我的班级
class MyClass
public String reason;
public long long_val;
我在布局中创建了 row.xml,但不知道如何使用 ArrayAdapter 在 ListView 中同时显示原因和 long_val。
【问题讨论】:
【参考方案1】:为您的类实现自定义适配器:
public class MyClassAdapter extends ArrayAdapter<MyClass>
private static class ViewHolder
private TextView itemView;
public MyClassAdapter(Context context, int textViewResourceId, ArrayList<MyClass> items)
super(context, textViewResourceId, items);
public View getView(int position, View convertView, ViewGroup parent)
if (convertView == null)
convertView = LayoutInflater.from(this.getContext())
.inflate(R.layout.listview_association, parent, false);
viewHolder = new ViewHolder();
viewHolder.itemView = (TextView) convertView.findViewById(R.id.ItemView);
convertView.setTag(viewHolder);
else
viewHolder = (ViewHolder) convertView.getTag();
MyClass item = getItem(position);
if (item!= null)
// My layout has only one TextView
// do whatever you want with your string and long
viewHolder.itemView.setText(String.format("%s %d", item.reason, item.long_val));
return convertView;
对于那些不太熟悉 android 框架的人,这里有更详细的解释:https://github.com/codepath/android_guides/wiki/Using-an-ArrayAdapter-with-ListView。
【讨论】:
对不起,MyClass item = items.get(position) 解决了错误,我的变量不匹配。 我已经从上面的代码中删除了 items 字段,因为它很容易导致错误 - 例如,如果有人使用 adapter.clear() 或 adapter.add(...) 更改了内部项目列表 我是否正确假设上面没有使用textViewResourceId
?
viewHolder 是从哪里来的?
什么是 R.layout.listview_association?那是您的自定义布局吗?我可以用 android.R.layout.simple_list_item_1 替换它吗?【参考方案2】:
您可以根据http://developer.android.com/reference/android/widget/ArrayAdapter.html 将toString()
方法添加到MyClass:
无论如何引用 TextView,它都会被数组中每个对象的 toString() 填充。您可以添加自定义对象的列表或数组。覆盖对象的 toString() 方法以确定列表中的项目将显示哪些文本。
class MyClass
@Override
public String toString()
return "Hello, world.";
【讨论】:
虽然是最简单的解决方案,但这(恕我直言)不是一个好主意。三个原因:如果你需要本地化,你将不得不重构。这仅在您有 1 个适配器时才有效,如果您有 2 个用于MyClass
的不同适配器,则必须重构。最后,将表示逻辑绑定到模型通常是个坏主意。模型不应该知道它们是如何呈现给用户的。
要解决@fernandohur 的一些问题,您可以简单地为 ArrayAdapter 创建一个专用的视图类...所以MyClass
类型的模型类需要您添加一个名为MyClassView
的专用类它包装了底层模型(并提供了toString( )
实现
这个答案来自 2011 年,我同意 @fernandohur 的观点——现在有更好的方法来处理这个问题。
我认为这是一个很好的答案,因为很多时候每个类都有一个属性而不是代表对象的名称。
这应该是公认的答案。覆盖仅用于绑定打印名称的适配器是错误的编码。【参考方案3】:
我认为这是最好的方法。使用泛型 ArrayAdapter 类并扩展您自己的 Object 适配器,如下所示:
public abstract class GenericArrayAdapter<T> extends ArrayAdapter<T>
// Vars
private LayoutInflater mInflater;
public GenericArrayAdapter(Context context, ArrayList<T> objects)
super(context, 0, objects);
init(context);
// Headers
public abstract void drawText(TextView textView, T object);
private void init(Context context)
this.mInflater = LayoutInflater.from(context);
@Override public View getView(int position, View convertView, ViewGroup parent)
final ViewHolder vh;
if (convertView == null)
convertView = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
vh = new ViewHolder(convertView);
convertView.setTag(vh);
else
vh = (ViewHolder) convertView.getTag();
drawText(vh.textView, getItem(position));
return convertView;
static class ViewHolder
TextView textView;
private ViewHolder(View rootView)
textView = (TextView) rootView.findViewById(android.R.id.text1);
这里是你的适配器(示例):
public class SizeArrayAdapter extends GenericArrayAdapter<Size>
public SizeArrayAdapter(Context context, ArrayList<Size> objects)
super(context, objects);
@Override public void drawText(TextView textView, Size object)
textView.setText(object.getName());
最后,如何初始化它:
ArrayList<Size> sizes = getArguments().getParcelableArrayList(Constants.ARG_PRODUCT_SIZES);
SizeArrayAdapter sizeArrayAdapter = new SizeArrayAdapter(getActivity(), sizes);
listView.setAdapter(sizeArrayAdapter);
我创建了一个带有 TextView 布局重力可定制 ArrayAdapter 的 Gist:
https://gist.github.com/m3n0R/8822803
【讨论】:
我非常喜欢你的代码,但我花了一段时间才弄清楚为什么它会因 android.content.res.Resources$NotFoundException: Resource ID #0x0 而崩溃。您在 super(..,0,..) 上的通用适配器调用中,其中 0 实际上是一个布局资源,它不存在,因此必须将其更改为其他内容。此外,您的要点是 404跨度> 最后我改变了很多 - 下拉菜单的布局与显示项目的布局不同,drawText 仅在微调器标题上调用,而不是在其单击的项目上调用。 这应该作为通用适配器有效。你能解决这个问题吗? 是的,我成功了。我意识到您提供的解决方案与我想要的有所不同,但我能够以您的代码为起点并以它为我想要的方式进行修改。感谢这段代码。 这应该是默认提供的。【参考方案4】:子类化 ArrayAdapter 并覆盖方法 getView() 以返回包含您要显示的内容的您自己的视图。
【讨论】:
【参考方案5】:如果您不想为扩展母类而烦恼,这里有一个快速而肮脏的示例,说明如何使用 ArrayAdapter:
class MyClass extends Activity
private ArrayAdapter<String> mAdapter = null;
@Override
protected void onCreate(Bundle savedInstanceState)
mAdapter = new ArrayAdapter<String>(getApplicationContext(),
android.R.layout.simple_dropdown_item_1line, android.R.id.text1);
final ListView list = (ListView) findViewById(R.id.list);
list.setAdapter(mAdapter);
//Add Some Items in your list:
for (int i = 1; i <= 10; i++)
mAdapter.add("Item " + i);
// And if you want selection feedback:
list.setOnItemClickListener(new OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
//Do whatever you want with the selected item
Log.d(TAG, mAdapter.getItem(position) + " has been selected!");
);
【讨论】:
以上是关于如何使用 ArrayAdapter<myClass>的主要内容,如果未能解决你的问题,请参考以下文章
使用带有 ArrayAdapter<Objects> 而不是 ArrayAdapter<Strings> 的 Android AutoCompleteTextView
如何在 Android ArrayAdapter 中使用对象数组?