How to make EditText's parent clickable?

2019-07-25 14:56发布

问题:

Suppose I have this pink box:

It consists of LinearLayout with its children: TextView as field name and an EditText. EditText is intentionally disabled. What I want is that, user can click wherever user wants on that pink box. By the way, please just ignore any UI/UX things that you found weird.

I've tried, but user can't tap the area that EditText occupies. User have to tap in TextView or blank area on pink box so that the apps got the 'click'. But if user taps on EditText's area, nothing will happen.

I've tried playing with some things in xml's properties, such as set LinearLayout's clickable to true, and all children or just EditText's properties of clickable, focusable, and focusableInTouchMode to false, all to no avail. EditText area still cannot be clicked.

Any idea? Can't it be reached just through xml? Should it be done programmatically just to turn bypass EditText's click?

回答1:

You can simply add onTouch Listener instead of click Listener.



回答2:

You need to request the parent layout (LinearLayout, whatever) and loop through the views if you dont want to bind them all. If you use databinding its easier. Anyway, here is a solution (a small piece of code is required!).

Layout:

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

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="out of focus"/>

    <LinearLayout
        android:id="@+id/linearTest"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="test for clicking"
            />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="another clicking test"
            />

        <EditText
            android:id="@+id/editTest"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="focus edittext when clicking linearlayout or other elements inside"
            />
    </LinearLayout>

</LinearLayout>

Code:

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        setContentView(R.layout.linear_focus_test);

        final EditText editText = (EditText) findViewById(R.id.editTest);

        LinearLayout linearTest = (LinearLayout) findViewById(R.id.linearTest);
            for (int i = 0; i < linearTest.getChildCount(); i++)

            View v = linearTest.getChildAt(i);
            v.setOnClickListener(new View.OnClickListener() {
                @Override public void onClick(View v) {
                    editText.requestFocus();
                }
            });
        }
}

If you dont like boilerplate you may also use lambda (use 1.8 features)

for (int i = 0; i < linearTest.getChildCount(); i++)
            linearTest.getChildAt(i).setOnClickListener(v1 -> editText.requestFocus());

If you use at least API 24 you can even make it shorter:

IntStream.range(0, linearTest.getChildCount()).forEach(i -> linearTest.getChildAt(i).setOnClickListener(v1 -> editText.requestFocus()));