Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
144 views
in Technique[技术] by (71.8m points)

android - adding CheckBox to list row loses my onItemClick events?

I have a ListView with an ArrayList adapter. The rows are not very complex (an Image on the left, a LinearLayout with TextViews inside, and a CheckBox on the right ... the layout is copied in below.) The goal is to have a QuickAction bar come up if the user clicks on the image or text, and have the CheckBox change state if the user clicks on the CheckBox. I have each part working independently, but not when they're together in the layout - somehow, I'm losing the onItemClick event.

The "QuickAction" bar is activated by OnItemClickListener(), and it works fine - unless I have the CheckBox in the layout, in which case the CheckBox works fine (using onClick()) but the onItemClickListener is never fired if the user clicks in the row but outside the CheckBox. The layout (minus some style stuff) is:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/vw1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <ImageView android:id="@+id/img"
        android:layout_alignParentLeft="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <CheckBox android:id="@+id/ckb"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_gravity="right"
    android:checked="false" />

<!-- stack text in middle section of the row -->
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >

        <TextView android:id="@+id/text1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content""/>

        <TextView android:id="@+id/text2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
</RelativeLayout>

The code behind it isn't complicated:

public class ListGroupsActivity extends BaseActivityForList {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list);

        // add QuickAction bar
        ListView lv = getListView();
        lv.setOnItemClickListener(new QAListener(this));
    }
}

    //inner classes of the ListGroupsActivity
    class CbOnClickListener implements OnClickListener {
        // ...
        // test the checkbox isChecked() and keep state in 'selectedItems' array

    class GroupListAdapter extends ArrayAdapter<Group> {
        super(/*...*/)
    CbOnClickListener cblistener = null; // common listener for all the CheckBoxes

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // here do normal testing for convertView being null etc 
            // heres the view inflation from the layout into the ViewHolder
            holder.tv1 = (TextView) convertView.findViewById(R.id.text1);
            holder.tv2 = (TextView) convertView.findViewById(R.id.text2);
            holder.img = (ImageView) convertView.findViewById(R.id.img);
            holder.ckb = (CheckBox) convertView.findViewById(R.id.ckb);

            Group g = groups.get(position); // this is the data obj for the row

            holder.tv1.setText(g.getName());
            holder.tv2.setText("child groups");
            Bitmap bm = BitmapFactory.decodeFile(g.getIconUri());
            holder.img.setImageBitmap(bm);
            Integer key = (Integer) g.getId();
            holder.ckb.setChecked(selectedItems.contains(key)); 

            holder.ckb.setOnClickListener(cblistener); // hook onClick to cblistener
            return convertView;
    }

The QAListener is in a superclass for all my list activities:

public class BaseActivityForList extends
    OrmLiteBaseListActivity<DatabaseHelper> {

    // QAListener inner class, constructs new quick action bar when item clicked
    class QAListener implements OnItemClickListener {
        public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) {
            // has three ActionItem instances, 'copyAction', 'delAction', 'editAction'
            ActionItem copyAction = new ActionItem();

            copyAction.setOnClickListener(new OnClickListener() {
                 @Override
                 public void onClick(View v) {
                     // ... does some stuff
                     mQuickAction.dismiss();
                 }
             }); // end setOnClickListener
        } // end onItemClick
    } // end QAListener
} end BaseActivityForList

So, how do I arrange for the Checkbox to pick up the onClick, and the rest of the list item to pick up the onItemClick()?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

After few hours of debugging and research. I got it working by setting following properties on the checkbox:

android:focusable="false"
android:focusableInTouchMode="false"

Also ImageView may need to be configured as described in http://blog.sachin.name/?p=62 (Thanks to that person)

On my side, I discovered that item view MUST NOT be clickable and text views should not be clickable, either. It took me a while to realize that I called setClickable(true) on my item view somewhere in the code.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...