How to realize strikethrough text in Listview with CheckBox? - android-listview

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

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.

Only 1 button enable in ListView, custom adapter

I run into a problem where I need to enable my button in the ListView. The weird thing is :
public class CookingStepAdapter extends ArrayAdapter<CookingStep> {
...
private void addButtonToList(Button clock, Button skip){
if (list_clock_button == null) {
list_clock_button = new ArrayList<Button>();
iterate = 0;
}
if (list_skip_button == null)
list_skip_button = new ArrayList<Button>();
list_clock_button.add(clock);
list_skip_button.add(skip);
clock.setEnabled(true);
skip.setEnabled(true);
list_clock_button.get(0).setEnabled(true);
list_clock_button.get(0).setFocusable(true);
list_clock_button.get(0).setFocusableInTouchMode(true);
list_clock_button.get(0).invalidate();
list_skip_button.get(0).setEnabled(true);
list_skip_button.get(0).setFocusable(true);
list_skip_button.get(0).setFocusableInTouchMode(true);
list_skip_button.get(0).postInvalidate();
}
}
When I set enable with the list_clock_button.get(0), it's not working at all. But clock.setEnabled(true); actually worked.
But then I only want the first button of the ListView enabled, that makes the first option more fit in this situation. The second option works, but it made all the buttons enabled, that's not what I want. I did recheck the first button address, and it matched list_clock_button.get(0), why it's not working.
EDIT :
Here's my function getView :
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.cooking_steps_and_timer, parent, false);
final Button button = (Button) rowView.findViewById(R.id.button_timer);
final TextView timer = (TextView) rowView.findViewById(R.id.cooking_timer);
final Button skipButton = (Button) rowView.findViewById(R.id.button_skip);
TextView stepContent = (TextView) rowView.findViewById(R.id.cooking_step_content);
final CookingStep step = list.get(position);
String stepOrder = (String) context.getResources().getText(R.string.step_order) + " " + step.getOrder();
String content = "<b>" + stepOrder + ":</b>" + " " + step.getContent() + "\n";
stepContent.setText(Html.fromHtml(content));
if (step.getTimer() == null || step.getTimer() == 0){
timer.setVisibility(View.GONE);
button.setVisibility(View.GONE);
skipButton.setVisibility(View.GONE);
} else {
//myTimer = new CookingTimer(step.getTimer());
timer.setText(step.getMyTimer().toString());
step.setCountDown(new CountDownTimer(step.getTimer() * 60000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
step.getMyTimer().tick();
timer.setText(step.getMyTimer().toString());
}
#Override
public void onFinish() {
nextButtonEnable();
}
});
button.setText(R.string.button_available);
skipButton.setText(R.string.skip_button_content);
addButtonToList(button, skipButton);
//button.setEnabled(true);
list_clock_button.get(0).setEnabled(true);
button.requestFocusFromTouch();
button.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (!button.isPressed()) {
button.setPressed(true);
button.setText(R.string.button_available);
step.getCountDown().start();
} else {
button.setPressed(false);
button.setText(R.string.button_pressed);
step.getCountDown().cancel();
}
}
return true;
}
});
skipButton.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
step.getCountDown().cancel();
nextButtonEnable();
}
return true;
}
});
}
return rowView;
}
The reason of all buttons getting enabled is you are setting all of them enable yourself. To set any particular button enable you have to check the id or the item position to set that particular button to enable.
Like this for example:-
if(clock.getID == R.id.some_id_in_xml){
clock.setEnabled(true);
}
But before that you have to check the position of the item to select the desired item in the list.

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

setOnCheckedChangeListener

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.

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.