我当前的项目包括一个带自定义适配器的ListView。但是,我现在有兴趣为ListView添加多种类型的视图,但经过多次尝试后,我无法将两个代码源添加到一起以成功集成它们。
有关多个视图的ListView文章:ListView Article for multiple views
我当前代码中的自定义适配器从另一个名为getData的类中检索数据,该类由" data"引用。
文章中的代码(包含多个视图的ListView):
public class MultipleItemsList extends ListActivity {
private MyCustomAdapter mAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAdapter = new MyCustomAdapter();
for (int i = 1; i < 50; i++) {
mAdapter.addItem("item " + i);
if (i % 4 == 0) {
mAdapter.addSeparatorItem("separator " + i);
}
}
setListAdapter(mAdapter);
}
private class MyCustomAdapter extends BaseAdapter {
private static final int TYPE_ITEM = 0;
private static final int TYPE_SEPARATOR = 1;
private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1;
private ArrayList mData = new ArrayList();
private LayoutInflater mInflater;
private TreeSet mSeparatorsSet = new TreeSet();
public MyCustomAdapter() {
mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void addItem(final String item) {
mData.add(item);
notifyDataSetChanged();
}
public void addSeparatorItem(final String item) {
mData.add(item);
// save separator position
mSeparatorsSet.add(mData.size() - 1);
notifyDataSetChanged();
}
@Override
public int getItemViewType(int position) {
return mSeparatorsSet.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;
}
@Override
public int getViewTypeCount() {
return TYPE_MAX_COUNT;
}
@Override
public int getCount() {
return mData.size();
}
@Override
public String getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
System.out.println("getView " + position + " " + convertView + " type = " + type);
if (convertView == null) {
holder = new ViewHolder();
switch (type) {
case TYPE_ITEM:
convertView = mInflater.inflate(R.layout.item1, null);
holder.textView = (TextView)convertView.findViewById(R.id.text);
break;
case TYPE_SEPARATOR:
convertView = mInflater.inflate(R.layout.item2, null);
holder.textView = (TextView)convertView.findViewById(R.id.textSeparator);
break;
}
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
}
holder.textView.setText(mData.get(position));
return convertView;
}
}
public static class ViewHolder {
public TextView textView;
}
}
当前代码(带自定义适配器的ListView):
FragmentA.java
package com.example.newsapp;
public class FragmentA extends Fragment{
getData data = getData.getMyData();
public Integer ArticleID;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View V = inflater.inflate(R.layout.fragment_a, container, false);
ListView listView = (ListView)V.findViewById(R.id.list)
CustomList adapter = new
CustomList(getActivity(), data.Headline.toArray(new String[data.Headline.size()]), data.Description.toArray(new String[data.Description.size()]), data.BitmapList.toArray(new Bitmap[data.BitmapList.size()]), data.ArticleID.toArray(new Integer[data.ArticleID.size()]));
listView.setAdapter(adapter);
listView.setOnItemClickListener(this); //Removed on click item event code.
return V;
}
CustomList.java
package com.example.newsapp;
public class CustomList extends ArrayAdapter<String>{
private final Activity context;
private final String[] titleId;
private final String[] descriptionId;
private final Bitmap[] pictureid;
public CustomList(Activity context,
String[] Headline, String[] Description, Bitmap[] BitmapList, Integer[] ArticleID) {
super(context, R.layout.single_row, Headline);
this.context = context;
this.titleId = Headline;
this.descriptionId = Description;
this.pictureid = BitmapList;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView= inflater.inflate(R.layout.single_row, null, true);
TextView txtTitle = (TextView) rowView.findViewById(R.id.tvTitle);
TextView txtDescription = (TextView) rowView.findViewById(R.id.tvDescription);
ImageView imageView = (ImageView) rowView.findViewById(R.id.ivIcon);
txtTitle.setText(titleId[position]);
txtDescription.setText(descriptionId[position]);
imageView.setImageBitmap(pictureid[position]);
return rowView;
}
}
修改
public class CustomList extends ArrayAdapter<String>{
private final Activity context;
private final String[] titleId;
private final String[] descriptionId;
private final Bitmap[] pictureid;
public CustomList(Activity context,
String[] Headline, String[] Description, Bitmap[] BitmapList, Integer[] ArticleID) {
super(context, R.layout.single_row, Headline);
this.context = context;
this.titleId = Headline;
this.descriptionId = Description;
this.pictureid = BitmapList;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
int viewType = getItemViewType(position);
View rowView = null;
switch(viewType) {
case 0:
LayoutInflater inflater = context.getLayoutInflater();
rowView= inflater.inflate(R.layout.single_row, null, true);
TextView txtTitle = (TextView) rowView.findViewById(R.id.tvTitle);
TextView txtDescription = (TextView) rowView.findViewById(R.id.tvDescription);
ImageView imageView = (ImageView) rowView.findViewById(R.id.ivIcon);
txtTitle.setText(titleId[position]);
txtDescription.setText(descriptionId[position]);
imageView.setImageBitmap(pictureid[position]);
case 1:
LayoutInflater inflater2 = context.getLayoutInflater();
rowView= inflater2.inflate(R.layout.single_row_loadmore, null, true);
}
return rowView;
}
@Override
public int getViewTypeCount() {
return 2; // TODO make this a static final
}
@Override
public int getItemViewType(int position) {
return position % 2; // 0 or 1
}
}
答案 0 :(得分:0)
首先,请稍等一下:您应该创建一个封装标题,描述等的类,并使用这些对象的数组/集合来支持您的适配器。它比管理许多不同的事物要容易得多,特别是如果有一天你决定需要文章的另一个属性(例如,它的类别)。
class Article {
int id;
String headline;
String description;
Bitmap picture;
}
关于ListView,魔术发生在方法getItemViewType()
和getViewTypeCount()
中。在getViewTypeCount()
中,您返回最大行类型数 - 您发布的文章使用两种行类型,因此返回2
。在getItemViewType()
中,您返回的值介于0和(viewTypeCount - 1)之间 - 在文章中,他的实现可以返回0
或1
,因为他的viewTypeCount是2
。< / p>
您如何确定哪种行类型适用于每个项目完全取决于您。例如,如果您想在每一行上简单地替换视图类型,则可以执行以下操作:
@Override
public int getViewTypeCount() {
return 2; // TODO make this a static final
}
@Override
public int getItemViewType(int position) {
return position % 2; // 0 or 1
}
在其他应用程序中,您可能会检查给定位置的项目,以帮助您确定getItemViewtype()
中应返回的内容。
此功能存在的原因是getView()
提供了一个参数(称为convertView
),该参数是已被回收的行。为了给你一个合适的convertView
,ListView需要首先知道它是什么行类型。如果要为具有多种行类型的适配器实现getView()
,通常看起来像这样:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int viewType = getItemViewType(position);
switch(viewType) {
case 0:
return setUpOneViewType(position, convertView, parent);
case 1:
return setUpAnotherViewType(position, convertView, parent);
}
}
请注意,switch语句的大小写对应于可以从getItemViewType()
返回的可能值。这些可能是static final
成员。
我强烈建议您观看The World of ListView。该视频介绍了此主题以及如何在适配器实现中正确使用convertView
。