मैं लेआउट के अंदर सभी विचारों को कैसे अक्षम कर सकता हूं?


84

उदाहरण के लिए मेरे पास है:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
        android:layout_height="fill_parent">
     <Button 
        android:id="@+id/backbutton"
        android:text="Back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <LinearLayout
        android:id="@+id/my_layout"
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/my_text_view"
            android:text="First Name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <EditText
            android:id="@+id/my_edit_view"
            android:width="100px"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" /> 
        <View .../>
        <View .../>
        ...
        <View .../>
    </LinearLayout>

</LinearLayout>

क्या LinearLayout के अंदर सभी तत्वों को अक्षम करने (सेट करने योग्य (गलत)) का कोई तरीका है my_layout?

जवाबों:


98

एक और तरीका है कि प्रत्येक बच्चे पर सेटएनेबल () कॉल करें (उदाहरण के लिए यदि आप अक्षम होने से पहले बच्चे पर कुछ अतिरिक्त जांच करना चाहते हैं)

LinearLayout layout = (LinearLayout) findViewById(R.id.my_layout);
for (int i = 0; i < layout.getChildCount(); i++) {
    View child = layout.getChildAt(i);
    child.setEnabled(false);
}

20
हालाँकि यह केवल पहले स्तर के बच्चों के लिए काम करता है, अगर आपके पास नेस्टेड विचार हैं तो यह काम नहीं करेगा।
htafoya

एक समाधान एक पुनरावर्ती कार्य कर रहा है, एक व्यूग्रुप को पैरामीटर के रूप में पारित कर रहा है। अगर यह एक EditText है, तो अपने हर बच्चों के लिए कक्षा की जाँच करें।
स्टोनलैम

126

यह एक ViewGroups के लिए पुनरावर्ती है

private void disableEnableControls(boolean enable, ViewGroup vg){
    for (int i = 0; i < vg.getChildCount(); i++){
       View child = vg.getChildAt(i);
       child.setEnabled(enable);
       if (child instanceof ViewGroup){ 
          disableEnableControls(enable, (ViewGroup)child);
       }
    }
}

अच्छा स्निपेट, लेकिन स्क्रॉलव्यू अभी भी स्क्रॉल किए जाएंगे, अतिरिक्त कार्यक्षमता के लिए कुछ और कोड की आवश्यकता है
htafoya

स्पिनरों को अक्षम नहीं होने का कारण नहीं पता :(
विवेक सिंह

ViewPagers भी अक्षम नहीं है, इसके अंदर के दृश्य भी शामिल हैं।
राफेल C

1
यह काम नहीं करता है क्योंकि setEnabled () का कार्यान्वयन दृश्य के उपवर्ग पर होता है, दूसरे शब्दों में इसे अलग-अलग विचारों के लिए अलग-अलग लागू किया जा सकता है। तो वहाँ कोई रास्ता नहीं है इस तरह के दृष्टिकोण के अस्तित्व में हर दृश्य के लिए काम करेंगे
रेक्सप्लोड

83

टूटू का जवाब सही रास्ते पर है, लेकिन उसकी पुनरावृत्ति थोड़ी अजीब है। मुझे लगता है कि यह क्लीनर है:

private static void setViewAndChildrenEnabled(View view, boolean enabled) {
    view.setEnabled(enabled);
    if (view instanceof ViewGroup) {
        ViewGroup viewGroup = (ViewGroup) view;
        for (int i = 0; i < viewGroup.getChildCount(); i++) {
            View child = viewGroup.getChildAt(i);
            setViewAndChildrenEnabled(child, enabled);
        }
    }
}

उत्कृष्ट समाधान। धन्यवाद
Blodhgard

यह सही जवाब है। यह पुनरावर्ती होकर जाता है। वर्तमान स्वीकृत उत्तर केवल एक स्तर गहरा होता है।
चुपके रब्बी

यह सबसे अच्छा जवाब है। यह सभी लेआउट के अंदर स्पर्श करता है। यही तो मैं चाहता था। धन्यवाद!
दीनथ रुक्शन कुमारा

24

मेरे लिए क्या काम है:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);

और इसे पूर्ववत करने के लिए:

getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);

3
अच्छा सरल समाधान है कि काम करता है!
श्मिट 1

2
यह समाधान गतिविधि में सभी विचारों को अक्षम कर देगा। वास्तव में प्रश्न का समाधान नहीं करता है। क्या होगा यदि लक्ष्य गतिविधि में केवल कुछ ViewGroups को अक्षम करना है?
एलनकिल

2
बिलकुल मैं ढूंढ रहा था, धन्यवाद !! लेकिन तब मैं यह पता लगा सकता हूं कि क्या उपयोगकर्ता कहीं क्लिक करना चाहता है?
स्किज़ो- oz 19S

1
महान सरल उपाय
WHOATEMYNOODLES

1
सबसे अच्छा समाधान यदि u केवल एक या दृश्य सेट को अक्षम / सक्षम करना चाहते हैं तो setEnabled (बूल) का उपयोग करें या यदि दृश्य इस दृश्य के सभी बच्चों के माध्यम से एक दृश्य लूप के सभी बच्चे हैं और उन सभी को अक्षम करें लेकिन मुझे लगता है कि यह समाधान सबसे अच्छा है (मेरा मतलब है कि यह उत्तर) धन्यवाद इदैन
मोहम्मद एल्सेयेद

21

यदि आप एक विशिष्ट ViewGroup में विचारों को अक्षम करने में रुचि रखते हैं तो आप दिलचस्प, शायद थोड़ा अस्पष्ट उपयोग कर सकते हैं duplicateParentState। एक दृश्य स्थिति बूलियन विशेषताओं का एक सेट है जैसे कि दबाया, सक्षम, सक्रिय और अन्य। बस उस प्रत्येक बच्चे पर इसका उपयोग करें जिसे आप मूल दृश्य में सिंक करना चाहते हैं:

android:duplicateParentState="true"

ध्यान दें कि यह पूरे राज्य को डुप्लिकेट करता है न कि केवल सक्षम स्थिति को। यह वही हो सकता है जो आप चाहते हैं! यदि आप लेआउट XML लोड कर रहे हैं, तो निश्चित रूप से, यह दृष्टिकोण सबसे अच्छा है।


13

आइए tütü का कोड बदलें

private void disableEnableControls(boolean enable, ViewGroup vg){
for (int i = 0; i < vg.getChildCount(); i++){
   View child = vg.getChildAt(i);
   if (child instanceof ViewGroup){ 
      disableEnableControls(enable, (ViewGroup)child);
   } else {
     child.setEnabled(enable);
   }
 }
}

मुझे लगता है, सिर्फ व्यूग्रुप को निष्क्रिय करने का कोई मतलब नहीं है। यदि आप इसे करना चाहते हैं, तो एक और तरीका है जिसका मैंने बिल्कुल उसी उद्देश्य के लिए उपयोग किया है। अपने ग्रुपव्यू के एक दृश्य के रूप में देखें:

<View
    android:visibility="gone"
    android:id="@+id/reservation_second_screen"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="bottom"
    android:background="#66ffffff"
    android:clickable="false" />

और रन-टाइम पर, इसे दृश्यमान बनाएं। नोट: आपके ग्रुपव्यू के पैरेंट लेआउट या तो रिश्तेदार या फ़्रेम लेआउट होना चाहिए। आशा है कि यह मदद करेगा।


1
आपका कोड उदाहरण के लिए स्पिनर को अक्षम नहीं करेगा, क्योंकि स्पिनर
व्यूग्रुप का

12

यदि कुछ हताश डेवलपर यहां स्क्रॉल करते हैं, तो मेरे पास एक और विकल्प है। जहाँ तक मैंने इसके साथ प्रयोग करने तक स्क्रॉलिंग को अक्षम कर दिया है। इस विचार को अपने सभी UI तत्वों के तहत किसी RelativeLayout में इस तरह देखें तत्व का उपयोग करना है।

<View
                android:id="@+id/shade"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/primaryShadow"
                android:visibility="gone"/>

तो यह कुछ हालत से पहले "चला गया" होना तय है। और फिर जब आप अपने यूआई को निष्क्रिय करना चाहते हैं तो आप इसे विज़िबिलिटी की दृश्यता निर्धारित करते हैं। साथ ही आपको OnClickListenerइस View के लिए कार्यान्वयन करना होगा। यह onClickListenerक्लिक ईवेंट को पकड़ लेगा और इसे अंतर्निहित तत्वों के पास नहीं भेजेगा।


1
यही कारण है कि मैं देख रहा था, हाँ मैं हताश था और पागलों की तरह अपने समाधान स्क्रॉलिंग पाया: D
Skizo-oz'S

1
बहुत अच्छा समाधान है, वास्तव में मेरे दिमाग में था और मैं किसी और की तलाश में था, उसी विचार के साथ इसलिए मैं एक पागल कुंवारा नहीं हूं; डी
रिकार्ड

12

मैं व्यक्तिगत रूप से कुछ इस तरह का उपयोग करता हूं (वर्टिकल ट्री ट्रैवर्सल इन रिकर्सन का उपयोग करके)

fun ViewGroup.deepForEach(function: View.() -> Unit) {
    this.forEach { child ->
        child.function()
        if (child is ViewGroup) {
            child.deepForEach(function)
        }
    }
}

उपयोग:

   viewGroup.deepForEach { isEnabled = false }

1
सुरुचिपूर्ण समाधान।
राफेल सी

forEachमुझे लगता है कि विधि याद आ रही है
Skizo-oz AugS

@ Skizo-ozᴉʞS यह एक androidx.core.viewतरीका है: developer.android.com/reference/kotlin/androidx/core/view/…
Achraf Amil

5

विवरण

  • एंड्रॉइड स्टूडियो 3.1.4
  • कोटलिन 1.2.70
  • minSdkVersion 19 में जाँच की गई

उपाय

fun View.forEachChildView(closure: (View) -> Unit) {
    closure(this)
    val groupView = this as? ViewGroup ?: return
    val size = groupView.childCount - 1
    for (i in 0..size) {
        groupView.getChildAt(i).forEachChildView(closure)
    }
}

प्रयोग

val layout = LinearLayout(context!!)
layout.forEachChildView {  it.isEnabled = false  }

val view = View(context!!)
view.forEachChildView {  it.isEnabled = false  }

val fragment = Fragment.instantiate(context, "fragment_id")
fragment.view?.forEachChildView {  it.isEnabled = false  }

एक आकर्षण की तरह काम किया;)
स्कीज़ो-ओज़्स

3

हालांकि लेआउट के भीतर विचारों को अक्षम करने के समान नहीं है , यह ध्यान देने योग्य है कि आप ViewGroup # onInterceptTitEvent (MotionEvent) विधि को ओवरराइड करके सभी बच्चों को स्पर्श प्राप्त करने से रोक सकते हैं (लेआउट पदानुक्रम की पुनरावृत्ति के बिना)।

public class InterceptTouchEventFrameLayout extends FrameLayout {

    private boolean interceptTouchEvents;

    // ...

    public void setInterceptTouchEvents(boolean interceptTouchEvents) {
        this.interceptTouchEvents = interceptTouchEvents;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return interceptTouchEvents || super.onInterceptTouchEvent(ev);
    }

}

तब आप बच्चों को स्पर्श कार्यक्रम प्राप्त करने से रोक सकते हैं:

InterceptTouchEventFrameLayout layout = (InterceptTouchEventFrameLayout) findViewById(R.id.layout);
layout.setInterceptTouchEvents(true);

यदि आपके पास एक क्लिक श्रोता सेट है layout, तो यह अभी भी चालू हो जाएगा।


इस उत्तर को प्यार करो। सभी बच्चों को निष्क्रिय करने के लिए लगातार व्यूग्राफ की तुलना में बहुत हल्का वजन और कुशल! इस समस्या को हल करने के लिए अभी भी क्लिकों के जवाब के साथ, आप बस सेट में लेआउट को अक्षम / सक्षम कर सकते
हैंइंटरसेप्ट टचवेंट्स

2
  private void disableLL(ViewGroup layout){
    for (int i = 0; i < layout.getChildCount(); i++) {
        View child = layout.getChildAt(i);
        child.setClickable(false);
        if (child instanceof ViewGroup)
            disableLL((ViewGroup) child);
    }
}

और इस तरह से कॉल विधि:

RelativeLayout rl_root = (RelativeLayout) findViewById(R.id.rl_root);
disableLL(rl_root);

2

कोटलिन में, जोड़े जाने isDuplicateParentStateEnabled = trueसे पहले उपयोग कर सकते हैं ।ViewViewGroup

जैसा कि setDuplicateParentStateEnabledविधि में प्रलेखित है , अगर बच्चे के दृश्य में अतिरिक्त राज्य हैं (जैसे चेकबॉक्स के लिए चेक किए गए राज्य), तो ये माता-पिता से प्रभावित नहीं होंगे।

Xml एनालॉग है android:duplicateParentState="true"


1

पुनरावर्ती क्रिया नीचे का प्रयोग करें अपने बच्चे को देखा गया बनाने के लिए दिखाई दे या चला गया है । पहला तर्क आपके माता-पिता का दृष्टिकोण है और दूसरा तर्क यह तय करता है कि आप माता-पिता के दृश्य को देखना चाहते हैं या चले गए हैं। true = दिखाई झूठा = गया

private void layoutElemanlarininGorunumunuDegistir(View view, boolean gorunur_mu_olsun) {
    ViewGroup view_group;
    try {
        view_group = (ViewGroup) view;
        Sabitler.konsolaYazdir(TAG, "View ViewGroup imiş!" + view.getId());
    } catch (ClassCastException e) {
        Sabitler.konsolaYazdir(TAG, "View ViewGroup değilmiş!" + view.getId());
        return;
    }

    int view_eleman_sayisi = view_group.getChildCount();
    for (int i = 0; i < view_eleman_sayisi; i++) {
        View view_group_eleman = view_group.getChildAt(i);
        if (gorunur_mu_olsun) {
            view_group_eleman.setVisibility(View.VISIBLE);
        } else {
            view_group_eleman.setVisibility(View.GONE);
        }
        layoutElemanlarininGorunumunuDegistir(view_group_eleman, gorunur_mu_olsun);
    }
}

1

यह एक बहुत देरी से जवाब है। लेकिन यह किसी की मदद कर सकता है। ऊपर वर्णित कई उत्तर अच्छे लगते हैं। लेकिन अगर आपके लेआउट। Xml में नेस्टग्रुप्स नेस्टेड हैं। फिर उपरोक्त उत्तर पूर्ण परिणाम प्रदान नहीं कर सकते हैं। इसलिए मैंने एक स्निपेट के रूप में अपनी राय पोस्ट की है। नीचे दिए गए कोड के साथ सभी दृश्य (नेस्टेड व्यूग्रुप्स सहित) अक्षम कर सकते हैं।

नोट: नेस्टेड व्यूग्रुप्स से बचने की कोशिश करें क्योंकि वे अनुशंसित नहीं हैं।

 private void setEnableView(boolean b) {
    LinearLayout layout = (LinearLayout)findViewById(R.id.parent_container);
    ArrayList<ViewGroup> arrVg = new ArrayList<>();
    for (int i = 0; i < layout.getChildCount(); i++) {
        View child = layout.getChildAt(i);
        if (child instanceof ViewGroup) {
            ViewGroup vg = (ViewGroup) child;
            arrVg.add(vg);
        }
        child.setEnabled(b);
    }

    for (int j=0;j< arrVg.size();j++){
        ViewGroup vg = arrVg.get(j);
        for (int k = 0; k < vg.getChildCount(); k++) {
         vg.getChildAt(k).setEnabled(b);
        }
    }
}

0

सेट

android:descendantFocusability="blocksDescendants"

yor ViewGroup दृश्य के लिए। सभी वंशज ध्यान नहीं देंगे।


वह फोकस के बारे में नहीं पूछ रहा है।
चुपके रब्बी

0

यदि आप किसी सेट को अक्षम करना चाहते हैं, या किसी विशेष प्रकार का दृश्य कहना चाहते हैं। तो मान लें कि आप किसी विशेष पाठ या किसी पाठ के साथ निश्चित संख्या में बटनों को अक्षम करना चाहते हैं, तो आप सरणी तत्वों के माध्यम से उस प्रकार के लूप का उपयोग कर सकते हैं। सेट (अक्षम) संपत्ति का उपयोग करके बटन अक्षम करते समय आप इसे इस तरह से फ़ंक्शन कॉल पर कर सकते हैं:

public void disable(){
        for(int i=0;i<9;i++){
                if(bt[i].getText().equals("")){//Button Text condition
                    bt[i].setEnabled(false);
            }
        }
}

0

मैंने एडिट टेक्स्ट और रेडियोबटन घटकों को ठीक से अक्षम करने के लिए tütü प्रतिक्रिया में सुधार किया । इसके अलावा, मैं एक ऐसा तरीका साझा कर रहा हूं जो मुझे दृश्य दृश्यता को बदलने और अक्षम विचारों में पारदर्शिता जोड़ने के लिए मिला है।

private static void disableEnableControls(ViewGroup view, boolean enable){
    for (int i = 0; i < view.getChildCount(); i++) {
        View child = view.getChildAt(i);
        child.setEnabled(enable);
        if (child instanceof ViewGroup){
            disableEnableControls((ViewGroup)child, enable);
        }
        else if (child instanceof EditText) {
            EditText editText = (EditText) child;
            editText.setEnabled(enable);
            editText.setFocusable(enable);
            editText.setFocusableInTouchMode(enable);
        }
        else if (child instanceof RadioButton) {
            RadioButton radioButton = (RadioButton) child;
            radioButton.setEnabled(enable);
            radioButton.setFocusable(enable);
            radioButton.setFocusableInTouchMode(enable);
        }
    }
}

public static void setLayoutEnabled(ViewGroup view, boolean enable) {
    disableEnableControls(view, enable);
    view.setEnabled(enable);
    view.setAlpha(enable? 1f: 0.3f);
}

public static void setLayoutEnabled(ViewGroup view, boolean enable, boolean visibility) {
    disableEnableControls(view, enable);
    view.setEnabled(enable);
    view.setAlpha(enable? 1f: 0.3f);
    view.setVisibility(visibility? View.VISIBLE: View.GONE);
}

0

मेरे दो सेंट बिना पुनरावृत्ति के कार्य करते हैं

    package io.chord.ui.utils

import android.view.View
import android.view.ViewGroup
import androidx.core.view.forEach

class ViewUtils
{
    companion object
    {
        fun setViewState(view: View, state: Boolean)
        {
            var depth = 0
            val views: MutableMap<Int, MutableList<View>> = mutableMapOf()
            views[depth] = mutableListOf(view)

            while(true)
            {
                val currentViews = views[depth]
                val nextViews = mutableListOf<View>()

                currentViews!!.forEach { view ->
                    if(view is ViewGroup)
                    {
                        view.forEach { children ->
                            nextViews.add(children)
                        }
                    }
                }

                if(nextViews.size == 0)
                {
                    break
                }

                depth++

                views[depth] = nextViews
            }

            views.flatMap {
                it.value
            }.forEach {
                it.isEnabled = state
            }
        }
    }
}

0

सबसे आसान तरीका है अपने xml में एक दृश्य बनाना, ऊंचाई और चौड़ाई के लिए match_parent के साथ, सुनिश्चित करें कि दृश्य हर दूसरे दृश्य के ऊपर है, फिर जब आप क्लिक को रोकना चाहते हैं, तो दृश्यमान को पैरामीटर के रूप में null के लिए उस दृश्य पर एक onClickListener जोड़ें ।

उदाहरण:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
        android:layout_height="fill_parent">
     <Button 
        android:id="@+id/backbutton"
        android:text="Back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <LinearLayout
        android:id="@+id/my_layout"
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/my_text_view"
            android:text="First Name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <EditText
            android:id="@+id/my_edit_view"
            android:width="100px"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" /> 
        
        <View
            android:id="@+id/disable_layout_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone"/>
    </LinearLayout>

</LinearLayout>

फिर अपने कोड में:

val disableLayoutView = rootView.find<View>(R.id.disable_layout_view)
disableLayoutView.visibility = View.VISIBLE
disableLayoutView.setOnClickListener(null)

0

मुझे रूट दृश्य पर नियंत्रण रखना पसंद है इसलिए मैंने includeSelfध्वज को जोड़ाdeepForEach

fun ViewGroup.deepForEach(includeSelf: Boolean = true, function: View.() -> Unit) {
    if (includeSelf) function()
    forEach {
        it.apply {
            function()
            (this as? ViewGroup)?.apply { deepForEach(includeSelf, function) }
        }
    }
}

0
You can have whichever children that you want to have the same state as the parents include android:duplicateParentState="true".  Then if you disable the parent, whatever children you have that set on will follow suit.  

यह आपको मूल दृश्य से एक साथ सभी राज्यों को गतिशील रूप से नियंत्रित करने की अनुमति देगा।

<LinearLayout
    android:id="@+id/some_parent_something"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
     <Button 
        android:id="@+id/backbutton"
        android:text="Back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:duplicateParentState="true"/>
    <LinearLayout
        android:id="@+id/my_layout"
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        android:duplicateParentState="true">
        <TextView
            android:id="@+id/my_text_view"
            android:text="First Name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" 
            android:duplicateParentState="true" />
        <EditText
            android:id="@+id/my_edit_view"
            android:width="100px"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" 
            android:duplicateParentState="true" /> 
        <View .../>
        <View .../>
        ...
           <View .../>
    </LinearLayout>

</LinearLayout>

-1

किसी दृश्य को अक्षम करने के लिए, आपको विधि सेट करना होगा जो तर्क के लिए गलत के साथ अक्षम हो। उदाहरण के लिए:

Button btn = ...
btn.setEnabled(false);

-1

मेरे लिए RelativeLayout या xml फ़ाइल के अंत में चौड़ाई और ऊँचाई के साथ किसी भी अन्य लेआउट के साथ मिलान करने के लिए सेट किया गया है जिसमें विशेषता के साथ मिलान योग्य और क्लिक करने योग्य सेट सही है।

 <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true"
            android:focusable="true">

        <ProgressBar
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true" />

    </RelativeLayout>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.