I am calling the adapter by this set of codes:
mAdapter = new MyCustomAdapter(getActivity());
mAdapter.addSeparatorItem(new ContentWrapper(q.get(0).getA_name(),null));
mAdapter.addItem(new ContentWrapper(q.get(0).getAS_name(), q.get(0).getDesc_art()));
Consider this code:
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<ContentWrapper> mData = new ArrayList<ContentWrapper>();
private LayoutInflater mInflater;
private TreeSet<Integer> mSeparatorsSet = new TreeSet<Integer>();
public MyCustomAdapter(Context context)
{
mInflater = LayoutInflater.from(context);
}
public void addItem(ContentWrapper value) {
mData.add(value);
notifyDataSetChanged();
}
public void addSeparatorItem(ContentWrapper value) {
mData.add(value);
// save separator position
mSeparatorsSet.add(mData.size() - 1);
notifyDataSetChanged();
}
public ContentWrapper getItem(int position) {
return mData.get(position);
}
@Override
public int getItemViewType(int position) {
return mSeparatorsSet.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;
}
@Override
public int getViewTypeCount() {
return TYPE_MAX_COUNT;
}
public int getCount() {
return mData.size();
}
public long getItemId(int position) {
Log.v("getItemId Position", ""+position);
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
if (convertView == null) {
holder = new ViewHolder();
switch (type) {
case TYPE_ITEM:
convertView = mInflater.inflate(R.layout.white, null);
holder.textView = (TextView)convertView.findViewById(R.id.text);
break;
case TYPE_SEPARATOR:
convertView = mInflater.inflate(R.layout.black, null);
holder.textView = (TextView)convertView.findViewById(R.id.textSeparator);
count++;
break;
}
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
} holder.textView.setText(mData.get(position).getItem());
if (type == TYPE_ITEM) {
holder.textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setIcon(R.drawable.ic_launcher);
final String title = mData.get(position).getItem();
builder.setTitle(title);
builder.setMessage(mData.get(position).getItemDescription());
builder.setCancelable(false);
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
AlertDialog alertDialog = (AlertDialog) dialog;
ViewGroup viewGroup = (ViewGroup) alertDialog.getWindow()
.getDecorView();
TextView textView = findTextViewWithTitle(viewGroup, title);
if (textView != null) {
textView.setEllipsize(null);
textView.setMaxHeight((int) (100 * alertDialog.getContext().getResources().getDisplayMetrics().density));
textView.setMovementMethod(new ScrollingMovementMethod());
}
}
});
alertDialog.show();
}
private TextView findTextViewWithTitle(ViewGroup viewGroup, String title) {
for (int i = 0, N = viewGroup.getChildCount(); i < N; i++) {
View child = viewGroup.getChildAt(i);
if (child instanceof TextView) {
TextView textView = (TextView) child;
if (textView.getText().equals(title)) {
return textView;
}
} else if (child instanceof ViewGroup) {
ViewGroup vGroup = (ViewGroup) child;
return findTextViewWithTitle(vGroup, title);
}
}
return null;
}
});
} else {
holder.textView.setOnClickListener(null);
}
return convertView;
}
}
public static class ViewHolder {
public TextView textView;
}
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return false;
}
This code just display the description of selected item (here TYPE_ITEM
) in an AlertDialog.
As you can see TYPE_SEPERATOR
have disabled onClick() & I want to add one more TYPE_SEPERATOR_GRAY
(let from gray.xml
) be the another type separator with disabled onClick()
.
Do I need to add one more method similar to addSeparatorItem(ContentWrapper value)
like addSeparatorItemGray(ContentWrapper value)
. I know that I have to add one more case in the switch of getView() for inflating the gray.xml
Or what else should I add/modify?
EDIT: ContentWrapper holds items text with its description. I implemented ContentWrapper to assign each TYPE_ITEM with a description
public class ContentWrapper {
private String mItem, mItemDescription;
public ContentWrapper(String item, String itemDescription) {
mItem = item;
mItemDescription = itemDescription;
}
public String getItem() {
return mItem;
}
public String getItemDescription() {
return mItemDescription;
}
}
mAdapter is of type MyCustomAdapter.
The first 3-4 lines of my question says that addSeparatorItem do not have any description so passed null in the second argument & addItem have both text , description.
I want to add the another TYPE_GRAY_SEPARATOR , at some specified positions in the list manually like:
mAdapter.addSeparatorItemGray("HI after 1st view");
mAdapter.addSeparatorItemGray("HI after 23rd view");
mAdapter.addSeparatorItemGray("HI after 45 view");
The method getViewType
should return 3 (List Item + Separator + Gray Separator). Hence set TYPE_MAX_COUNT
to 3.
private static final int TYPE_GRAY_SEPARATOR = 2;
private static final int TYPE_MAX_COUNT = TYPE_GRAY_SEPARATOR + 1;
Data structure to hold gray separator positions:
private TreeSet<Integer> mGraySeparatorsSet = new TreeSet<Integer>();
Method to add the gray separator.
public void addGraySeparatorItem(ContentWrapper value) {
mData.add(value);
// save separator position
mGraySeparatorsSet.add(mData.size() - 1);
notifyDataSetChanged();
}
The method getItemViewType
should return appropriate view based on position.
@Override
public int getItemViewType(int position) {
int viewType = TYPE_ITEM;
if(mSeparatorSet.contains(position))
viewType = TYPE_SEPARATOR;
else if(mGraySeparatorSet.contains(position)) {
viewType = TYPE_GRAY_SEPARATOR;
}
return viewType;
}
The method getView
should handle TYPE_GRAY_SEPARATOR:
public View getView(final int position, View convertView, ViewGroup parent) {
// Existing code
switch(type) {
// Existing cases
case TYPE_GRAY_SEPARATOR:
// Inflate appropriate view
break;
}
// Existing code
}
Think of the extra separator as another view type.
Therefore, to conform to your code style, you need to add another Collection
for these separators, and add needed methods:
private static final int TYPE_GRAY_SEPARATOR = 2;
private TreeSet<Integer> mGraySeparatorsSet = new TreeSet<Integer>();
Also update your getViewTypeCount()
method, as you have one more view type now.
Lastly, add another if else
check in your getView
method, checking for this new view type.
Alternatively, check out the StickyListHeaders library, which handles a lot of this logic for you.
First, add yet another type to getViewTypeCount and getItemViewType, as other suggest.
However, you make it wrong. You don't need to make list items clickable! This is task of ListView to detect clicks and fire OnItemClickListener when item is clicked. So you may remove all setOnClickListener calls.
To make separators in ListView, you need to make some items disabled. For this purpose, there are these functions:
Also there's no need to use Set<> to mark separators. Just lookup your source list of entries with position, and return that separators are disabled, normal items are enabled.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With