List item layout containing a CheckBox doesn't work as expected

北慕城南 提交于 2019-12-12 04:51:51

问题


I have a ListView whose layout contains a CheckBox.

I want both the CheckBox to be active, and list items themselves to be tappable.

It doesn't work.

Yes, I know about the typical solution (setting focusable to false on the CheckBox so that it doesn't steal focus). It doesn't help.

Here's the layout of my list item:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"

    android:id="@+id/rl_container"

    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="8dp">

    <ImageView
        android:id="@+id/img_icon"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_margin="8dp"
        android:contentDescription="@null"
        android:scaleType="centerInside"
        android:visibility="gone"/>

    <RelativeLayout
        android:id="@+id/rl_texts"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/img_icon"
        android:layout_centerVertical="true">

        <TextView
            android:id="@+id/txt_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textIsSelectable="false"
            android:textColor="@color/black"/>

        <TextView
            android:id="@+id/txt_subtitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/txt_name"
            android:textIsSelectable="false"/>
    </RelativeLayout>

    <CheckBox
        android:id="@+id/cb_toggle_switch"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@+id/img_arrow"
        android:layout_alignWithParentIfMissing="true"
        android:layout_marginRight="25dp"/>

    <ImageView
        android:id="@+id/img_arrow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/arrow_button"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"/>

</RelativeLayout>

Here's the fragment hosting the list:

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

    <ListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:cacheColorHint="#00000000"

        android:clipToPadding="false"
        android:divider="@null"
        android:dividerHeight="0dp"
        android:listSelector="#00000000"
        android:paddingBottom="60dp"/>

</RelativeLayout>

Pretty simple.

Only removing CheckBox from the layout fixes the problem (tappability of the list items, obviously; I have no checkbox then, though).

Setting Visibility of the CheckBox to GONE (which I actually have to do for some items) doesn't fix it.

OnItemClickListener doesn't work at all.

OnClickListener of items - rl_container (the root view of the entire list item) and cb_toggle_switch (the checkbox) kind of works.

It's seems not to be deterministic. Clicking repeatedly sometimes fires the click listener of the container and the checkbox, and once you click several times in a row on the checkbox, you're able to force switching its state. But it's never immediate.

This made me suspect that behind the scenes we've got some complex logic regarding focus, but I attached OnFocusChangeListeners to both the container and the checkbox and they are never even notified.

I tried fiddling with descendantFocusability (on the ListView), disabling and enabling focusability and clickability of the container (root) layout.

Removing all subviews and leaving only the container and the checkbox leaves the same problem.

Any ideas? What would you try?


回答1:


I answered a question similar to this a day or so ago, except it was with image buttons, this should work though if you modify the imagebuttons to checkbox's, check it out..

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
    ListView lv;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list);
        lv = (ListView) findViewById( R.id.list );
        lv.setOnItemClickListener(
                new OnItemClickListener() {
                    public void onItemClick(AdapterView<?> arg0,
                            android.view.View arg1, int arg2, long arg3) {
                        Toast.makeText( MainActivity.this,
                                arg2 + " clicked",
                                Toast.LENGTH_SHORT).show();
                    }
            });
        ArrayList<String> items = new ArrayList<String>();
        items.add( "item1");
        items.add( "item2");
        items.add( "item3");
        items.add( "item4");
        items.add( "item5");
        items.add( "item6");
        items.add( "item7");
        items.add( "item8");
        items.add( "item9");
        items.add( "item10");
        items.add( "item11");
        items.add( "item12");
        items.add( "item13");
        items.add( "item14");
        items.add( "item15");
        ListAdapter adapter = new ListAdapter( this, items);
        lv.setAdapter( adapter );
    }  
}

and...

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.BaseAdapter;
import android.widget.Toast;

import java.util.List;

public class ListAdapter extends BaseAdapter {

    public ListAdapter(Context context,
                        List<String> items ) { 
        inflater = LayoutInflater.from( context );
        this.context = context;
        this.items = items;
    }

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

    public Object getItem(int position) {     
        return items.get(position);
    }

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

    public View getView(int position, View convertView, ViewGroup parent) { 
        String item = items.get(position);
        View v = null;
        if( convertView != null )
            v = convertView;
        else
            v = inflater.inflate( R.layout.item, parent, false);
        TextView itemTV = (TextView)v.findViewById( R.id.item);
        itemTV.setText( item );
        ImageButton button = 
            (ImageButton)v.findViewById( R.id.button);
        button.setOnClickListener(
                    new OnClickListener() {
                        public void onClick(View v) {
                            Toast.makeText( context,
                                    "ImageButton clicked",
                                    Toast.LENGTH_SHORT).show();
                        }
                    });
        return v;
    }

    private Context context;
    private List<String> items;
    private LayoutInflater inflater;
}

Good luck!




回答2:


I have a ListView with CheckBoxes in the rows. Here's what I did:

For the root view in the row.xml, I added:

android:descendantFocusability="blocksDescendants"

For the child elements (CheckBoxes) in the hierarchy, I added:

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



回答3:


If you don't want select it when you press on your list item, you can add an attribute to the checkbox attributes: android:enabled="false"



来源:https://stackoverflow.com/questions/26910822/list-item-layout-containing-a-checkbox-doesnt-work-as-expected

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!