Confused about android clickable, focusable true-false and their work

Xplosive picture Xplosive · Mar 25, 2014 · Viewed 10.4k times · Source

I have created a grid view follow this link

Android - Gridview with Custom BaseAdapter, get clicked View at position

It works fine. But I am confused at these two line in cell.xml

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

It is false but it is working when I click and it is not working when I turn it o true. So I am confused and I have some questions –

•   Why they are needed? When we generally create button we don’t define these two attribute. But I when create a button for grid view cell why it is needed?
•   Why they work in reverse way? 
•   Is there any way to avoid these two line?

cell.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <Button
        android:id="@+id/grid_item"
        android:layout_gravity="center"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="05"
        android:textSize="20sp"
        android:clickable="false"
        android:focusable="false"/>
    </Button>

</LinearLayout>

MainActivity.java

public class MainActivity extends Activity {

    private TextView text;
    private GridView gridView;
    private final String[] items = new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
            "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        text = (TextView) findViewById(R.id.feedback);

        gridView = (GridView) this.findViewById(R.id.myGridView);
        CustomGridAdapter gridAdapter = new CustomGridAdapter(MainActivity.this, items);
        gridView.setAdapter(gridAdapter);
        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                text.setText((String) (gridView.getItemAtPosition(position)));
                Log.i("ITEM_CLICKED", "" + (String) (gridView.getItemAtPosition(position)));
            }
        });

    }
}

CustomGridAdapter.xml

public class CustomGridAdapter extends BaseAdapter {

    private Context context;
    private String[] items;
    LayoutInflater inflater;

    public CustomGridAdapter(Context context, String[] items) {
        this.context = context;
        this.items = items;
        inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

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

        if (convertView == null) {
            convertView = inflater.inflate(R.layout.cell, null);
        }
        Button button = (Button) convertView.findViewById(R.id.grid_item);
        button.setText(items[position]);

        return convertView;
    }

    @Override
    public int getCount() {
        return items.length;
    }

    @Override
    public Object getItem(int position) {
        return items[position];
    }

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

Answer

Stephane Mathis picture Stephane Mathis · Mar 25, 2014

In most case the view for each cell doesn't have anything that could consume the click event. So when you click on a row, the onItemClickListener will be called by the GridView (or Listview).

But here there is a Button which is clickable by default. The thing is that a view inside a GridView can capture the click event and prevent the propagation to the gridview onItemClick event.

So to avoid the button to keep the event, you can say that it should not be clickable, with the attribute clickable.

Having clickable elements in a cell can be used to have multiple clickable area for each row.