chuyển đối số cho DialogFragment


116

Tôi cần chuyển một số biến sang DialogFragment, để tôi có thể thực hiện một hành động. Eclipse gợi ý rằng tôi nên sử dụng

Fragment#setArguments(Bundle)

Nhưng tôi không biết làm thế nào để sử dụng chức năng này. Làm thế nào tôi có thể sử dụng nó để chuyển các biến vào hộp thoại của tôi?


Câu trả lời:


299

Sử dụng 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;
}

Và nhận được các đối số như thế này

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

Xem ví dụ đầy đủ tại đây
http://developer.android.com/reference/android/app/DialogFragment.html


Bạn có thể chỉ đặt các biến riêng tư trên MyDialogFragment thay vì sử dụng gói không?
SIr Codealot

10
@SIrCodealot hiệu ứng sẽ giống như cài đặt các biến trên Activity hoặc Fragment. Nếu bạn đối mặt với thứ gì đó phá hủy và tạo lại DialogDragment như thay đổi xoay vòng, bạn sẽ mất tất cả các biến.
inmyth

2
Đối với tất cả những người thắc mắc tại sao một công cụ xây dựng quá tải không được sử dụng trong trường hợp này, hãy xem một cuộc thảo luận khác về chủ đề mang tính hướng dẫn cao: stackoverflow.com/questions/14011808/
Lỗi

Mất một phút để tôi nhận thấy rằng saveInstanceState không được sử dụng.
Odys

25

Tôi đã từng gửi một số giá trị từ listview của tôi

Làm cách nào để gửi

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

Cách nhận bên trong phương thức DialogFragment của onCreate ()

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

// Tải lên 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")

// nhận được

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

1
Câu trả lời tốt hơn!
dùng55924

1
Cảm ơn bạn ! Phiên bản Kotlin đã giúp.
ArdenDev

6

Vì vậy, có hai cách để chuyển các giá trị từ phân đoạn / hoạt động sang phân đoạn hộp thoại: -

  1. Tạo đối tượng phân đoạn hộp thoại với phương thức setter và truyền giá trị / đối số.

  2. Truyền giá trị / đối số thông qua gói.

Cách 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
}

Lưu ý: - Đây không phải là cách tốt nhất để làm

Cách 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
}

Lưu ý: - Đây là cách tốt nhất để làm.


Thậm chí, bạn có thể sử dụng thư viện Gson để truyền Đối tượng hoặc ArrayList <Đối tượng> dưới dạng Chuỗi trong Gói.
Jeffrey

@duggu, tại sao getter và setter không phải là cách tốt nhất để làm như vậy?
sky91

5

như một cách làm việc chung với Fragment, như JafarKhQ đã lưu ý, bạn không nên vượt qua các tham số trong hàm tạo mà với a Bundle.

phương thức tích hợp cho điều đó trong Fragmentlớp là setArguments(Bundle)getArguments().

về cơ bản, những gì bạn làm là thiết lập một gói với tất cả các Parcelablemặt hàng của bạn và gửi chúng vào.
lần lượt, Mảnh vỡ của bạn sẽ có được những vật phẩm đó trong đó onCreatevà làm điều kỳ diệu với chúng.

cách hiển thị trong DialogFragmentliên kết là một cách để thực hiện điều này trong một đoạn nhiều lần xuất hiện với một loại dữ liệu cụ thể và hoạt động tốt hầu hết thời gian, nhưng bạn cũng có thể thực hiện việc này một cách thủ công.


0

Trong trường hợp của tôi, không có đoạn mã nào ở trên có bundle-operatetác phẩm; Đây là quyết định của tôi (tôi không biết đó có phải là mã phù hợp hay không, nhưng nó hoạt động trong trường hợp của tôi):

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) Bằng cách lưu trữ bodyText một cách tĩnh, bạn thực sự không thể có hai phiên bản của lớp này cùng một lúc, với các văn bản cơ thể khác nhau. Thay vào đó, không có lý do gì để không lưu trữ nó như một biến thể. 2) Toàn bộ mục đích của việc gửi đối số bằng setArgument (Gói) là hệ điều hành sau đó có thể tạo lại đoạn đó trong trường hợp bị mất trong tình huống bộ nhớ thấp, v.v. Với giải pháp của bạn, đoạn đó sẽ được tạo lại và văn bản cơ thể sẽ là bất cứ trường hợp cuối cùng của hộp thoại được sử dụng (vì nó là tĩnh). Giải pháp đúng là đặt văn bản cơ thể làm tham số bó.
JHH

0

Chỉ là tôi muốn chỉ cho bạn cách làm những gì đã nói @JafarKhQ trong Kotlin cho những người sử dụng kotlin có thể giúp họ và tiết kiệm thời gian chủ đề:

vì vậy bạn phải tạo một objet đồng hành để tạo chức năng newInstance mới

bạn có thể thiết lập paremter của hàm bất cứ điều gì bạn muốn. sử dụng

 val args = Bundle()

bạn có thể thiết lập đối số của bạn.

Bây giờ bạn có thể sử dụng args.putSomthingđể thêm cho bạn các đối số mà bạn đưa ra làm tham số trong hàm newInstance của mình. putString(key:String,str:String)để thêm chuỗi chẳng hạn, v.v.

Bây giờ để có được đối số bạn có thể sử dụng arguments.getSomthing(Key:String)=> thícharguments.getString("1")

đây là một ví dụ đầy đủ

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

    }
  ...
}

Bây giờ làm thế nào để tạo hộp thoại của bạn, bạn có thể làm một cái gì đó như thế này trong một lớp khác

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

như thế này chẳng hạn

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

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.