รับผลลัพธ์จาก DialogFragment


232

ฉันใช้DialogFragmentsสำหรับสิ่งต่าง ๆ : เลือกรายการจากรายการป้อนข้อความ

วิธีที่ดีที่สุดในการคืนค่า (เช่นสตริงหรือรายการจากรายการ) กลับไปที่กิจกรรม / ส่วนที่เรียกคืออะไร?

ขณะนี้ฉันกำลังทำให้กิจกรรมการโทรดำเนินการDismissListenerและให้ DialogFragment อ้างอิงกับกิจกรรม ไดอะล็อกจะเรียกOnDimissเมธอดในกิจกรรมและกิจกรรมจะคว้าผลลัพธ์จากวัตถุ DialogFragment ยุ่งมากและไม่ทำงานกับการเปลี่ยนแปลงการกำหนดค่า (เปลี่ยนการวางแนว) เนื่องจาก DialogFragment สูญเสียการอ้างอิงไปยังกิจกรรม

ขอบคุณสำหรับความช่วยเหลือ


10
DialogFragments ยังคงเป็นเพียงเศษเล็กเศษน้อย วิธีการของคุณเป็นวิธีที่แนะนำให้ใช้แฟรกเมนต์เพื่อพูดคุยกับกิจกรรมหลัก developer.android.com/guide/topics/fundamentals/…
codinguser

1
ขอบคุณสำหรับสิ่งนั้น ฉันสนิทมาก (อย่างที่คุณพูด) บิตที่เอกสารที่เชื่อมโยงช่วยฉันด้วยคือการใช้ onAttach () และส่งกิจกรรมให้ผู้ฟัง
James Cross

2
@codinguser, @Styx - "ให้ DialogFragment เป็นข้อมูลอ้างอิงถึงกิจกรรม" - รายละเอียดนี้มีความเสี่ยงเล็กน้อยเนื่องจากทั้งActivityและDialogFragmentอาจถูกสร้างขึ้นใหม่ การใช้Activitypass to onAttach(Activity activity)เป็นวิธีที่เหมาะสมและแนะนำ
sstn

คำตอบ:


246

ใช้myDialogFragment.setTargetFragment(this, MY_REQUEST_CODE)จากสถานที่ที่คุณแสดงไดอะล็อกจากนั้นเมื่อไดอะล็อกของคุณเสร็จสิ้นจากนั้นคุณสามารถโทรgetTargetFragment().onActivityResult(getTargetRequestCode(), ...)และนำไปใช้onActivityResult()ในส่วนที่มี

ดูเหมือนเป็นการละเมิดonActivityResult()โดยเฉพาะอย่างยิ่งเนื่องจากไม่เกี่ยวข้องกับกิจกรรมเลย แต่ฉันเคยเห็นมันแนะนำโดยคน Google อย่างเป็นทางการและอาจจะอยู่ในการสาธิต API ฉันคิดว่ามันเป็นสิ่งที่g/setTargetFragment()เพิ่มเข้ามา


2
setTargetFragment ระบุว่า requestcode สำหรับใช้ใน onActivityResult ดังนั้นฉันเดาว่ามันใช้ได้กับวิธีนี้
Giorgi

87
เกิดอะไรขึ้นถ้าเป้าหมายเป็นกิจกรรม
Fernando Gallego

9
หากเป้าหมายคือกิจกรรมฉันจะประกาศส่วนติดต่อด้วยวิธีเช่น "void onActivityResult2 (int requestCode, int resultCode, ข้อมูล Intent)" และนำไปใช้โดยกิจกรรม ใน DialogFragment เพียงแค่ getActivity และตรวจสอบอินเทอร์เฟซนี้และเรียกมันอย่างเหมาะสม
Ruslan Yanchyshyn

4
มันไม่ใช่ทางออกที่ดี มันจะไม่ทำงานหลังจากบันทึกและกู้คืนสถานะส่วนโต้ตอบ LocalBroadcastManager เป็นทางออกที่ดีที่สุดในกรณีนี้
Nik

4
@ นิกนั่นไม่ใช่ความจริง มันเป็นทางออกที่ดีที่สุด ไม่มีปัญหาเมื่อบันทึกและกู้คืนสถานะ หากคุณเคยมีปัญหาคุณใช้ผู้จัดการส่วนที่ไม่ถูกต้อง แฟรกเมนต์เป้าหมาย / ผู้โทรต้องใช้ getChildFragmentManager () เพื่อแสดงไดอะล็อก
เหลือเชื่อ

140

อย่างที่คุณเห็นที่นี่มีวิธีง่าย ๆ ในการทำเช่นนั้น

ในการDialogFragmentเพิ่มฟังอินเทอร์เฟซของคุณชอบ:

public interface EditNameDialogListener {
    void onFinishEditDialog(String inputText);
}

จากนั้นเพิ่มการอ้างอิงไปยังผู้ฟัง:

private EditNameDialogListener listener;

สิ่งนี้จะถูกใช้เพื่อ "เปิดใช้งาน" วิธีการฟังและเพื่อตรวจสอบว่ากิจกรรมหลัก / ส่วนย่อยใช้อินเทอร์เฟซนี้ (ดูด้านล่าง)

ในActivity/ FragmentActivity/ Fragmentว่า "เรียกว่า" DialogFragmentเพียงแค่ใช้อินเตอร์เฟสนี้

ในDialogFragmentทุกสิ่งที่คุณต้องเพิ่ม ณ จุดที่คุณต้องการยกเลิกDialogFragmentและส่งคืนผลลัพธ์คือ:

listener.onFinishEditDialog(mEditText.getText().toString());
this.dismiss();

ไหนคือสิ่งที่จะถูกส่งกลับไปยังโทรmEditText.getText().toString()Activity

โปรดทราบว่าหากคุณต้องการส่งคืนสิ่งอื่นเพียงแค่เปลี่ยนอาร์กิวเมนต์ที่ผู้ฟังใช้

ท้ายสุดคุณควรตรวจสอบว่าอินเทอร์เฟซถูกนำไปใช้จริงโดยกิจกรรมหลัก / แฟรกเมนต์:

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    // Verify that the host activity implements the callback interface
    try {
        // Instantiate the EditNameDialogListener so we can send events to the host
        listener = (EditNameDialogListener) context;
    } catch (ClassCastException e) {
        // The activity doesn't implement the interface, throw exception
        throw new ClassCastException(context.toString()
                + " must implement EditNameDialogListener");
    }
}

เทคนิคนี้มีความยืดหยุ่นสูงและอนุญาตให้โทรกลับพร้อมผลแม้ว่าคุณจะไม่ต้องการยกเลิกการโต้ตอบก็ตาม


13
มันใช้งานได้ดีกับActivity's และFragmentActivity' s แต่ถ้าเป็นผู้โทรFragment?
Brais Gabin

1
ฉันไม่แน่ใจว่าฉันเข้าใจคุณอย่างเต็มที่ Fragmentแต่มันจะทำงานเดียวกันถ้าโทรเป็น
Assaf Gamliel

2
หากผู้โทรเป็นFragmentคุณคุณสามารถทำบางสิ่งได้: 1. ส่งแฟรกเมนต์เป็นการอ้างอิง (อาจไม่ใช่ความคิดที่ดีเพราะคุณอาจทำให้หน่วยความจำรั่ว) 2. ใช้FragmentManagerและโทรfindFragmentByIdหรือfindFragmentByTagจะได้รับชิ้นส่วนที่มีอยู่ในกิจกรรมของคุณ ฉันหวังว่ามันจะช่วย ขอให้มีความสุขมาก ๆ ในวันนี้!
Assaf Gamliel

5
ปัญหาเกี่ยวกับวิธีการนี้คือส่วนที่ไม่ดีในการเก็บรักษาวัตถุเนื่องจากพวกเขาตั้งใจที่จะสร้างขึ้นมาใหม่เช่นพยายามเปลี่ยนการวางแนว OS จะสร้างชิ้นส่วนใหม่ แต่อินสแตนซ์ของผู้ฟังจะไม่สามารถใช้ได้อีก
Necronet

5
@LOG_TAG ดูที่คำตอบของ @ Timmmm setTargetFragment()และgetTargetFragment()เป็นเวทมนตร์
Brais Gabin

48

มีวิธีที่ง่ายกว่ามากในการรับผลลัพธ์จาก DialogFragment

ก่อนอื่นในกิจกรรมกิจกรรมส่วนหรือกิจกรรมส่วนคุณต้องเพิ่มข้อมูลต่อไปนี้:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Stuff to do, dependent on requestCode and resultCode
    if(requestCode == 1) { // 1 is an arbitrary number, can be any int
         // This is the return result of your DialogFragment
         if(resultCode == 1) { // 1 is an arbitrary number, can be any int
              // Now do what you need to do after the dialog dismisses.
         }
     }
}

นี่requestCodeคือป้ายกำกับ int ของคุณสำหรับ DialogFragment ที่คุณเรียกว่าฉันจะแสดงให้เห็นว่ามันใช้งานได้ในไม่กี่วินาที resultCode คือรหัสที่คุณส่งกลับมาจาก DialogFragment เพื่อบอกให้คุณทราบถึงกิจกรรมรอชิ้นส่วนหรือ FragmentActivity ที่กำลังเกิดขึ้น

ส่วนต่อไปของรหัสในการเรียก DialogFragment ตัวอย่างอยู่ที่นี่:

DialogFragment dialogFrag = new MyDialogFragment();
// This is the requestCode that you are sending.
dialogFrag.setTargetFragment(this, 1);     
// This is the tag, "dialog" being sent.
dialogFrag.show(getFragmentManager(), "dialog");

ด้วยสามบรรทัดนี้คุณจะประกาศ DialogFragment ของคุณให้ตั้งค่า requestCode (ซึ่งจะเรียกใช้ onActivityResult (... ) เมื่อไดอะล็อกถูกยกเลิกและคุณจะแสดงกล่องโต้ตอบมันง่ายมาก

ตอนนี้ใน DialogFragment ของคุณคุณต้องเพิ่มหนึ่งบรรทัดก่อนหน้าโดยตรงdismiss()เพื่อที่คุณจะส่ง resultCode กลับไปที่ onActivityResult ()

getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, getActivity().getIntent());
dismiss();

แค่นั้นแหละ. หมายเหตุ resultCode ถูกกำหนดตามint resultCodeที่ฉันได้ตั้งไว้resultCode = 1;ในกรณีนี้

เพียงเท่านี้คุณก็สามารถส่งผลลัพธ์ของ DialogFragment กลับไปยังกิจกรรมการโทรแฟรกเมนต์หรือแฟรกเมนต์ของคุณได้

นอกจากนี้ดูเหมือนว่าข้อมูลนี้ถูกโพสต์ก่อนหน้านี้ แต่ไม่มีตัวอย่างเพียงพอให้ดังนั้นฉันคิดว่าฉันจะให้รายละเอียดเพิ่มเติม

แก้ไข 06.24.2016 ฉันขอโทษสำหรับรหัสที่ทำให้เข้าใจผิดด้านบน แต่แน่นอนที่สุดคุณไม่สามารถรับผลลัพธ์กลับไปที่กิจกรรมที่เห็นในบรรทัด:

dialogFrag.setTargetFragment(this, 1);

กำหนดเป้าหมายและไม่ได้Fragment Activityดังนั้นในการทำเช่นนี้คุณต้องใช้แอInterfaceCommunicator

ในDialogFragmentชุดของคุณเป็นตัวแปรทั่วโลก

public InterfaceCommunicator interfaceCommunicator;

สร้างฟังก์ชั่นสาธารณะเพื่อจัดการกับมัน

public interface InterfaceCommunicator {
    void sendRequestCode(int code);
}

จากนั้นเมื่อคุณพร้อมที่จะส่งรหัสกลับไปActivityเมื่อDialogFragmentจะทำทำงานคุณเพียงแค่เพิ่มสายก่อนที่คุณdismiss();ของคุณDialogFragment:

interfaceCommunicator.sendRequestCode(1); // the parameter is any int code you choose.

ในกิจกรรมของคุณตอนนี้คุณต้องทำสองสิ่งอย่างแรกคือการลบโค้ดหนึ่งบรรทัดที่ไม่สามารถใช้งานได้อีกต่อไป:

dialogFrag.setTargetFragment(this, 1);  

จากนั้นใช้อินเทอร์เฟซและเสร็จสิ้น คุณสามารถทำได้โดยเพิ่มบรรทัดต่อไปนี้ไปยังimplementsประโยคที่ด้านบนสุดของคลาสของคุณ:

public class MyClass Activity implements MyDialogFragment.InterfaceCommunicator

จากนั้น@Overrideฟังก์ชั่นในกิจกรรม

@Override
public void sendRequestCode(int code) {
    // your code here
}

คุณใช้วิธีการอินเทอร์เฟซนี้เหมือนกับonActivityResult()วิธีที่คุณทำ ยกเว้นวิธีการอินเตอร์เฟซสำหรับการDialogFragmentsและอื่น ๆ Fragmentsสำหรับ


4
วิธีการนี้จะไม่ทำงานหากเป้าหมายคือกิจกรรมเพราะคุณไม่สามารถเรียก onActivityResult (จาก DialogFragment ของคุณ) เนื่องจากระดับการเข้าถึงที่ได้รับการป้องกัน
Ruslan Yanchyshyn

2
นั่นไม่จริงเลย ฉันใช้รหัสที่แน่นอนนี้ในโครงการของฉัน นั่นคือที่ที่ฉันดึงมันออกมาและมันก็ใช้ได้ดี โปรดจำไว้ว่าถ้าคุณมีปัญหาระดับการเข้าถึงที่ได้รับการป้องกันนี้คุณสามารถเปลี่ยนระดับการเข้าถึงของคุณสำหรับวิธีการและชั้นเรียนใด ๆ จากการป้องกันเป็นส่วนตัวหรือสาธารณะหากจำเป็น
แบรนดอน

6
สวัสดีคุณบอกว่าคุณสามารถโทรdialogFrag.setTargetFragment(this, 1)จากกิจกรรมได้ แต่วิธีนี้จะได้รับแฟรกเมนต์เป็นอาร์กิวเมนต์แรกดังนั้นจึงไม่สามารถส่งได้ ฉันถูกไหม ?
MondKin

1
ฉันจะโพสต์คำตอบบางอย่างให้คุณทั้งหมดเพื่ออธิบายกิจกรรม
Brandon

1
@Swift @lcompare คุณอาจต้องแทนที่ onAttach (บริบทบริบท) ใน DialogFragment ของคุณ เช่น:@Override public void onAttach(Context context) { super.onAttach(context); yourInterface = (YourInterface) context; }
lidkxx

20

ดีที่จะสายเกินไปอาจจะตอบ DialogFragmentแต่นี่คือสิ่งที่ฉันได้เพื่อให้ได้ผลลัพธ์กลับมาจาก คล้ายกับคำตอบของ @ brandon ที่นี่ฉันกำลังโทรDialogFragmentจากแฟรกเมนต์เพียงวางโค้ดนี้ในตำแหน่งที่คุณโทรหาไดอะล็อกของคุณ

FragmentManager fragmentManager = getFragmentManager();
            categoryDialog.setTargetFragment(this,1);
            categoryDialog.show(fragmentManager, "dialog");

categoryDialogของฉันอยู่ที่ไหนDialogFragmentที่ฉันต้องการโทรและหลังจากนี้ในการใช้งานของคุณdialogfragmentวางรหัสนี้ที่คุณกำลังตั้งค่าข้อมูลของคุณในเจตนา ค่าresultCodeเป็น 1 คุณสามารถตั้งค่าหรือใช้ระบบที่กำหนด

            Intent intent = new Intent();
            intent.putExtra("listdata", stringData);
            getTargetFragment().onActivityResult(getTargetRequestCode(), resultCode, intent);
            getDialog().dismiss();

ตอนนี้ถึงเวลาที่จะกลับไปที่ส่วนการโทรและใช้วิธีนี้ ตรวจสอบความถูกต้องของข้อมูลหรือผลลัพธ์สำเร็จหากคุณต้องการด้วยresultCodeและrequestCodeในเงื่อนไข

 @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);        
        //do what ever you want here, and get the result from intent like below
        String myData = data.getStringExtra("listdata");
Toast.makeText(getActivity(),data.getStringExtra("listdata"),Toast.LENGTH_SHORT).show();
    }

10

วิธีการที่แตกต่างกันในการอนุญาตให้แฟรกเมนต์สื่อสารกับกิจกรรมได้ :

1)กำหนดส่วนต่อประสานสาธารณะในส่วนและสร้างตัวแปรให้

public OnFragmentInteractionListener mCallback;

public interface OnFragmentInteractionListener {
    void onFragmentInteraction(int id);
}

2)ส่งกิจกรรมเป็นตัวแปร mCallback ในแฟรกเมนต์

try {
    mCallback = (OnFragmentInteractionListener) getActivity();
} catch (Exception e) {
    Log.d(TAG, e.getMessage());
}

3)ใช้ผู้ฟังในกิจกรรมของคุณ

public class MainActivity extends AppCompatActivity implements DFragment.OnFragmentInteractionListener  {
     //your code here
}

4)แทนที่ OnFragmentInteraction ในกิจกรรม

@Override
public void onFragmentInteraction(int id) {
    Log.d(TAG, "received from fragment: " + id);
}

ข้อมูลเพิ่มเติมเกี่ยวกับมัน: https://developer.android.com/training/basics/fragments/communicating.html


ขอบคุณที่สรุปมันเป็นอย่างดี เพียงแค่โน้ตเดียวสำหรับคนอื่น ๆ การสอนของ Android Devs แนะนำให้แทนที่public void onAttachส่วนย่อยและทำกิจกรรมที่นั่น
Big_Chair

8

วิธีง่าย ๆ ที่ฉันค้นพบมีดังต่อไปนี้: ใช้สิ่งนี้เป็น dialogFragment ของคุณ

  CallingActivity callingActivity = (CallingActivity) getActivity();
  callingActivity.onUserSelectValue("insert selected value here");
  dismiss();

จากนั้นในกิจกรรมที่เรียกว่า Dialog Fragment สร้างฟังก์ชั่นที่เหมาะสมเช่น:

 public void onUserSelectValue(String selectedValue) {

        // TODO add your implementation.
      Toast.makeText(getBaseContext(), ""+ selectedValue, Toast.LENGTH_LONG).show();
    }

ขนมปังปิ้งคือการแสดงให้เห็นว่ามันใช้งานได้ ทำงานให้ฉัน


ผมไม่แน่ใจว่าถ้ามันเป็นวิธีการที่เหมาะสมที่จะทำ แต่งานอย่างแน่นอน :)
soshial

ใช้งานได้ดีInterfaceกว่าการมีเพศสัมพันธ์อย่างหนักกับคลาสคอนกรีต
waqaslam

6

ฉันประหลาดใจมากที่เห็นว่าไม่มีใครแนะนำให้ใช้การออกอากาศท้องถิ่นDialogFragmentเพื่อActivityการสื่อสาร! ฉันคิดว่ามันง่ายและสะอาดกว่าคำแนะนำอื่น ๆ โดยพื้นฐานแล้วคุณลงทะเบียนActivityเพื่อรับฟังการออกอากาศและคุณส่งการออกอากาศท้องถิ่นจากDialogFragmentอินสแตนซ์ของคุณ ง่าย สำหรับคำแนะนำทีละขั้นตอนเกี่ยวกับวิธีการตั้งค่าทั้งหมดให้ดูที่นี่


2
ฉันชอบวิธีการแก้ปัญหานี้ถือว่าเป็นการปฏิบัติที่ดีหรือดีที่สุดใน Android หรือไม่?
Benjamin Scharbau

1
ฉันชอบการกวดวิชาจริงๆขอบคุณสำหรับการโพสต์ ฉันต้องการเพิ่มที่ขึ้นอยู่กับสิ่งที่คุณพยายามทำให้สำเร็จวิธีใดวิธีหนึ่งอาจมีประโยชน์มากกว่าวิธีอื่น ฉันขอแนะนำเส้นทางออกอากาศท้องถิ่นถ้าคุณมีหลายอินพุต / ผลลัพธ์ถูกส่งกลับไปยังกิจกรรมจากกล่องโต้ตอบ ฉันอยากจะแนะนำให้ใช้เส้นทาง onActivityResult หากผลลัพธ์ของคุณนั้นเรียบง่าย / เรียบง่าย ดังนั้นเพื่อตอบคำถามฝึกหัดที่ดีที่สุดมันขึ้นอยู่กับสิ่งที่คุณพยายามทำ!
แบรนดอน

1
@AdilHussain คุณพูดถูก ฉันตั้งสมมติฐานว่าผู้คนกำลังใช้ชิ้นส่วนภายในกิจกรรม ตัวเลือก setTargetFragment นั้นยอดเยี่ยมถ้าคุณกำลังสื่อสารกับ Fragment และ DialogFragment แต่คุณต้องใช้วิธีการออกอากาศเมื่อเป็นกิจกรรมที่เรียกใช้ DialogFragment
แบรนดอน

3
สำหรับความรักของ Foo อย่าใช้ Broadcasts !! มันเปิดแอปพลิเคชันของคุณเพื่อปัญหาด้านความปลอดภัย นอกจากนี้ฉันพบว่าแอปพลิเคชัน Android ที่เลวร้ายที่สุดที่ฉันต้องทำงานในการแพร่กระจายการละเมิด คุณคิดว่าวิธีที่ดีกว่าในการสร้างรหัสใช้ไม่ได้อย่างสมบูรณ์หรือไม่ ตอนนี้ฉันต้องรูทเอาต์ตัวรับสัญญาณออกอากาศแทนที่จะเป็นรหัส CLEAR หรือไม่? เพื่อความชัดเจนมีการใช้งานสำหรับผู้เผยแพร่โฆษณา แต่ไม่ใช่ในบริบทนี้! ไม่เคยอยู่ในบริบทนี้! มันเป็นเพียงเลอะเทอะ ท้องถิ่นหรือไม่ การโทรกลับเป็นสิ่งที่คุณต้องการ
StarWind0

1
เช่นเดียวกับฝรั่ง EventBus อีกทางเลือกหนึ่งคือEventBus GreenRobot ฉันไม่ได้ใช้ Guava EventBus แต่เคยใช้ GreenRobot EventBus และมีประสบการณ์ที่ดีกับมัน ดีและใช้งานง่าย สำหรับตัวอย่างเล็ก ๆ ของวิธีการสถาปัตยกรรมการประยุกต์ใช้ Android ใช้ EventBus GreenRobot ให้ดูที่นี่
Adil Hussain

3

หรือแชร์ ViewModel เหมือนที่แสดงไว้ที่นี่:

public class SharedViewModel extends ViewModel {
    private final MutableLiveData<Item> selected = new MutableLiveData<Item>();

    public void select(Item item) {
        selected.setValue(item);
    }

    public LiveData<Item> getSelected() {
        return selected;
    }
}


public class MasterFragment extends Fragment {
    private SharedViewModel model;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
        itemSelector.setOnClickListener(item -> {
            model.select(item);
        });
    }
}

public class DetailFragment extends Fragment {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
        model.getSelected().observe(this, { item ->
           // Update the UI.
        });
    }
}

https://developer.android.com/topic/libraries/architecture/viewmodel#sharing_data_between_fragments


2

ในกรณีของฉันฉันต้องการส่งอาร์กิวเมนต์ไปยัง targetFragment แต่ฉันได้รับข้อยกเว้น "Fragment active แล้ว" ดังนั้นฉันจึงประกาศอินเทอร์เฟซใน DialogFragment ซึ่ง parentFragment ใช้งาน เมื่อ parentFragment เริ่ม DialogFragment มันตั้งค่าตัวเองเป็น TargetFragment จากนั้นใน DialogFragment ฉันเรียกว่า

 ((Interface)getTargetFragment()).onSomething(selectedListPosition);

2

ในคอตลิน

    // My DialogFragment
class FiltroDialogFragment : DialogFragment(), View.OnClickListener {
    
    var listener: InterfaceCommunicator? = null

    override fun onAttach(context: Context?) {
        super.onAttach(context)
        listener = context as InterfaceCommunicator
    }

    interface InterfaceCommunicator {
        fun sendRequest(value: String)
    }   

    override fun onClick(v: View) {
        when (v.id) {
            R.id.buttonOk -> {    
        //You can change value             
                listener?.sendRequest('send data')
                dismiss()
            }
            
        }
    }
}

// กิจกรรมของฉัน

class MyActivity: AppCompatActivity(),FiltroDialogFragment.InterfaceCommunicator {

    override fun sendRequest(value: String) {
    // :)
    Toast.makeText(this, value, Toast.LENGTH_LONG).show()
    }
}
 

ฉันหวังว่ามันจะให้บริการหากคุณสามารถปรับปรุงโปรดแก้ไข ภาษาอังกฤษของฉันไม่ค่อยดี


ในกรณีของฉันกล่องโต้ตอบจะถูกสร้างขึ้นจากส่วนที่ไม่ใช่กิจกรรมดังนั้นวิธีนี้จะไม่ทำงาน แต่ฉันชอบรอยยิ้มที่คุณใส่ไว้ :)
Ssenyonjo

0

ถ้าคุณต้องการส่งอาร์กิวเมนต์และรับผลลัพธ์จากแฟรกเมนต์ที่สองคุณอาจใช้ Fragment.setArguments เพื่อทำงานนี้ให้สำเร็จ

static class FirstFragment extends Fragment {
    final Handler mUIHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case 101: // receive the result from SecondFragment
                Object result = msg.obj;
                // do something according to the result
                break;
            }
        };
    };

    void onStartSecondFragments() {
        Message msg = Message.obtain(mUIHandler, 101, 102, 103, new Object()); // replace Object with a Parcelable if you want to across Save/Restore
                                                                               // instance
        putParcelable(new SecondFragment(), msg).show(getFragmentManager().beginTransaction(), null);
    }
}

static class SecondFragment extends DialogFragment {
    Message mMsg; // arguments from the caller/FirstFragment

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onViewCreated(view, savedInstanceState);
        mMsg = getParcelable(this);
    }

    void onClickOK() {
        mMsg.obj = new Object(); // send the result to the caller/FirstFragment
        mMsg.sendToTarget();
    }
}

static <T extends Fragment> T putParcelable(T f, Parcelable arg) {
    if (f.getArguments() == null) {
        f.setArguments(new Bundle());
    }
    f.getArguments().putParcelable("extra_args", arg);
    return f;
}
static <T extends Parcelable> T getParcelable(Fragment f) {
    return f.getArguments().getParcelable("extra_args");
}

-3

เพียงเพื่อให้มันเป็นหนึ่งในตัวเลือก (เนื่องจากยังไม่มีใครพูดถึง) - คุณสามารถใช้อีเวนต์บัสเช่นออตโต ดังนั้นในบทสนทนาที่คุณทำ:

bus.post(new AnswerAvailableEvent(42));

และให้ผู้โทรของคุณ (กิจกรรมหรือส่วน) สมัครเป็นสมาชิก:

@Subscribe public void answerAvailable(AnswerAvailableEvent event) {
   // TODO: React to the event somehow!
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.