Integrating current ListView with a Custom Adapter with ListView to allow multiple views

烈酒焚心 提交于 2019-12-12 04:56:59

问题


The current project I have includes a ListView with a Custom Adapter. However, I am now interested in adding multiple types of views to my ListView but after several attempts I have been unable to add the two sources of code together to successfully integrate them.

Article on ListView with multiple views: ListView Article for multiple views

The custom adapter in my current code retrieves the data from another class called getData which is referenced by "data".

Code from article (ListView with multiple views):

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;
}
}

Current code (ListView with custom adapter):

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;
}

}

Edit:

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
}

}

回答1:


First, a bit of an aside: you should create a class that encapsulates a headline, description, etc. and use an array/collection of those objects to back your adapter. It will be far easier than managing many disparate arrays of things, especially if one day you decide you need another attribute of an Article (its category, for example).

class Article {
    int id;
    String headline;
    String description;
    Bitmap picture;
}

With regard to your ListView, the magic happens in the methods getItemViewType() and getViewTypeCount(). In getViewTypeCount() you return the maximum number of row types -- the article you posted uses two row types and so returns 2. In getItemViewType() you return a value between zero and (viewTypeCount - 1) -- in the article, his implementation can return 0 or 1 because his viewTypeCount is 2.

How you decide which row type applies to each item is entirely up to you. If, for example, you wanted to simply alternate view types on every row, you can do this:

@Override
public int getViewTypeCount() {
    return 2; // TODO make this a static final
}

@Override
public int getItemViewType(int position) {
    return position % 2; // 0 or 1
}

In other applications you would probably inspect the item at the given position to help you determine what should be returned in getItemViewtype().

The reason this functionality exists is that getView() provides a parameter (called convertView) that is a row which has been recycled. In order to give you an appropriate convertView, ListView needs to first know what row type it was. When you want to implement getView() for an adapter with multiple row types, it generally looks something like this:

@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);
    }
}

Note the cases for the switch statement correspond to the possible values that can be returned from getItemViewType(). These could be static final members.

I highly suggest watching The World of ListView. That video covers this topic as well as how to properly use convertView in your adapter implementation.



来源:https://stackoverflow.com/questions/24914947/integrating-current-listview-with-a-custom-adapter-with-listview-to-allow-multip

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!