มีใครช่วยฉันสร้างอินเทอร์เฟซผู้ฟังที่กำหนดโดยผู้ใช้ด้วยข้อมูลโค้ดบางส่วนได้ไหม
มีใครช่วยฉันสร้างอินเทอร์เฟซผู้ฟังที่กำหนดโดยผู้ใช้ด้วยข้อมูลโค้ดบางส่วนได้ไหม
คำตอบ:
สร้างไฟล์ใหม่:
MyListener.java:
public interface MyListener {
// you can define any parameter as per your requirement
public void callback(View view, String result);
}
ในกิจกรรมของคุณใช้อินเทอร์เฟซ:
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
}
}
ในคลาสที่กำหนดเองของคุณให้เรียกใช้อินเทอร์เฟซเมื่อจำเป็น:
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<>ในกรณีนี้ แต่คุณไม่สามารถทำให้ผู้ฟังเป็นคลาสที่ไม่ระบุตัวตนหรืออะไรก็ได้ที่ผู้ฟังไม่มีการอ้างอิงอื่น ... ดังนั้นจึงไม่ควรใช้
โปรดอ่านรูปแบบผู้สังเกตการณ์
อินเทอร์เฟซสำหรับผู้ฟัง
public interface OnEventListener {
void onEvent(EventResult er);
// or void onEvent(); as per your need
}
จากนั้นในชั้นเรียนของคุณพูดว่าEventชั้นเรียน
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 :)
}
}
ในคลาสคนขับของคุณ 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();
}
}
ฉันได้สร้าง Generic AsyncTask Listener ซึ่งได้รับผลลัพธ์จาก AsycTask แยกคลาสและมอบให้กับ CallingActivity โดยใช้ Interface Callback
new GenericAsyncTask(context,new AsyncTaskCompleteListener()
{
public void onTaskComplete(String response)
{
// do your work.
}
}).execute();
อินเตอร์เฟซ
interface AsyncTaskCompleteListener<T> {
public void onTaskComplete(T result);
}
ทั่วไป AsyncTask
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);
}
}
มี 4 ขั้นตอนดังนี้
1. สร้างคลาสอินเตอร์เฟส (ผู้ฟัง)
2. ใช้อินเทอร์เฟซในมุมมอง 1 (กำหนดตัวแปร)
3. อินเทอร์เฟซที่เรียบง่ายเพื่อดู 2 (มุมมอง 1 ใช้ในมุมมอง 2)
4. ส่งผ่านอินเทอร์เฟซในมุมมอง 1 เพื่อดู 2
ตัวอย่าง:
ขั้นตอนที่ 1: คุณต้องสร้างอินเทอร์เฟซและกำหนดฟังก์ชัน
public interface onAddTextViewCustomListener {
void onAddText(String text);
}
ขั้นตอนที่ 2: ใช้อินเทอร์เฟซนี้ในมุมมอง
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");
}
}
ขั้นตอนที่ 3,4: ดำเนินการกับกิจกรรม
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);
}
}
สร้างอินเทอร์เฟซสำหรับผู้ฟัง
public interface YourCustomListener
{
public void onCustomClick(View view);
// pass view as argument or whatever you want.
}
และสร้างเมธอด setOnCustomClick ในกิจกรรมอื่น (หรือแฟรกเมนต์) ซึ่งคุณต้องการใช้ตัวฟังแบบกำหนดเองของคุณ ......
public void setCustomClickListener(YourCustomListener yourCustomListener)
{
this.yourCustomListener= yourCustomListener;
}
เรียกวิธีนี้จากกิจกรรมแรกของคุณและส่งผ่านอินเทอร์เฟซสำหรับผู้ฟัง ...
ในปี 2018 ไม่จำเป็นต้องมีอินเทอร์เฟซสำหรับผู้ฟัง คุณมี Android LiveData เพื่อดูแลการส่งผลลัพธ์ที่ต้องการกลับไปยังส่วนประกอบ UI
ถ้าฉันจะเอาคำตอบของ Rupesh ไปปรับให้ใช้ LiveData มันจะเป็นดังนี้:
public class Event {
public LiveData<EventResult> doEvent() {
/*
* code code code
*/
// and in the end
LiveData<EventResult> result = new MutableLiveData<>();
result.setValue(eventResult);
return result;
}
}
และตอนนี้ในคลาสไดรเวอร์ของคุณ 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.
}
});
}
}
สำหรับข้อมูลเพิ่มเติมพร้อมกับตัวอย่างโค้ดคุณสามารถอ่านโพสต์ของฉันเกี่ยวกับเรื่องนี้รวมถึงเอกสารอย่างเป็นทางการ:
ใน Android คุณสามารถสร้างอินเทอร์เฟซเช่น Listener และกิจกรรมของคุณก็ใช้งานได้ แต่ฉันไม่คิดว่ามันเป็นความคิดที่ดี หากเรามีองค์ประกอบจำนวนมากเพื่อรับฟังการเปลี่ยนแปลงของสถานะเราสามารถสร้าง BaseListener ใช้ Listener อินเตอร์เฟสและใช้รหัสประเภทเพื่อจัดการ เราสามารถผูกเมธอดเมื่อเราสร้างไฟล์ XML ตัวอย่างเช่น:
<Button
android:id="@+id/button4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button4"
android:onClick="Btn4OnClick" />
และซอร์สโค้ด:
public void Btn4OnClick(View view) {
String strTmp = "点击Button04";
tv.setText(strTmp);
}
แต่ฉันไม่คิดว่ามันเป็นความคิดที่ดี ...
ฉันได้ทำบางสิ่งดังต่อไปนี้สำหรับการส่งคลาสโมเดลของฉันจากกิจกรรมที่สองไปยังกิจกรรมแรก ฉันใช้ LiveData เพื่อให้บรรลุสิ่งนี้ด้วยความช่วยเหลือของคำตอบจาก Rupesh และ TheCodeFather
กิจกรรมที่สอง
public static MutableLiveData<AudioListModel> getLiveSong() {
MutableLiveData<AudioListModel> result = new MutableLiveData<>();
result.setValue(liveSong);
return result;
}
"liveSong" คือ AudioListModel ที่ประกาศทั่วโลก
เรียกวิธีนี้ในกิจกรรมแรก
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());
}
}
});
ขอความช่วยเหลือสำหรับนักสำรวจมือใหม่เช่นฉัน
วิธีง่ายๆในการทำแนวทางนี้ ขั้นแรกดำเนินการOnClickListenersในชั้นเรียนกิจกรรมของคุณ
รหัส:
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;
}
}
}