Unable to check/uncheck CheckedTextView inside getView
Asked Answered
A

3

16

I'm loading phone contacts in a custom ListView. Each row is a checkable LinearLayout containing a CheckedTextView and another TextView.

I'm feeding the list view with a custom ArrayAdapter. My problem is that I can't control CheckedTextViews inside getView(). For example when I try the following

public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        if(row == null){            
            row = inflater.inflate(layout, parent, false);
        }

        CheckedTextView checkedTextView =  (CheckedTextView) row.findViewById(R.id.checkedTextView);
        checkedTextView.setText("A");
        checkedTextView.setChecked(true);
        return row;
    }

That's supposed to check every text view whenever I scroll the list view, but that's not happening. Can anybody tell me how to do it?

EDIT: It's important to check it inside getView(), I can't just check all after setListAdapter()

EDIT2: This is the xml file showing the view of each row

<?xml version="1.0" encoding="utf-8"?>
<com.example.multiplecontacts.CheckableLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <CheckedTextView
        android:id="@+id/checkedTextView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:checkMark="?android:attr/listChoiceIndicatorMultiple"
        android:paddingBottom="0dp"
        android:text="CheckedTextView"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <TextView
        android:id="@+id/subTextView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Small Text"
        android:paddingTop="0dp"
        android:textAppearance="?android:attr/textAppearanceSmall" />

</com.example.multiplecontacts.CheckableLinearLayout>

CheckableLinearLayout is a custom layout that extends LinearLayout and implements Checkable as I said before. And I've taken it from here

Antoniaantonie answered 28/9, 2012 at 14:1 Comment(3)
I don't need it to be checked by default. Actually the above code is not my actual code it's just a sample demonstrating my problem. All what I need is to be able to toggle a CheckedTextView inside getView()Antoniaantonie
You got layout with checkbox but when you press the checkbox doesn't checked?Patch
Following the good response of Alex Orlov i did like this: public View getView(int position, View convertView, ViewGroup parent) {..... ((ListView) parent).setItemChecked(position, true);....}Cinchonism
C
29

Did you set a checkMark property for your CheckedTextView in your layout xml?

For example: android:checkMark="?android:attr/listChoiceIndicatorMultiple

CheckedTextView is not just a checkbox with a text. You must also note, that CheckedTextView is not focusable, or clickable without some manipulation (since it was designed for ListView and therefore it's state must be controlled by ListView's setOnItemClickListener)

setChoiceMode should be set for a ListView. And checking of the row inside adapter's getView should be done via: listView.setItemChecked(position, value)

Catima answered 28/9, 2012 at 14:12 Comment(8)
I did. And it's checked/unchecked normally when I press an item myself. It's just inside getView() that behaves like that.Antoniaantonie
So it can be controlled only in setOnItemClickListener ?? there is no way to toggle it outside it?Antoniaantonie
Where this piece of code should be written? I'm trying to toggle the checkedTextView automatically, not when an onClick event is released. I already implemented onListItemClick and it works well.Antoniaantonie
Probably CheckedTextView is controlled by ListView, did you setChoiceMode to multiple for ListView?Catima
Yes, I did. And it behaves as supposed and I can select multiple contacts.Antoniaantonie
if you have access to instance of your ListView from adapter you can (and probably should) use listView.setItemChecked(position, value)Catima
Alex Orlov, prefect. Thanks very much. I've passed an instance to the adapter and done what you said. And it works now like charm. Please edit your answer and include your comment :)Antoniaantonie
You can use ((ListView) parent).setItemChecked(position, true); from the adapter instead of passing a reference.Jacelynjacenta
W
3

@Pier-Luc Gendreau and @fox mentioned the solution in comments but not in answer, so posting answer on their behalf.

As mentioned by @AlexOrlov, CheckedTextView is not focusable, or clickable without some manipulation. So what you have to do is set item check using ListView, you can either do it from the adapter itself or from activity/fragment where you have ListView.

To do it from adapter,

public View getView(int position, View convertView, ViewGroup parent) 
{ 
if (//logic) {
((ListView) parent).setItemChecked(position, true);
}
}

From activity/fragment

if (//logic) {
listView.setItemChecked(position, true);
}
Whip answered 27/2, 2017 at 18:34 Comment(0)
G
1

When ever you scroll list, every time it calls its getview() method. So, if you have any checkbox or any editbox in listcell it will reinitialize it.

My idea is to store the status (checked or unchecked) of checkbox. So here I used ArrayList first I filled it with false value then on its click event i used to store it actual status.

 class MyAdapter extends BaseAdapter  implements OnClickListener   {

    private ArrayList<Boolean> checks=new ArrayList<Boolean>();//Boolean type array to   manage check box

  private static LayoutInflater inflater=null;

    public MyAdapter(Context context, ArrayList<HashMap<String, String>> d)
    {
              inflater =     (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

      //fill with false values
    for (int i = 0; i < d.size(); i++) 
    {
            checks.add(i, false);
    }
    }

    public int getCount()
    {
        return data.size();
    }

    public Object getItem(int position)
    {
        return position;
    }

    public long getItemId(int position) 
    {
        return position;
    }




        public View getView(int position, View convertView, ViewGroup parent)
       {

        View vi=convertView;

        if(convertView==null)

          vi = inflater.inflate(R.layout.<your layout>, null);

          //Checkbox is of button type----android:button="@drawable/btn_check"
          //make a selector xml for checkbox       

          checkBox=(CheckBox)vi.findViewById(R.id.check_box);


          checkBox.setTag(Integer.valueOf(position));
          checkBox.setOnClickListener(this);
          checkBox.setChecked(checks.get(position));


        return vi;
    }

        @Override
        public void onClick(View v) 
        {
          int viewId=v.getId();
          if(viewId== R.id.check_box)
          {
            Integer index = (Integer)v.getTag();
            boolean state = checks.get(index.intValue());
            checks.set(index.intValue(), !state);

          }
        }
     }

Update: Solution 2nd: You can put a boolean variable in your ViewHolder class. This boolean variable will used to define wether item is selected or not.

Hope this should help you.

Garin answered 28/9, 2012 at 14:32 Comment(2)
checkBox.setChecked(checks.get(position)); is that working with you? is checkBox of type CheckedTextView or just a checkbox?Antoniaantonie
@IslamHassan yes its working on my side. Here my checkbox is of Button type.Garin

© 2022 - 2024 — McMap. All rights reserved.