ส่งผ่านอาร์กิวเมนต์ไปยัง DialogFragment


116

ฉันต้องการส่งผ่านตัวแปรบางตัวไปDialogFragmentจึงจะสามารถดำเนินการได้ Eclipse แนะนำว่าฉันควรใช้

Fragment#setArguments(Bundle)

แต่ฉันไม่รู้วิธีใช้ฟังก์ชันนี้ ฉันจะใช้มันเพื่อส่งผ่านตัวแปรไปยังไดอะล็อกของฉันได้อย่างไร


คำตอบ:


299

การใช้ newInstance

public static MyDialogFragment newInstance(int num) {
    MyDialogFragment f = new MyDialogFragment();

    // Supply num input as an argument.
    Bundle args = new Bundle();
    args.putInt("num", num);
    f.setArguments(args);

    return f;
}

และรับ Args แบบนี้

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mNum = getArguments().getInt("num");
    ...
}

ดูตัวอย่างเต็มได้ที่นี่
http://developer.android.com/reference/android/app/DialogFragment.html


คุณสามารถตั้งค่าตัวแปรส่วนตัวบน MyDialogFragment แทนการใช้บันเดิลได้หรือไม่
SIr Codealot

10
@SIrCodealot ผลจะเหมือนกับการตั้งค่าตัวแปรใน Activity หรือ Fragment หากคุณเผชิญกับสิ่งที่ทำลายและสร้าง DialogDragment ขึ้นมาใหม่เช่นการเปลี่ยนแปลงการหมุนเวียนคุณจะสูญเสียตัวแปรทั้งหมด
เข้า

2
สำหรับทุกคนที่สงสัยว่าเหตุใดจึงไม่ใช้ตัวสร้างที่โอเวอร์โหลดในกรณีนี้โปรดดูการสนทนาอื่นในหัวข้อที่ให้คำแนะนำอย่างมาก: stackoverflow.com/questions/14011808/…
HondaGuy

เอาฉันนาทีที่จะแจ้งให้ทราบว่าsavedInstanceStateไม่ได้ใช้
Odys

25

ฉันเคยส่งค่าบางอย่างจากมุมมองรายการของฉัน

วิธีการส่ง

mListview.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
            Favorite clickedObj = (Favorite) parent.getItemAtPosition(position);

            Bundle args = new Bundle();
            args.putString("tar_name", clickedObj.getNameTarife());
            args.putString("fav_name", clickedObj.getName());

            FragmentManager fragmentManager = getSupportFragmentManager();
            TarifeDetayPopup userPopUp = new TarifeDetayPopup();
            userPopUp.setArguments(args);
            userPopUp.show(fragmentManager, "sam");

            return false;
        }
    });

วิธีรับภายใน onCreate () เมธอด DialogFragment

    Bundle mArgs = getArguments();
    String nameTrife = mArgs.getString("tar_name");
    String nameFav = mArgs.getString("fav_name");
    String name = "";

// อัปโหลด Kotlin

 val fm = supportFragmentManager
        val dialogFragment = AddProgFargmentDialog() // my custom FargmentDialog
        var args: Bundle? = null
        args?.putString("title", model.title);
        dialogFragment.setArguments(args)
        dialogFragment.show(fm, "Sample Fragment")

// รับ

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (getArguments() != null) {
            val mArgs = arguments
            var myDay= mArgs.getString("title")
        }
    }

1
คำตอบที่ดีกว่า!
user55924

1
ขอบคุณ ! เวอร์ชัน Kotlin ช่วยได้
ArdenDev

6

ดังนั้นจึงมีสองวิธีในการส่งผ่านค่าจากแฟรกเมนต์ / กิจกรรมไปยังส่วนไดอะล็อก: -

  1. สร้างไดอะล็อกแฟรกเมนต์อ็อบเจกต์ด้วยเมธอด make setter และส่งผ่านค่า / อาร์กิวเมนต์

  2. ส่งผ่านค่า / อาร์กิวเมนต์ผ่านบันเดิล

วิธีที่ 1:

// Fragment or Activity 
@Override
public void onClick(View v) {
     DialogFragmentWithSetter dialog = new DialogFragmentWithSetter();
     dialog.setValue(header, body);
     dialog.show(getSupportFragmentManager(), "DialogFragmentWithSetter");         
}


//  your dialog fragment
public class MyDialogFragment extends DialogFragment {
    String header; 
    String body;
    public void setValue(String header, String body) {   
          this.header = header;
          this.body = body;
    }
    // use above variable into your dialog fragment
}

หมายเหตุ: - นี่ไม่ใช่วิธีที่ดีที่สุด

วิธีที่ 2:

// Fragment or Activity 
@Override
public void onClick(View v) {
     DialogFragmentWithSetter dialog = new DialogFragmentWithSetter();
     
     Bundle bundle = new Bundle();
     bundle.putString("header", "Header");
     bundle.putString("body", "Body");  
     dialog.setArguments(bundle);
     dialog.show(getSupportFragmentManager(), "DialogFragmentWithSetter");         
}


//  your dialog fragment
public class MyDialogFragment extends DialogFragment {
    String header; 
    String body;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
             header = getArguments().getString("header","");
             body = getArguments().getString("body","");
        }
    }
    // use above variable into your dialog fragment
}

หมายเหตุ: - นี่เป็นวิธีที่ดีที่สุด


คุณยังสามารถใช้ไลบรารี Gson เพื่อส่งผ่าน Objects หรือ ArrayList <Objects> เป็น Strings ใน Bundle
Jeffrey

@duggu ทำไม getter และ setter ถึงไม่ใช่วิธีที่ดีที่สุด?
sky91

5

ตามวิธีทั่วไปในการทำงานกับ Fragments ดังที่ JafarKhQ กล่าวไว้คุณไม่ควรส่ง params ในตัวสร้าง แต่ใช้ไฟล์Bundle.

เมธอดในตัวสำหรับสิ่งนั้นในFragmentคลาสคือsetArguments(Bundle)และgetArguments()และ

โดยพื้นฐานแล้วสิ่งที่คุณทำคือตั้งค่าชุดรวมกับรายการทั้งหมดของคุณParcelableแล้วส่งไป
ในทางกลับกัน Fragment ของคุณจะได้รับไอเท็มเหล่านั้นในนั้นonCreateและสร้างเวทมนตร์ให้กับพวกมัน

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


0

ในกรณีของฉันไม่มีรหัสด้านบนที่ใช้bundle-operateงานได้ นี่คือการตัดสินใจของฉัน (ฉันไม่รู้ว่าเป็นรหัสที่เหมาะสมหรือไม่ แต่ใช้ได้ในกรณีของฉัน):

public class DialogMessageType extends DialogFragment {
    private static String bodyText;

    public static DialogMessageType addSomeString(String temp){
        DialogMessageType f = new DialogMessageType();
        bodyText = temp;
        return f;
    };

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final String[] choiseArray = {"sms", "email"};
        String title = "Send text via:";
        final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle(title).setItems(choiseArray, itemClickListener);
        builder.setCancelable(true);
        return builder.create();
    }

    DialogInterface.OnClickListener itemClickListener = new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            switch (which){
                case 0:
                    prepareToSendCoordsViaSMS(bodyText);
                    dialog.dismiss();
                    break;
                case 1:
                    prepareToSendCoordsViaEmail(bodyText);
                    dialog.dismiss();
                    break;
                default:
                    break;
            }
        }
    };
[...]
}

public class SendObjectActivity extends FragmentActivity {
[...]

DialogMessageType dialogMessageType = DialogMessageType.addSomeString(stringToSend);
dialogMessageType.show(getSupportFragmentManager(),"dialogMessageType");

[...]
}

1) การจัดเก็บ bodyText แบบคงที่จะทำให้คุณไม่สามารถมีสองอินสแตนซ์ของคลาสนี้ในเวลาเดียวกันได้อย่างมีประสิทธิภาพโดยมีข้อความเนื้อหาที่แตกต่างกัน ไม่มีเหตุผลที่จะไม่เก็บไว้เป็นตัวแปรอินสแตนซ์แทน 2) จุดประสงค์ทั้งหมดของการส่งอาร์กิวเมนต์โดยใช้ setArguments (Bundle) คือจากนั้นระบบปฏิบัติการสามารถสร้างแฟรกเมนต์ขึ้นมาใหม่ในกรณีที่สูญหายในสถานการณ์หน่วยความจำเหลือน้อยเป็นต้นด้วยวิธีการแก้ปัญหาของคุณส่วนย่อยจะถูกสร้างขึ้นใหม่และข้อความเนื้อหาจะ เป็นอินสแตนซ์สุดท้ายของกล่องโต้ตอบที่ใช้ (เนื่องจากเป็นแบบคงที่) วิธีแก้ไขที่ถูกต้องคือการตั้งค่าข้อความเนื้อหาเป็นพารามิเตอร์บันเดิล
JHH

0

เพียงแค่ว่าฉันต้องการแสดงวิธีการทำสิ่งที่ @JafarKhQ กล่าวใน Kotlin สำหรับผู้ที่ใช้kotlinซึ่งอาจช่วยพวกเขาและประหยัดเวลาของธีมด้วย:

ดังนั้นคุณต้องสร้างobjet ร่วมเพื่อสร้างฟังก์ชันnewInstanceใหม่

คุณสามารถตั้งค่าพารามิเตอร์ของฟังก์ชันได้ตามที่คุณต้องการ การใช้

 val args = Bundle()

คุณสามารถตั้งค่า args ของคุณ

ตอนนี้คุณสามารถใช้args.putSomthingเพื่อเพิ่ม args ที่คุณให้เป็น prameter ในฟังก์ชัน newInstance ของคุณ putString(key:String,str:String)เพื่อเพิ่มสตริงเป็นต้นและอื่น ๆ

ตอนนี้เพื่อรับอาร์กิวเมนต์คุณสามารถใช้ arguments.getSomthing(Key:String)=> likearguments.getString("1")

นี่คือตัวอย่างเต็มรูปแบบ

class IntervModifFragment : DialogFragment(), ModContract.View
{
    companion object {
        fun newInstance(  plom:String,type:String,position: Int):IntervModifFragment {
            val fragment =IntervModifFragment()
            val args = Bundle()
            args.putString( "1",plom)
            args.putString("2",type)
            args.putInt("3",position)
            fragment.arguments = args
            return fragment
        }
    }

...
    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        fillSpinerPlom(view,arguments.getString("1"))
         fillSpinerType(view, arguments.getString("2"))
        confirmer_virme.setOnClickListener({on_confirmClick( arguments.getInt("3"))})


        val dateSetListener = object : DatePickerDialog.OnDateSetListener {
            override fun onDateSet(view: DatePicker, year: Int, monthOfYear: Int,
                                   dayOfMonth: Int) {
                val datep= DateT(year,monthOfYear,dayOfMonth)
                updateDateInView(datep.date)
            }
        }

    }
  ...
}

ตอนนี้วิธีสร้างกล่องโต้ตอบของคุณคุณสามารถทำบางสิ่งเช่นนี้ในชั้นเรียนอื่นได้

  val dialog = IntervModifFragment.newInstance(ListInter.list[position].plom,ListInter.list[position].type,position)

เช่นนี้

class InterListAdapter(private val context: Context, linkedList: LinkedList<InterItem> ) : RecyclerView.Adapter<InterListAdapter.ViewHolder>()
{
   ... 
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {

        ...
        holder.btn_update!!.setOnClickListener {
           val dialog = IntervModifFragment.newInstance(ListInter.list[position].plom,ListInter.list[position].type,position)
           val ft = (context as AppCompatActivity).supportFragmentManager.beginTransaction()
            dialog.show(ft, ContentValues.TAG)
        }
        ...
    }
..

}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.