¿Cómo crear nuestra propia interfaz de escucha en Android?

134

¿Podría alguien ayudarme a crear una interfaz de escucha definida por el usuario con algunos fragmentos de código?

Rajapandian
fuente

Respuestas:

198

Crea un nuevo archivo:

MyListener.java:

public interface MyListener {
    // you can define any parameter as per your requirement
    public void callback(View view, String result);
}

En su actividad, implemente la interfaz:

MyActivity.java:

public class MyActivity extends Activity implements MyListener {
   @override        
   public void onCreate(){
        MyButton m = new MyButton(this);
   }

    // method is invoked when MyButton is clicked
    @override
    public void callback(View view, String result) {   
        // do your stuff here
    }
}

En su clase personalizada, invoque la interfaz cuando sea necesario:

MyButton.java:

public class MyButton {
    MyListener ml;

    // constructor
    MyButton(MyListener ml) {
        //Setting the listener
        this.ml = ml;
    }

    public void MyLogicToIntimateOthers() {
        //Invoke the interface
        ml.callback(this, "success");
    }
}
Rakesh Soni
fuente
2
Cómo pasar el objeto de escucha si nuestro botón ya está en el diseño, en lugar de no usar MyButton m = new MyButton (this); forma de crear el objeto de Button.
Qadir Hussain
2
Puede agregar un nuevo método en la clase MyButton: void setMyListener (MyListner m1) {this.ml = m1;} y luego usar este método en cualquier momento para configurar su objeto de escucha.
Rakesh Soni
1
¿Dónde se utiliza MyLogicToIntimateOthere () este método?
abh22ishek
1
Viniendo de un fondo de iOS, si hiciera esto en iOS causaría una pérdida de memoria porque el oyente de MyButton es una fuerte referencia al oyente, y el oyente tiene una fuerte referencia al MyButton ... es un recolector de basura java lo suficientemente inteligente como para ¿sabe que tanto el oyente como MyButton deben limpiarse si no quedan referencias al oyente que no sean de MyButton? Podría usar un WeakReference<>en este caso, pero luego no puede convertir al oyente en una clase anónima o cualquier cosa donde el oyente no tenga otras referencias ... por lo que sería preferible no usarlo
Fonix
donde es MyLogicToIntimateOthers () utilizado
Ab
109

por favor lea el patrón de observador

interfaz de oyente

public interface OnEventListener {
    void onEvent(EventResult er);
    // or void onEvent(); as per your need
}

entonces en tu clase di Eventclase

public class Event {
    private OnEventListener mOnEventListener;

    public void setOnEventListener(OnEventListener listener) {
        mOnEventListener = listener;
    }

    public void doEvent() {
        /*
         * code code code
         */

         // and in the end

         if (mOnEventListener != null)
             mOnEventListener.onEvent(eventResult); // event result object :)
    }
}

en tu clase de conductor MyTestDriver

public class MyTestDriver {
    public static void main(String[] args) {
        Event e = new Event();
        e.setOnEventListener(new OnEventListener() {
             public void onEvent(EventResult er) {
                 // do your work. 
             }
        });
        e.doEvent();
    }
}
Rupesh
fuente
11

He creado un Asistente de AsyncTask genérico que obtiene el resultado de la clase separada AsycTask y se lo doy a CallingActivity usando la devolución de llamada de interfaz.

new GenericAsyncTask(context,new AsyncTaskCompleteListener()
        {
             public void onTaskComplete(String response) 
             {
                 // do your work. 
             }
        }).execute();

Interfaz

interface AsyncTaskCompleteListener<T> {
   public void onTaskComplete(T result);
}

GenericAsyncTask

class GenericAsyncTask extends AsyncTask<String, Void, String> 
{
    private AsyncTaskCompleteListener<String> callback;

    public A(Context context, AsyncTaskCompleteListener<String> cb) {
        this.context = context;
        this.callback = cb;
    }

    protected void onPostExecute(String result) {
       finalResult = result;
       callback.onTaskComplete(result);
   }  
}

Echa un vistazo a esto , esta pregunta para más detalles.

Xar-e-ahmer Khan
fuente
8

Hay 4 pasos:

1.crear clase de interfaz (oyente)

2.utilice la interfaz en la vista 1 (defina la variable)

3.implementa la interfaz para ver 2 (vista 1 usada en la vista 2)

Interfaz 4.pass en la vista 1 para ver 2

Ejemplo:

Paso 1: necesita crear una interfaz y definir la función

public interface onAddTextViewCustomListener {
    void onAddText(String text);
}

Paso 2: use esta interfaz a la vista

public class CTextView extends TextView {


    onAddTextViewCustomListener onAddTextViewCustomListener; //listener custom

    public CTextView(Context context, onAddTextViewCustomListener onAddTextViewCustomListener) {
        super(context);
        this.onAddTextViewCustomListener = onAddTextViewCustomListener;
        init(context, null);
    }

    public CTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public CTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs);
    }

    public void init(Context context, @Nullable AttributeSet attrs) {

        if (isInEditMode())
            return;

        //call listener
        onAddTextViewCustomListener.onAddText("this TextView added");
    }
}

Paso 3,4: implementos a la actividad

public class MainActivity extends AppCompatActivity implements onAddTextViewCustomListener {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //get main view from layout
        RelativeLayout mainView = (RelativeLayout)findViewById(R.id.mainView);

        //create new CTextView and set listener
        CTextView cTextView = new CTextView(getApplicationContext(), this);

        //add cTextView to mainView
        mainView.addView(cTextView);
    }

    @Override
    public void onAddText(String text) {
        Log.i("Message ", text);
    }
}
Rasoul Miri
fuente
7

Crear interfaz de oyente.

public interface YourCustomListener
{
    public void onCustomClick(View view);
            // pass view as argument or whatever you want.
}

Y cree el método setOnCustomClick en otra actividad (o fragmento), donde desee aplicar su escucha personalizada ......

  public void setCustomClickListener(YourCustomListener yourCustomListener)
{
    this.yourCustomListener= yourCustomListener;
}

Llame a este método desde su primera actividad y pase la interfaz de escucha ...

Kapil Vij
fuente
4

En el año de 2018, no hay necesidad de interfaces de oyentes. Tienes Android LiveData para encargarse de devolver el resultado deseado a los componentes de la interfaz de usuario.

Si tomo la respuesta de Rupesh y la ajusto para usar LiveData, me gustaría:

public class Event {

    public LiveData<EventResult> doEvent() {
         /*
          * code code code
          */

         // and in the end

         LiveData<EventResult> result = new MutableLiveData<>();
         result.setValue(eventResult);
         return result;
    }
}

y ahora en su clase de controlador MyTestDriver:

public class MyTestDriver {
    public static void main(String[] args) {
        Event e = new Event();
        e.doEvent().observe(this, new  Observer<EventResult>() {
            @Override
            public void onChanged(final EventResult er) {
                // do your work.
            }
        });
    }
}

Para obtener más información junto con ejemplos de código, puede leer mi publicación al respecto, así como los documentos oficiales:

Cuándo y por qué usar LiveData

Documentos oficiales

TheCodeFather
fuente
0

En Android, puede crear una interfaz como Listener, y su Actividad la implementa, pero no creo que sea una buena idea. Si tenemos muchos componentes para escuchar los cambios de su estado, podemos crear una BaseListener implementa la interfaz de escucha, y usar código de tipo para manejarlos. Podemos vincular el método cuando creamos un archivo XML, por ejemplo:

<Button  
        android:id="@+id/button4"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="Button4"  
        android:onClick="Btn4OnClick" />

y el código fuente:

 public void Btn4OnClick(View view) {  
        String strTmp = "点击Button04";  
        tv.setText(strTmp);  
    }  

pero no creo que sea una buena idea ...

usuario3055973
fuente
0

Lo hice de la siguiente manera para enviar mi clase de modelo de la Segunda Actividad a la Primera Actividad. Utilicé LiveData para lograr esto, con la ayuda de las respuestas de Rupesh y TheCodeFather.

Segunda actividad

public static MutableLiveData<AudioListModel> getLiveSong() {
        MutableLiveData<AudioListModel> result = new MutableLiveData<>();
        result.setValue(liveSong);
        return result;
    }

"liveSong" es AudioListModel declarado globalmente

Llame a este método en la primera actividad

PlayerActivity.getLiveSong().observe(this, new Observer<AudioListModel>() {
            @Override
            public void onChanged(AudioListModel audioListModel) {
                if (PlayerActivity.mediaPlayer != null && PlayerActivity.mediaPlayer.isPlaying()) {
                    Log.d("LiveSong--->Changes-->", audioListModel.getSongName());
                }
            }
        });

Que esto ayude a nuevos exploradores como yo.

Deepak J
fuente
-4

Método simple para hacer este enfoque. Primero implementa el OnClickListenersen su clase de actividad.

Código:

class MainActivity extends Activity implements OnClickListeners{

protected void OnCreate(Bundle bundle)
{    
    super.onCreate(bundle);    
    setContentView(R.layout.activity_main.xml);    
    Button b1=(Button)findViewById(R.id.sipsi);    
    Button b2=(Button)findViewById(R.id.pipsi);    
    b1.SetOnClickListener(this);    
    b2.SetOnClickListener(this);    
}

public void OnClick(View V)    
{    
    int i=v.getId();    
    switch(i)    
    {    
        case R.id.sipsi:
        {
            //you can do anything from this button
            break;
        }
        case R.id.pipsi:
        {    
            //you can do anything from this button       
            break;
        }
    }
}
Rishabh Rawat
fuente