Czy ktoś mógłby mi pomóc w utworzeniu interfejsu odbiornika zdefiniowanego przez użytkownika z niektórymi fragmentami kodu?
Czy ktoś mógłby mi pomóc w utworzeniu interfejsu odbiornika zdefiniowanego przez użytkownika z niektórymi fragmentami kodu?
Odpowiedzi:
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");
}
}
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ć
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();
}
}
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.
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);
}
}
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 ...
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:
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ł ...
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.
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;
}
}
}