tyczj
tyczj

Reputation: 74046

Using a checkbox and onListItemClick in listview

What I am trying to accomplish is to have a checkbox in each row, having the ability to check the box separately (for batch deleting) and being able to select the entire row to view data associated with the list item.

I have done a checkbox with a textview but that only lets be select the box and I cant click on the list item to view that items data. I also used checkedTextView but that checks the box where ever you click on the row calling the onListItemClick and thats not what I want either. Is there some what I can separate checking the box from clicking a listview item?

Pretty much trying to do what the gmail app does when selecting messages to delete and view

this is my row layout

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<CheckBox
    android:id="@+id/checkBox1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"/>

<TextView
    android:id="@+id/nameCheckTV"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignTop="@+id/checkBox1"
    android:layout_toRightOf="@+id/checkBox1"
    android:paddingTop="5dp"
    android:paddingLeft="15dp"
    android:text="Name"
    android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>

creating listview

@Override
    public void onActivityCreated(Bundle state){
        super.onActivityCreated(state);
        lv = getListView();
        lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        lv.setItemsCanFocus(false);
        setEmptyText("No Bowlers");       
        registerForContextMenu(getListView());
        populateList();
    }

EDIT:

my populate method

public void populateList(){

        String[] fields = new String[] {BowlersDB.NAME};
        //mAdapter = new CheckAdapter(getActivity(),R.layout.check_listview,null,fields,new int[] {R.id.nameCheckTV});
        mAdapter = new SimpleCursorAdapter(getActivity(),R.layout.check_listview,null,fields,
            new int[] {R.id.nameCheckTV});
        setListAdapter(mAdapter);         
        getLoaderManager().initLoader(0,null,this);
    }

Upvotes: 1

Views: 2640

Answers (4)

Alex Lockwood
Alex Lockwood

Reputation: 83311

The issue is that Android doesn't allow you to select list items that have elements on them that are focusable. Try modifying the checkbox on the list item:

android:focusable="false"

Upvotes: 13

MikeC
MikeC

Reputation: 374

The gmail app uses its own view called CanvasConversationHeaderView that manages its subviews. This method is probably more heavy-weight than what you are looking for.

An easier method would be to make the checkbox not "focusable" (as Alex Lockwood suggests) and then attach an onClick in the XML.

<CheckBox
    android:id="@+id/checkBox1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:focusable="false"
    android:onClick="onCheckboxClicked"/>

Then in your activity code add

public void onCheckboxClicked(View view) {
    RelativeLayout rl = (RelativeLayout)view.getParent();
    Log.d(TAG, "Checkbox clicked! getTag returned: " + rl.getTag());
}

EDIT: How to add a tag from SimpleCursorAdapter.bindView

private class MyCursorAdapter extends SimpleCursorAdapter {
    public MyCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
        super(context, layout, c, from, to);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        //Log.d(TAG, "Cursor pos: " + cursor.getPosition());
        String name = cursor.getString(
                cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
        view.setTag(name);
        super.bindView(view, context, cursor);
    }
}

Note: I set the tag to the View from the bindView call, which is the RelativeLayout at the root of your xml. Look at the onCheckboxClicked method to see how I got the tag.

Upvotes: 0

Codeman
Codeman

Reputation: 12375

I had a strange workaround with this issue. Here is my solution.

Use this for your ListView. Product is just a model object to hold your data in this case:

public class CatalogItemAdapter extends ArrayAdapter<Product> //
{
private ArrayList<Product> products;
private Activity activity;

public CatalogItemAdapter(Context context, int textViewResourceId,
        ArrayList<Product> items, Activity activity) //
{
    super(context, textViewResourceId, items);
    this.products = items;
    this.activity = activity;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) //
{
    Product product = products.get(position);

    if (convertView == null) //
    {
        LayoutInflater vi = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = vi.inflate(R.layout.catalog_item_stub, null, false);
    }
}
}

Somewhere in your onResume(), put this:

listView = (ListView) activity.findViewById(R.id.CatalogProducts);

m_adapter = new CatalogItemAdapter(activity,
            R.layout.catalog_item_stub, products, activity);

if (products == null)
        products = new ArrayList<Product>();

listView.setAdapter(m_adapter);

R.layout.catalog_item_stub is a layout stub created in XML like so (put the appropriate items in it for you, like the checkbox):

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:id="@+id/catalog_item_stub"
android:layout_width="match_parent" android:layout_height="90dp"
xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="5dp">
<LinearLayout android:layout_height="match_parent"
    android:layout_width="match_parent" android:weightSum="5"
    android:gravity="center_vertical|right">
    <TextView android:layout_width="0dp" android:layout_height="match_parent"
        android:text="product_title" android:textAppearance="?android:attr/textAppearanceMedium"
        android:id="@+id/ProductTitle" android:padding="5dp"
        android:layout_weight="2.5" android:textColor="#000000" />
    <CheckBox android:padding="5dp" android:layout_height="match_parent"
        android:text="select" android:layout_width="0dp" android:id="@+id/chkSelect"
        android:layout_weight="1.5" android:textColor="#000000"
        android:gravity="right" />
</LinearLayout>

Hopefully this helps! Holler if you need any clarification.

Upvotes: 0

Alex Paino
Alex Paino

Reputation: 250

You need to set an onItemClickListener for your ListView that will start another activity with the info of the row selected when the row is clicked (outside the CheckBox of course). I would recommend having your Activity implement AdapterView.OnItemClickListener which requires the method

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {}

Inside this method you can launch an Activity with details corresponding to the data in the row selected. Hopefully I understood your question correctly.

Upvotes: -3

Related Questions