Zum Beispiel habe ich:
<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>
Gibt es eine Möglichkeit, alle Elemente in LinearLayout zu deaktivieren (setEnable (false)) my_layout
?
android
android-layout
Scit
quelle
quelle
Dieser ist für ViewGroups rekursiv
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); } } }
quelle
Tutus Antwort ist auf dem richtigen Weg, aber seine Rekursion ist etwas umständlich. Ich finde das sauberer:
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); } } }
quelle
Was für mich wirklich funktioniert:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
und um es rückgängig zu machen:
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
quelle
Wenn Sie Ansichten in einer bestimmten ViewGroup deaktivieren möchten, können Sie die interessante, möglicherweise etwas undurchsichtige verwenden
duplicateParentState
. Ein Ansichtsstatus ist eine Reihe von booleschen Attributen wie gedrückt, aktiviert, aktiviert und andere. Verwenden Sie dies einfach für jedes Kind, das Sie mit der übergeordneten ViewGroup synchronisieren möchten:android:duplicateParentState="true"
Beachten Sie, dass der gesamte Status und nicht nur der aktivierte Status dupliziert wird. Dies kann sein, was Sie wollen! Dieser Ansatz ist natürlich am besten geeignet, wenn Sie Layout-XML laden.
quelle
Lassen Sie uns den Code von tütü ändern
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); } } }
Ich denke, es macht keinen Sinn, nur die Ansichtsgruppe zu deaktivieren. Wenn Sie es tun möchten, gibt es einen anderen Weg, den ich für genau den gleichen Zweck verwendet habe. Erstellen Sie eine Ansicht als Geschwister Ihrer Gruppenansicht:
<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" />
und zur Laufzeit sichtbar machen. Hinweis: Das übergeordnete Layout Ihrer Gruppenansicht sollte entweder ein relatives oder ein Rahmenlayout sein. Hoffe das wird helfen.
quelle
Wenn ein verzweifelter Entwickler hier nach unten scrollt, habe ich eine andere Möglichkeit, dies zu tun. Das deaktiviert auch das Scrollen, soweit ich damit experimentiert habe. Die Idee ist, ein View-Element wie dieses in einem RelativeLayout unter all Ihren UI-Elementen zu verwenden.
<View android:id="@+id/shade" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/primaryShadow" android:visibility="gone"/>
Es ist also so eingestellt, dass es vor einer bestimmten Bedingung "weg" ist. Und dann setzen Sie die Sichtbarkeit auf SICHTBAR, wenn Sie Ihre Benutzeroberfläche deaktivieren möchten. Außerdem müssen Sie
OnClickListener
für diese Ansicht implementieren . DadurchonClickListener
wird das Klickereignis abgefangen und nicht an die zugrunde liegenden Elemente übergeben.quelle
Ich persönlich benutze so etwas (vertikale Baumdurchquerung mit Rekursion)
fun ViewGroup.deepForEach(function: View.() -> Unit) { this.forEach { child -> child.function() if (child is ViewGroup) { child.deepForEach(function) } } }
Verwendung :
viewGroup.deepForEach { isEnabled = false }
quelle
forEach
androidx.core.view
Methode: developer.android.com/reference/kotlin/androidx/core/view/…Einzelheiten
Lösung
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) } }
Verwendung
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 }
quelle
Obwohl dies nicht ganz mit dem Deaktivieren von Ansichten in einem Layout identisch ist, sollten Sie erwähnen, dass Sie verhindern können, dass alle untergeordneten Elemente Berührungen erhalten (ohne die Layouthierarchie wiederholen zu müssen), indem Sie die ViewGroup # onInterceptTouchEvent (MotionEvent) -Methode überschreiben :
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); } }
Dann können Sie verhindern, dass Kinder Berührungsereignisse erhalten:
InterceptTouchEventFrameLayout layout = (InterceptTouchEventFrameLayout) findViewById(R.id.layout); layout.setInterceptTouchEvents(true);
Wenn Sie einen Klick-Listener aktiviert haben
layout
, wird dieser weiterhin ausgelöst.quelle
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); } }
und rufen Sie die Methode wie folgt auf:
RelativeLayout rl_root = (RelativeLayout) findViewById(R.id.rl_root); disableLL(rl_root);
quelle
In Kotlin können Sie verwenden,
isDuplicateParentStateEnabled = true
bevor dasView
zum hinzugefügt wirdViewGroup
.Wie in der
setDuplicateParentStateEnabled
Methode dokumentiert , werden diese nicht vom übergeordneten Status beeinflusst, wenn die untergeordnete Ansicht zusätzliche Status aufweist (z. B. den aktivierten Status für ein Kontrollkästchen).Das XML-Analogon ist
android:duplicateParentState="true"
.quelle
Verwenden Sie die folgende rekursive Funktion, um die Ansichten Ihres Kindes sichtbar oder verschwunden zu machen . Das erste Argument ist Ihre übergeordnete Ansicht und das zweite Argument entscheidet, ob Kinder der übergeordneten Ansicht sichtbar oder verschwunden sein sollen. wahr = sichtbar falsch = weg
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); } }
quelle
Dies ist eine ziemlich verspätete Antwort. Aber es könnte jemandem helfen. Viele der oben genannten Antworten scheinen gut zu sein. Aber wenn Ihre layout.xml verschachtelte Ansichtsgruppen hat. Dann liefern die obigen Antworten möglicherweise nicht das vollständige Ergebnis. Daher habe ich meine Meinung als Ausschnitt gepostet. Mit dem folgenden Code können alle Ansichten deaktiviert werden (einschließlich verschachtelter Ansichtsgruppen).
HINWEIS: Vermeiden Sie verschachtelte ViewGroups, da diese nicht empfohlen werden.
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); } } }
quelle
einstellen
android:descendantFocusability="blocksDescendants"
für Ihre ViewGroup-Ansicht. Alle Nachkommen werden nicht fokussiert.
quelle
Wenn Sie einen Satz von oder eine bestimmte Art von Ansicht deaktivieren möchten. Nehmen wir an, Sie möchten eine feste Anzahl von Schaltflächen mit einem bestimmten Text oder keinem Text deaktivieren, dann können Sie ein Array dieses Typs verwenden und die Array-Elemente durchlaufen während Sie die Schaltflächen mit der Eigenschaft setEnabled (false) deaktivieren Sie können dies bei einem Funktionsaufruf wie folgt tun:
public void disable(){ for(int i=0;i<9;i++){ if(bt[i].getText().equals("")){//Button Text condition bt[i].setEnabled(false); } } }
quelle
Ich habe die Tütü- Reaktion verbessert , um die EditText- und RadioButton-Komponenten ordnungsgemäß zu deaktivieren. Außerdem teile ich eine Möglichkeit, die Sichtbarkeit der Ansicht zu ändern und Transparenz in den deaktivierten Ansichten hinzuzufügen.
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); }
quelle
Meine zwei Cent funktionieren ohne Rekursion
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 } } } }
quelle
Am einfachsten ist es, eine <Ansicht in Ihrer XML-Datei mit match_parent für Höhe und Breite zu erstellen. Stellen Sie sicher, dass sich die Ansicht über allen anderen Ansichten befindet. Wenn Sie Klicks verhindern möchten, machen Sie sie sichtbar und fügen Sie dieser Ansicht einen onClickListener mit null als Parameter hinzu .
Beispiel:
<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>
Dann in Ihrem Code:
val disableLayoutView = rootView.find<View>(R.id.disable_layout_view) disableLayoutView.visibility = View.VISIBLE disableLayoutView.setOnClickListener(null)
quelle
Ich möchte eine Kontrolle über die Stammansicht haben, also habe ich das
includeSelf
Flag hinzugefügtdeepForEach
fun ViewGroup.deepForEach(includeSelf: Boolean = true, function: View.() -> Unit) { if (includeSelf) function() forEach { it.apply { function() (this as? ViewGroup)?.apply { deepForEach(includeSelf, function) } } } }
quelle
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.
Auf diese Weise können Sie alle Status gleichzeitig dynamisch in der übergeordneten Ansicht steuern.
<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>
quelle
Für mich ist RelativeLayout oder ein anderes Layout am Ende der XML-Datei mit Breite und Höhe auf match_parent gesetzt, wobei das Attribut fokussierbar und anklickbar auf true gesetzt ist.
<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>
quelle
Um eine Ansicht zu deaktivieren, müssen Sie die Methode setEnabled mit false als Argument aufrufen. Ex:
Button btn = ... btn.setEnabled(false);
quelle