Jak stworzyć własny interfejs Listenera w systemie Android?

138

Czy ktoś mógłby mi pomóc w utworzeniu interfejsu odbiornika zdefiniowanego przez użytkownika z niektórymi fragmentami kodu?

Rajapandian
źródło

Odpowiedzi:

203

Utwórz nowy plik:

MyListener.java:

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

W swojej działalności zaimplementuj interfejs:

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
    }
}

W swojej klasie niestandardowej w razie potrzeby wywołaj interfejs:

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
źródło
3
Jak przekazać obiekt Listener, jeśli nasz Button jest już w układzie, a nie używaliśmy MyButton m = new MyButton (this); sposób na stworzenie obiektu Button.
Qadir Hussain
2
Możesz dodać nową metodę w klasie MyButton: void setMyListener (MyListner m1) {this.ml = m1;}, a następnie użyć tej metody w dowolnym momencie do ustawienia obiektu detektora.
Rakesh Soni
1
gdzie jest MyLogicToIntimateOthere () używana ta metoda?
abh22ishek
1
Pochodząc z tła iOS, gdybym zrobił to w iOS, spowodowałoby to wyciek pamięci, ponieważ odbiornik MyButton jest silnym odniesieniem do słuchacza, a odbiornik ma silne odniesienie do MyButton ... czy java garbage collector jest wystarczająco sprytny, aby czy wiesz, że zarówno listener, jak i MyButton powinny zostać wyczyszczone, jeśli nie ma żadnych innych odniesień do nasłuchiwania niż z MyButton? Możesz użyć a WeakReference<>w tym przypadku, ale wtedy nie możesz uczynić słuchacza anonimową klasą lub czegokolwiek, gdzie słuchacz nie ma innych odniesień ... więc lepiej go nie używać
Fonix
gdzie jest MyLogicToIntimateOthers () używana
Ab
110

przeczytaj wzorzec obserwatora

interfejs słuchacza

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

następnie w klasie powiedz Eventklasa

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 :)
    }
}

w Twojej klasie kierowcy 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
źródło
11

Utworzyłem Generic Listener AsyncTask, który pobiera wynik z oddzielnej klasy AsycTask i przekazuje go do CallingActivity przy użyciu interfejsu Callback.

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

Berło

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);
   }  
}

Spójrz na to , to pytanie, aby uzyskać więcej informacji.

Xar-e-ahmer Khan
źródło
9

Istnieją 4 kroki:

1. utwórz klasę interfejsu (odbiornik)

2. użyj interfejsu w widoku 1 (zdefiniuj zmienną)

3. implementuje interfejs do widoku 2 (widok 1 używany w widoku 2)

4. przejście interfejsu w widoku 1 do widoku 2

Przykład:

Krok 1: musisz stworzyć interfejs i zdefiniować funkcję

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

Krok 2: użyj tego interfejsu w widoku

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");
    }
}

Krok 3,4: narzędzia do działania

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
źródło
7

Utwórz interfejs słuchacza.

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

I utwórz metodę setOnCustomClick w innym działaniu (lub fragmencie), w którym chcesz zastosować niestandardowy odbiornik ......

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

Wywołaj tę metodę z pierwszego działania i przekaż interfejs odbiornika ...

Kapil Vij
źródło
4

W roku 2018 nie ma potrzeby stosowania interfejsów słuchaczy. Masz Android LiveData, aby zająć się przekazaniem pożądanego wyniku z powrotem do komponentów interfejsu użytkownika.

Jeśli wezmę odpowiedź Rupesha i dostosuję ją do korzystania z LiveData, spodoba się tak:

public class Event {

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

         // and in the end

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

a teraz w Twojej klasie kierowcy 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.
            }
        });
    }
}

Aby uzyskać więcej informacji wraz z przykładami kodu, możesz przeczytać mój post na ten temat, a także oficjalne dokumenty:

Kiedy i dlaczego używać LiveData

Oficjalne dokumenty

TheCodeFather
źródło
0

W systemie Android możesz utworzyć interfejs, taki jak Listener, a Twoja aktywność go implementuje, ale nie sądzę, że jest to dobry pomysł. jeśli mamy wiele komponentów do nasłuchiwania zmian ich stanu, możemy stworzyć BaseListener implementuje Listener interfejsu i użyć kodu typu do ich obsługi. możemy powiązać metodę podczas tworzenia pliku XML, na przykład:

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

oraz kod źródłowy:

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

ale nie sądzę, żeby to był dobry pomysł ...

user3055973
źródło
0

Zrobiłem to jak poniżej, aby wysłać moją klasę modelu z drugiej czynności do pierwszej. Użyłem LiveData, aby to osiągnąć, z pomocą odpowiedzi od Rupesh i TheCodeFather.

Drugie działanie

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

„liveSong” to AudioListModel zadeklarowane globalnie

Wywołaj tę metodę w pierwszym działaniu

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());
                }
            }
        });

Niech to pomoże nowym odkrywcom, takim jak ja.

Deepak J.
źródło
-4

Prosta metoda wykonania tego podejścia. Po pierwsze implementuje OnClickListenersw swojej klasie Activity.

Kod:

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
źródło