setOnCheckedChangeListener - android-listview

I want to expand the group item when I check on it, but for some reasons I can't collapse the group item after it expands.
Can someone please tell me what I am doing wrong?
public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
final GroupHolder holder;
final ViewGroup viewGroup = parent;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.group_list, null);
holder = new GroupHolder();
holder.checkbox = (CheckBox) convertView.findViewById(R.id.cb);
holder.imageView = (ImageView) convertView.findViewById(R.id.label_indicator);
holder.title = (TextView) convertView.findViewById(R.id.group_title);
convertView.setTag(holder);
} else {
holder = (GroupHolder) convertView.getTag();
}
holder.imageView.setImageResource(groupStatus[groupPosition] == 0 ? R.drawable.group_down: R.drawable.group_up);
final Item groupItem = getGroup(groupPosition);
holder.title.setText(groupItem.name);
holder.checkbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (!ALL_CHECKED) {
ArrayList<Item> childItem = getChild(groupItem);
for (Item children : childItem)
children.isChecked = isChecked;
}
groupItem.isChecked = isChecked;
// TODO Auto-generated method stub
if(groupItem.isChecked)
((ExpandableListView) viewGroup).expandGroup(groupPosition);
notifyDataSetChanged();
new Handler().postDelayed(new Runnable() {
public void run() {
// TODO Auto-generated method stub
if (ALL_CHECKED)
ALL_CHECKED = false;
}
}, 10);
}
});
holder.checkbox.setChecked(groupItem.isChecked);
return convertView;
}
//Below is the logcat for when I only put a check mark on group0:
08-19 07:49:08.860: D/group pos: 0
08-19 07:49:08.863: D/group pos: 0
08-19 07:49:08.887: D/group pos: 4
I noticed that it showed groupId0 & 4 when I ONLY clicked on group0
Edit: Re-wrote to make it clear for others to understand better

I have one idea.
First remove CheckBOx and try to collapse by this
lv.setOnGroupExpandListener(new OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
if (lastExpandedPosition != -1
&& groupPosition != lastExpandedPosition) {
lv.collapseGroup(lastExpandedPosition);
}
lastExpandedPosition = groupPosition;
}
});
If still getting any problem please ping me if not getting any problem then add view and view group

First of all, thanks a lot to Blue Green for trying to help. I figured it out after days of debugging. The reason that it didn't let me collapse the expanded group was
public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
AND
public View getChildView(final int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
BOTH had final int groupPosition. This is why the expandablelistview doesn't know which groupPosition that I want to collapse. Furthermore, because of this, it printed out groupId0 & 4 when I ONLY clicked on group0.
ExpandalblelistView is very ^$^** hard to deal with for me. I hope this helps someone else.

Related

ListFragment only showing first item in Fragment View with ExpandableListadpater

I have one fragment with parent and child items. But expandable list only shows the first item in parent list
The problem is that the list view only shows the first item.it contains 3 items, so the listview should show 3 list. Did I miss anything? thanks a lot.
My fragment is
public class FragmentChapters extends ListFragment {
ExpandableListAdapter listAdapter;
ExpandableListView expListView;
List<String> listDataHeader;
HashMap<String, List<String>> listDataChild;
View view;
Context context;
public FragmentChapters() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_chapters, container, false);
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
expListView = (ExpandableListView) getListView();
prepareListData();
context=getActivity();
listAdapter = new ExpandableListAdapter(context, listDataHeader, listDataChild);
// setting list adapter
expListView.setAdapter(listAdapter);
}
private void prepareListData() {
listDataHeader = new ArrayList<String>();
listDataChild = new HashMap<String, List<String>>();
// Adding child data
listDataHeader.add("Top 250");
listDataHeader.add("Now Showing");
listDataHeader.add("Coming Soon..");
// Adding child data
List<String> top250 = new ArrayList<String>();
top250.add("The Shawshank Redemption");
top250.add("The Godfather");
top250.add("The Godfather: Part II");
top250.add("Pulp Fiction");
top250.add("The Good, the Bad and the Ugly");
top250.add("The Dark Knight");
top250.add("12 Angry Men");
List<String> nowShowing = new ArrayList<String>();
nowShowing.add("The Conjuring");
nowShowing.add("Despicable Me 2");
nowShowing.add("Turbo");
nowShowing.add("Grown Ups 2");
nowShowing.add("Red 2");
nowShowing.add("The Wolverine");
List<String> comingSoon = new ArrayList<String>();
comingSoon.add("2 Guns");
comingSoon.add("The Smurfs 2");
comingSoon.add("The Spectacular Now");
comingSoon.add("The Canyons");
comingSoon.add("Europa Report");
listDataChild.put(listDataHeader.get(0), top250); // Header, Child data
listDataChild.put(listDataHeader.get(1), nowShowing);
listDataChild.put(listDataHeader.get(2), comingSoon);
}
}
My Expandable lisAdpter is
[public class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context _context;
private List<String> _listDataHeader; // header titles
// child data in format of header title, child title
private HashMap<String, List<String>> _listDataChild;
public ExpandableListAdapter(Context context, List<String> listDataHeader,
HashMap<String, List<String>> listChildData) {
this._context = context;
this._listDataHeader = listDataHeader;
this._listDataChild = listChildData;
}
#Override
public Object getChild(int groupPosition, int childPosititon) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.get(childPosititon);
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
#Override
public View getChildView(int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final String childText = (String) getChild(groupPosition, childPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.list_item, null);
}
TextView txtListChild = (TextView) convertView
.findViewById(R.id.lblListItem);
txtListChild.setText(childText);
return convertView;
}
#Override
public int getChildrenCount(int groupPosition) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.size();
}
#Override
public Object getGroup(int groupPosition) {
return this._listDataHeader.get(groupPosition);
}
#Override
public int getGroupCount() {
return this._listDataHeader.size();
}
#Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String headerTitle = (String) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.list_group, null);
}
TextView lblListHeader = (TextView) convertView
.findViewById(R.id.lblListHeader);
lblListHeader.setTypeface(null, Typeface.BOLD);
lblListHeader.setText(headerTitle);
return convertView;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
My outupt show this Screen. Only one item listed in fragment.
[1]: https://i.stack.imgur.com/cUiQC.jpg
All is good , Data is actually loading to the expandable list view. Issue is with the layout. You can see the data if you give a fixed height to your Expandable list view. Adjust height of the parent layout (or NestedScrollView) of the view which you used to replace the fragment into your activity.

How to realize strikethrough text in Listview with CheckBox?

I have a ListView with CheckBox and TextView. But when I click on Checkbox, I can’t get strikethrough text. But when I click on the last checkbox, I get strikethrough text.
This is my GetView:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder listViewHolder;
if(convertView == null){
listViewHolder = new ViewHolder();
convertView = lInflater.inflate(R.layout.listview_with_checkbox, parent, false);
listViewHolder.textInListView = (TextView)convertView.findViewById(R.id.textView);
listViewHolder.checkBox = (CheckBox)convertView.findViewById(R.id.checkBox);
convertView.setTag(listViewHolder);
}else{
listViewHolder = (ViewHolder)convertView.getTag();
}
listViewHolder.textInListView.setText(listStorage.get(position).getName());
listViewHolder.checkBox.setChecked(false);
listViewHolder.checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (listViewHolder.checkBox.isChecked()){
listViewHolder.textInListView.setPaintFlags(listViewHolder.textInListView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
listViewHolder.checkBox.setChecked(true);
}else{
listViewHolder.checkBox.setChecked(false);
}
}
});
return convertView;
}
This is my Main:
ListView listViewWithCheckBox = (ListView)RootView1.findViewById(R.id.listView);
List<AimsDiaryCheckBoxBolvanka> listViewItems = new ArrayList<AimsDiaryCheckBoxBolvanka>();
listViewItems.add(new AimsDiaryCheckBoxBolvanka("Nigeria"));
listViewItems.add(new AimsDiaryCheckBoxBolvanka("Ghana"));
listViewItems.add(new AimsDiaryCheckBoxBolvanka("Senegal"));
listViewItems.add(new AimsDiaryCheckBoxBolvanka("OPA"));
listViewItems.add(new AimsDiaryCheckBoxBolvanka("KNIGA"));
listViewWithCheckBox.setAdapter(new AimsDiaryCheckBoxAdapter(getContext(), listViewItems));
listViewWithCheckBox.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// make Toast when click
Toast.makeText(getActivity().getApplicationContext(), "Position " + position, Toast.LENGTH_LONG).show();
}
});
I believe it has something to do with these lines:
if (listViewHolder.checkBox.isChecked()){
listViewHolder.textInListView.setPaintFlags(listViewHolder.textInListView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
listViewHolder.checkBox.setChecked(true);
Take a look at what listViewHolder is pointing to and you are doing the isChecked() before actually calling listViewHolder.checkBox.setChecked(true). Looks like a timing issue

Delete listview items in custom adapter

I'm sorry for this question, but I'm a new in Android developing. I searched in internet, but I don't found any appropriate answer. I have a following code in my custom adapter:
public class ItemsAdapter extends CursorAdapter {
public ItemsAdapter(Context context, Cursor c) {
super(context, c, false);
}
#Override
public void bindView(View view, Context arg1, Cursor cursor) {
ViewHolder viewHolder = (ViewHolder) view.getTag();
viewHolder.title.setText(cursor.getString(cursor
.getColumnIndex("title")));
viewHolder.publishDate.setText(cursor.getString(cursor.getColumnIndex("date_time")));
viewHolder.rssNewsImage.setImageResource(R.drawable.rssnews);
}
#Override
public View newView(Context arg0, Cursor arg1, ViewGroup arg2) {
View view = LayoutInflater.from(mContext).inflate(
R.layout.listview_rssreaderactivity_row, arg2, false);
ViewHolder viewHolder = new ViewHolder();
viewHolder.title = (TextView) view
.findViewById(R.id.tw_title_listview_row_main);
viewHolder.publishDate = (TextView) view.findViewById(R.id.tw_pubDate_listview_row_main);
viewHolder.rssNewsImage = (ImageView) view.findViewById(R.id.imageRssView);
view.setTag(viewHolder);
return view;
}
public class ViewHolder {
TextView title;
TextView publishDate;
ImageView rssNewsImage;
}
}
I want to delete listView item in my custom adapter. Here is my code for click events:
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
final int position, long id) {
AlertDialog.Builder itemLongClickdialog = new AlertDialog.Builder(
RssNewsActivity.this);
itemLongClickdialog.setItems(R.array.array_longclick_item,
new OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
});
I can't delete given item.
How to resolve this problem? I will appreciate all answers.
Try This:
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User clicked OK button
ItemsAdapter dba = new ItemsAdapter (yourActivity);
dba.open();
dba.remove(_id);
Log.i("TAAG", "removed: "+_id);
dba.close();
cursor.requery();
listview.getadaper().notifyDataSetChanged();
}
});

How to set the color of the first column of a Listview item?

I have a Listview (shown in an AlertDialog) that is composed by two columns, made with a HashMap (got the idea somewhere here).
Each column is a TextView. It works well.
Now I want to change the textcolor of the first column of a given row, but I have no idea on how to pick and set this... I googled for hours! Any clues??
This is my code (lists is a SortedSet):
public void showlistdesc () {
ListView listview = new ListView(this);
listview.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
listview.setSoundEffectsEnabled(true);
listview.setSelector(R.drawable.selector);
Integer i=0, pos = 0;
ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
HashMap<String, String> map;
for (String l : lists) {
if (l.equals(currlist)) pos = i;
i++;
map = new HashMap<String, String>();
map.put("list", l);
map.put("desc", getlistdesc(l, false));
mylist.add(map);
}
listview.setAdapter(new SimpleAdapter(this, mylist, R.layout.lists_row,
new String[] {"list", "desc"}, new int[] {R.id.list1, R.id.desc1}));
AlertDialog.Builder builder = new AlertDialog.Builder(AveActivity.this)
.setView(listview)
.setIcon(R.drawable.ic_launcher)
.setTitle(lists.size() + " bird lists in databases");
final AlertDialog dial = builder.create();
//Scrolls the listview to this position at top
listview.setSelection(pos);
dial.show();
}
Thanks!
EDIT
Tried to extend SimpleAdapter with the following code, and all I can see are solid black rows:
public class MySimpleAdapter extends SimpleAdapter {
private Context context;
public MySimpleAdapter(Context context,List<? extends Map<String, ?>> data,
int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater inflater = (LayoutInflater) this.context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.lists_row, null);
}
TextView list1 = ((TextView) v.findViewById(R.id.list1));
TextView desc1 = ((TextView) v.findViewById(R.id.desc1));
if (v.isPressed()) {
v.setBackgroundColor(context.getResources().getColor(R.color.pressed));
list1.setTypeface(null, 1);
list1.setTextColor(context.getResources().getColor(R.color.selected));
} else {
v.setBackgroundColor(context.getResources().getColor(R.color.black));
if (v.isSelected()) {
list1.setTypeface(null, 1);
list1.setTextColor(context.getResources().getColor(R.color.checked));
desc1.setTextColor(context.getResources().getColor(R.color.white));
} else {
list1.setTypeface(null, 0);
list1.setTextColor(context.getResources().getColor(R.color.normal));
desc1.setTextColor(context.getResources().getColor(R.color.lesswhite));
}
}
return v;
}
}
Now you have special requirement, it is no longer simple, you can't use SimpleAdapter to achieve the effect you are asking. You will have to extend BaseAdapter and in the getView() method you can do the following:
if (position == 0) {
convertView.setBackground(color1);
} else {
convertView.setBackground(color2);
}
Or if what you want is a Header, you can use ListView.addHeaderView() without much hassle.
I found a solution, essentially contained in several posts here.
What I did was to use listview.setItemChecked(pos, true);, something that I tried before and failed, because it showed nothing. The problem was that LinearLayout does not implement Checkable. So I implemented it (code found essentially somewhere here also) with this:
public class CheckableLinearLayout extends LinearLayout implements Checkable {
private boolean isChecked;
public CheckableLinearLayout(Context context) {
super(context);
}
public CheckableLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setChecked(boolean isChecked) {
this.isChecked = isChecked;
TextView list1 = ((TextView) findViewById(R.id.list1));
TextView desc1 = ((TextView) findViewById(R.id.desc1));
if (isPressed()) {
list1.setTextColor(getResources().getColor(R.color.selected));
setBackgroundColor(getResources().getColor(R.color.pressed));
} else {
setBackgroundColor(getResources().getColor(R.color.black));
if (isChecked) {
list1.setTextColor(getResources().getColor(R.color.checked));
desc1.setTextColor(getResources().getColor(R.color.white));
} else {
list1.setTextColor(getResources().getColor(R.color.normal));
desc1.setTextColor(getResources().getColor(R.color.lesswhite));
}
}
}
public boolean isChecked() {
return isChecked;
}
public void toggle() {
setChecked(!isChecked);
}
}
And that's it. No need to use selector, nor to touch the adapter. To make this work, in the row layout, use <com.[yourpackage].CheckableLinearLayout instead of the usual LinearLayout.

Android ListView with a Custom Adapter - getChildAt() returns null

I have a ListView with a Custom Adapter, and I need to access the View of individual rows of this ListView. I am trying to do it using getChildAt(), but it is returning null.
Here's my ListView:
myListView = (ListView) findViewById (R.id.listViewLayout);
This is the custom adapter:
public class MyListAdapter extends BaseAdapter {
...
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_row_layout, parent, false);
}
...
}
I create a List, and set it for the ListView:
List <String> myList = new ArrayList<String>();
myList.add("entry 1");
myList.add("entry 2");
myList.add("entry 3");
MyListAdapter myListAdapter = new MyListAdapter(getApplicationContext(), myList);
myListView.setAdapter(myListAdapter);
Now, I want to access the View for individual rows.
View v = myListView.getChildAt(myListView.getFirstVisiblePosition());
This v is null, no matter what. Additionally, myListView.getChildCount() always returns null.
What am I missing? Do I need to add the convertView to parent in getView()? Am I passing wrong parameters to inflate?
I have struggled a lot to figure this out. Please help me!
EDIT: I am posting the MyListAdapter class:
public class MyListAdapter extends BaseAdapter {
private Context context;
private List<String> myList;
public MyListAdapter(Context c, List<String> m) {
context = c;
myList = m;
}
#Override
public int getCount() {
return myList.size();
}
#Override
public Object getItem(int position) {
return myList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final int pos = position;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_row_layout, parent, false);
}
TextView text = (TextView) convertView.findViewById(R.id.itemText);
text.setText(myList.get(pos));
// Set the onClick Listener on this button
Button rowButton = (Button) convertView.findViewById(R.id.itemButton);
//commenting next two lines makes the list row clickable
rowButton.setFocusableInTouchMode(false);
rowButton.setFocusable(false);
rowButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Toast.makeText(context, myList.get(pos), Toast.LENGTH_SHORT).show();
}
});
convertView.setTag(pos);
return convertView;
}
}
In all probability you're doing all of this in onCreate(). Any view-related methods will return null (or empty) because the list has not been rendered yet. What do you need the child view for?
Try instead of extending the BaseAdapter, to use the ArrayAdapter class. With the BaseAdapter, I believe that you have to maintain both the list of objects and the views themselves. So something like this
public class MyAdapter extends ArrayAdapter<String>
{
...
}
Then you would create the class like this.
MyListAdapter myListAdapter = new MyListAdapter(getApplicationContext(), R.layout.list_row_layout, myList);
Updated
Also, in your constructor, you are not calling your base class constructor.