style studio setenabled enabled disabled java android string button disabled-control

java - studio - ¿Tienes un onClick desactivado?



disabled button android studio (10)

Cuando está deshabilitado, setEnabled(false) , estos escuchas no funcionarán.

Intente de esta manera: no lo deshabilite, use setOnCheckedChangeListener y setOnCheckedChangeListener con su entrada completada allí:

utilizar setOnCheckedChangeListener

switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (!isEntryFilled) { buttonView.setChecked(false); // your alert dialog } else { } } });

esto lo volverá a marcar y desactivará su alerta, hasta que se cumpla isEntryFilled .

EDITAR

O en lugar de setEnabled(false) , use setClickable(false) o android:clickable="false" ya que los documentos dicen que setClickable() está vinculado a eventos de clic .

y en lugar de OnClickListener , intente OnTouchListener . Registrará su toque instantáneo (e ignorará su toque instantáneo), ya que un clic consiste en abajo + arriba.

switch.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (!isEntryFilled) { buttonView.setChecked(false); // your alert dialog } return false; } });

luego, en otro lugar, donde verifique que haya isEntryFilled , reactive su conmutador con switch.setClickable(true)

Quiero poder responder a un evento de clic en un interruptor deshabilitado, ¿es posible?

Tengo un interruptor que no está habilitado hasta que el usuario llena alguna información, por lo que se ve así:

Quiero pedirle al usuario que complete la información si hace clic en el interruptor deshabilitado con un cuadro de diálogo, así:

mySwitch.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (!userInfo.isFilled){ new AlertDialog.Builder(MainActivity.this) .setTitle("Fill out info first!") .setMessage("You must first fill out info before turning on this featurel") .setNeutralButton("Okay", null) .show(); } } });

Sin embargo, el onClick() no se activa cuando hago clic en el interruptor deshabilitado, entonces, ¿cómo obtengo cuando el usuario hace clic en él?


Deje que la View intercepte ClickEvent s o TouchEvent s, cuando se detecte, compruebe si la View receptora está desactivada y haga lo que tenga que hacer.

Editar

" no funciona cuando está deshabilitado? "

pruebe estos códigos, uso LinearLayout para facilitar la alineación. Pero en general debería darte un ejemplo.

este es un ejemplo completo

XML

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="70dp" android:background="#273746"> <FrameLayout android:layout_width="match_parent" android:id="@+id/ass" android:background="@drawable/abc_popup_background_mtrl_mult" android:layout_height="match_parent"> </FrameLayout>

MainActivity onCreate

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_entry_screen); FrameLayout fl = (FrameLayout)findViewById(R.id.ass); Test t = new Test(this); FrameLayout.LayoutParams lp = (LayoutParams) fl.getLayoutParams(); lp.height = LayoutParams.MATCH_PARENT; lp.width = LayoutParams.MATCH_PARENT; t.setOrientation(LinearLayout.VERTICAL); t.setLayoutParams(lp); fl.addView(t); t.setBackgroundColor(Color.YELLOW); Button b = new Button(this); b.setText("patricia"); t.addView(b); b = new Button(this); b.setText("monica"); t.addView(b); b = new Button(this); b.setText("rebecca"); t.addView(b); }

Test.java

public class Test extends LinearLayout { public Test(Context context) { super(context); } @Override public boolean onInterceptTouchEvent(MotionEvent event) { StringBuilder sb = new StringBuilder(); sb.append("intercept /n/r"); int x = (int)event.getX(), y= (int)event.getY(); for(int i =0; i< getChildCount(); i++){ int[] pos = new int[]{getChildAt(i).getLeft(),getChildAt(i).getTop(), getChildAt(i).getMeasuredWidth(), getChildAt(i).getMeasuredHeight()}; sb.append(getChildAt(i).getLeft()+", "); sb.append(getChildAt(i).getTop()+", "); sb.append(getChildAt(i).getMeasuredWidth()+", "); sb.append(getChildAt(i).getMeasuredHeight()); sb.append("/n/r"); sb.append(isInBounds(pos, x, y)); sb.append("/n/r"); } sb.append("x is "); sb.append(x); sb.append("y is "); sb.append(y); Toast.makeText(getContext(),sb.toString() , Toast.LENGTH_LONG).show(); return super.onInterceptTouchEvent(event); } private boolean isInBounds(int[] dimen, int x, int y){ return ((x >= dimen[0] && x < (dimen[0] + dimen[2])) && (y >= dimen[1] && y < (dimen[1] + dimen[3]))); } }

Ahora, en el que haga clic se comprobará que es verdadero, ese es el niño, ahora, cuando se verifica que es verdadero, puede hacer algo como esto.

View v = getchildAt(pos); //its the one that is tapped or clicked if(!v.isEnabled()){ //this is the guy you want now, do what you want to do

para el evento de clic, no intento esto, pero simplemente puede hacer View.performClick() o poner su diálogo en la clase ViewGroup y llamarlo

en realidad, podría usar View..getClipBounds() para salvarse de la matriz int


Desde el código fuente de View.java ,

public boolean dispatchTouchEvent(MotionEvent event) { // If the event should be handled by accessibility focus first. if (event.isTargetAccessibilityFocus()) { // We don''t have focus or no virtual descendant has it, do not handle the event. if (!isAccessibilityFocusedViewOrHost()) { return false; } // We have focus and got the event, then use normal event dispatch. event.setTargetAccessibilityFocus(false); } boolean result = false; if (mInputEventConsistencyVerifier != null) { mInputEventConsistencyVerifier.onTouchEvent(event, 0); } final int actionMasked = event.getActionMasked(); if (actionMasked == MotionEvent.ACTION_DOWN) { // Defensive cleanup for new gesture stopNestedScroll(); } if (onFilterTouchEventForSecurity(event)) { //noinspection SimplifiableIfStatement ListenerInfo li = mListenerInfo; if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED && li.mOnTouchListener.onTouch(this, event)) { result = true; } if (!result && onTouchEvent(event)) { result = true; } } if (!result && mInputEventConsistencyVerifier != null) { mInputEventConsistencyVerifier.onUnhandledEvent(event, 0); } // Clean up after nested scrolls if this is the end of a gesture; // also cancel it if we tried an ACTION_DOWN but we didn''t want the rest // of the gesture. if (actionMasked == MotionEvent.ACTION_UP || actionMasked == MotionEvent.ACTION_CANCEL || (actionMasked == MotionEvent.ACTION_DOWN && !result)) { stopNestedScroll(); } return result; }

el indicador habilitado garantiza que los eventos UnhandledEvents se consuman, sin embargo, no se transmiten a los oyentes, por lo que se omiten todos los códigos posibles. Por lo tanto, no es posible escuchar eventos en una vista deshabilitada.

Dicho esto, tus opciones son,

  1. Cambie el estilo para imitar el de una vista deshabilitada como se menciona here , y luego agregue la funcionalidad requerida.
  2. Agregue una vista invisible de superposición para realizar la funcionalidad requerida que puede configurar como Desactivada una vez que la vista debe estar habilitada.
  3. Use algo aparte de habilitado, (podría establecer setClickable(false) y consumir eventos táctiles)

Establezca los interruptores deshabilitados en el escucha de clic para cambiar los oyentes de los otros interruptores. Por ejemplo:

Switch s = (Switch) findViewById(R.id.SwitchID); if (s != null) { s.setOnCheckedChangeListener(this); } /* ... */ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { Toast.makeText(this, "The Switch is " + (isChecked ? "on" : "off"), Toast.LENGTH_SHORT).show(); if(isChecked) { //do stuff when Switch is ON //this is where you set your normal state OnClickListner } else { mySwitch.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (!userInfo.isFilled){ new AlertDialog.Builder(MainActivity.this) .setTitle("Fill out info first!") .setMessage("You must first fill out info before turning on this featurel") .setNeutralButton("Okay", null) .show(); } } }); } }


Intente configurar setFocusable(false) y setEnabled(true) en su conmutador. De esa manera, los eventos de clics se activarán mientras el interruptor aún esté "deshabilitado". Tomado de esta respuesta .


Podría colocar una View transparente sobre el Switch y cambiar su estado habilitado frente al Interruptor, y mostrar el mensaje cuando se haga clic en esta View superpuesta.


Puede configurar onTouchListener y reaccionar a la referencia boolean (por ejemplo, isToggleEnable ) con respecto a las acciones anteriores del usuario:

mySwitch.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if(!isToggleEnable){ //Taost here } //If isToggleEnable = false on return OnClickListener won''t be called return isToggleEnable; } });


Puede hacer esto de una manera diferente. Dar un diseño de raíz para alternar el botón con la misma anchura y altura que el botón de alternar

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <!--Root layout to toggle button with same height and width of toggle button--> <LinearLayout android:layout_width="wrap_content" android:id="@+id/linear" android:layout_height="wrap_content"> <ToggleButton style="?android:attr/buttonStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/button" /> </LinearLayout> </RelativeLayout>

Cuando deshabilita el botón, haga que el botón no se pueda enfocar y hacer clic. Luego, el sistema operativo entregará la funcionalidad táctil a rootlayout. En la lista de clics del diseño raíz, podemos escribir la lógica de clic cuando el botón no está habilitado.

public class MainActivity extends AppCompatActivity { ToggleButton button; LinearLayout linearLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button= (ToggleButton) findViewById(R.id.button); linearLayout= (LinearLayout) findViewById(R.id.linear); //disabling button button.setEnabled(false); button.setClickable(false); button.setFocusableInTouchMode(false); button.setFocusable(false); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //write the logic here which will execute when button is enabled } }); linearLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //write the logic here which will execute when button is disabled } }); } }

Cuando habilite el botón, haga que el botón se pueda hacer clic y se pueda usar.

//enabling button button.setEnabled(true); button.setClickable(true); button.setFocusableInTouchMode(true); button.setFocusable(true);


Supongo que ha deshabilitado el conmutador utilizando switch.setEnabled (false). Si es así, el evento onclick no se activará. Si aún desea manejar una acción de clic cuando el interruptor está deshabilitado, puede usar .setOnTouchListener () ...

Sin embargo, lo mejor es usar .setOnCheckedChangeListener () y mantener el interruptor habilitado. Básicamente, cuando se llama a onCheckChanged (), puede abrir el cuadro de diálogo si el valor del interruptor está activado y cuando el usuario hace clic en Aceptar, el interruptor vuelve a estar predeterminado.

mSwitched.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { if (checked && !userInfo.isFilled){ new AlertDialog.Builder(Activity.this) .setTitle("Fill out info first!") .setMessage("You must first fill out info before turning on this featurel") .setNeutralButton("Okay", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { mSwitched.setChecked(false); } }) .show(); } } });


mySwitch.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (isClick()){ //Your Valid Code }else{ //Make our switch to false new AlertDialog.Builder(MainActivity.this) .setTitle("Fill out info first!") .setMessage("You must first fill out info before turning on this featurel") .setNeutralButton("Okay", null) .show(); } } }); public Boolean isClick(){ //check condition that user fill details or not //if yes then return true // else return false }