Debido a que show solo se necesita dentro de la clase anidada ButtonHandler, quiero hacer lo siguiente

public class MainActivity extends AppCompatActivity
{
    private class ButtonHandler implements OnClickListener
    {
        @Override
        public void onClick(View view)
        {
           // removed for simplicity
        }
        private void show(String s)
        {
            //Toast.makeText(this, s, LENGTH_LONG).show();
        }
    }   

}

En lugar de lo siguiente.

public class MainActivity extends AppCompatActivity
{
    private class ButtonHandler implements OnClickListener
    {
        @Override
        public void onClick(View view)
        {
           // removed for simplicity
        }
    }

    private void show(String s)
    {
        Toast.makeText(this, s, LENGTH_LONG).show();
    }

}

Pregunta

¿Cómo obtener el contexto this para Toast.makeText en el primer enfoque? Estoy familiarizado con C # pero no con Java y Android.

1
Money Oriented Programmer 23 feb. 2018 a las 20:09

4 respuestas

La mejor respuesta

Si ButtonHandler es una clase interna no estática (que parece ser), puede usar MainActivity.this en lugar de this para tener una referencia a un Context :

Toast.makeText(MainActivity.this, s, LENGTH_LONG).show();

Si ButtonHandler es estático (entonces MainActivity.this no funciona), tendrá que pasar un objeto de contexto al método de alguna manera. Suponiendo que está llamando a show() desde el método onClick(), puede aprovechar View.getContext() y escribir esto:

show(v.getContext(), s);
private void show(Context c, String s)
{
    Toast.makeText(c, s, LENGTH_LONG).show();
}
3
Ben P. 23 feb. 2018 a las 17:13

Debe especificar qué clase cuando se trata de clases anidadas.

El uso de this se refiere a ButtonHandler, que no funcionará ya que no tiene el contexto en sí. En su lugar, use MainActivity.this (this@MainActivity en Kotlin) para referirse a la clase externa:

Toast.makeText(MainActivity.this, s, LENGTH_LONG).show();
1
Zoe 23 feb. 2018 a las 17:13

También puedes hacer una variable privada

private Activity activity;

Y en tu método onCreate:

this.activity = this;

Porque en cada clase anidada tienes acceso a todas las variables externas, pero simplemente "esto" no funciona. Entonces su ejemplo sería algo así:

public class MainActivity extends AppCompatActivity{

    private Activity activity;

    public void onCreate(...){
        this.activity = this;
        ...
    }

    private class ButtonHandler implements OnClickListener
    {
        @Override
        public void onClick(View view)
        {
           // removed for simplicity
        }
        private void show(String s)
        {
            //Toast.makeText(activity, s, LENGTH_LONG).show();
        }
    }   

}

Por favor no me mates por ningún buen estilo de código

1
Alexander Dauer 26 sep. 2018 a las 14:06

Se puede acceder a las instancias de clases externas a través de MainActivity.this. Además, se puede acceder a los campos a través de MainActivity.this.field.

1
Marko Pacak 23 feb. 2018 a las 17:13