Android Layout make all children's not clickable

后端 未结 12 2066
一生所求
一生所求 2021-01-01 12:45

I am using Relative Layout and many buttons in it with TextViews etc.I want to make all of them not clickable unless some event happens.

相关标签:
12条回答
  • 2021-01-01 13:03

    Problem : same as original question, but different use case. i want to progressBar widget which in container with transparent background colors. i want to disable all clicks on other items which comes under my transparent background color .

    solution : just set your container clickable in my case Relative layout, it can any other layout too, keep your layout clickable true, until you want according to condition in my case till api call completed. after it simply set your parent clickable false.

    android xml

    <RelativeLayout
    android:id="@+id/rl_parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <!-- the children views begins -->
    ...
    <!-- the children views ends -->
    
    
    </RelativeLayout>
    

    Java:

    rl_parent.setClickable(true); // when to disable all clicks of children view
    
    rl_parent.setClickable(false); // when to enable all clicks of children view
    
    0 讨论(0)
  • 2021-01-01 13:05

    When you say click do you actually mean touch? Touch events are done element by element. They're first sent to the top level, which says if it handled it and if it didn't it goes onto each children of the view.

    When a touch event is created, the onTouch method of view in the chain is called, if any of these return true (true meaning "I handled this!") it stops going down to the children.

    To make your relativelayout block touches and clicks for all of its children you simply need to set the onTouchListener, like this:

    YOUR_RELATIVE_LAYOUT.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // ignore all touch events
            return true;
        }
    });
    

    This will ignore all touch events happening on the relative layout (and all of its children) which includes simple touch down then release events (called clicks).

    0 讨论(0)
  • 2021-01-01 13:06

    You can use following function to find all the child view and cancel click.

      public void setClickable(View view) {
        if (view != null) {
            view.setClickable(false);
            if (view instanceof ViewGroup) {
                ViewGroup vg = ((ViewGroup) view);
                for (int i = 0; i < vg.getChildCount(); i++) {
                    setClickable(vg.getChildAt(i));
                }
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-01 13:10

    As an alternative way, you can make clickable ViewGroup with children views via FrameLayout instead of RelativeLayout. Just position your child views in FrameLayout using paddings and gravity, make FrameLayout clickable, and all children views non-clickable:

    <FrameLayout
        android:layout_width="51dp"
        android:layout_height="59dp"
        android:layout_gravity="center"
        android:clickable="true"
        android:focusable="true"
        android:onClick="@{() -> activity.onClick()}"
        android:padding="5dp">
    
        <android.support.v7.widget.AppCompatImageButton
            android:layout_width="wrap_content"
            android:layout_height="29dp"
            android:layout_gravity="center"
            android:clickable="false"
            app:srcCompat="@drawable/ic_back" />
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|left"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="5dp"
            android:clickable="false"
            android:text="@string/back" />
    </FrameLayout>
    
    0 讨论(0)
  • 2021-01-01 13:11

    If Butterknife library is used, the views can be grouped and the functionality can be done on the group. Refer http://jakewharton.github.io/butterknife/,

    @BindViews({ R.id.first_name, R.id.middle_name, R.id.last_name })
    List<EditText> nameViews;
    

    The apply method allows you to act on all the views in a list at once.

    ButterKnife.apply(nameViews, DISABLE);
    ButterKnife.apply(nameViews, ENABLED, false);
    

    Action and Setter interfaces allow specifying simple behavior.

    static final ButterKnife.Action<View> DISABLE = new ButterKnife.Action<View>() {
      @Override public void apply(View view, int index) {
        view.setEnabled(false);
      }
    };
    
    static final ButterKnife.Setter<View, Boolean> ENABLED = new ButterKnife.Setter<View, Boolean>() {
      @Override public void set(View view, Boolean value, int index) {
        view.setEnabled(value);
      }
    };
    

    For eg., if the textviews are grouped, you could do

    static final ButterKnife.Setter<TextView, Boolean> ENABLED = new ButterKnife.Setter<TextView, Boolean>() {
            @Override public void set(TextView view, Boolean value, int index) {
                view.setClickable(value);
                view.setLongClickable(value);
                if(value){
                    view.setTextColor(color);
                } else {
                    view.setTextColor(color);
                }
            }
        };
    
    0 讨论(0)
  • 2021-01-01 13:13

    A very simple and full-proof way to do it is to create a sub class and override onInterceptTouchEvent:

    public class MyRelativeLayout extends RelativeLayout {
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            // true if you do not want the children to be clickable.
            return mShouldInterceptAllTouch;
        }
    }
    

    No need to call any of the children's methods.

    You can still call setOnClickListener on your myRelativeLayout object. Also, you can use the class in XMLs as if you were using a RelativeLayout

    0 讨论(0)
提交回复
热议问题