将参数传递给DialogFragment


Answers:


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上设置私有变量而不使用bundle吗?
法拉尔爵士

10
@SIrCodealot的效果与在Activity或Fragment上设置变量的效果相同。如果您遇到破坏并重新创建DialogDragment的事物(例如旋转更改),则将丢失所有变量。
神话

2
对于所有想知道为什么在这种情况下不使用重载的构造函数的人,请参阅关于该主题的另一篇很有启发性的讨论:stackoverflow.com/questions/14011808/…–
HondaGuy

我花了一点时间注意到未使用saveedInstanceState
奥德斯

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

如何在DialogFragment的onCreate()方法内部接收

    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 '18

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库将对象或ArrayList <Objects>作为字符串传递给Bundle。
杰弗里

@duggu,为什么getter和setter不是最好的方法?
sky91”,

5

正如JafarKhQ所指出的,作为使用Fragments的一般方法,您不应在构造函数中传递参数,而应使用 Bundle

Fragment该类中的内置方法是setArguments(Bundle)getArguments()

基本上,您要做的是将所有Parcelable商品都捆绑在一起并发送。
反过来,您的片段会在其中获得这些物品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)发送参数的整个目的是,操作系统可以在内存不足等情况下丢失时重新创建该片段。通过您的解决方案,该片段将被重新创建,并且正文将可以使用对话框的最后一个实例(因为它是静态的)。正确的解决方案是将正文设置为bundle参数。
JHH

0

只是我想展示如何使用Kotlin的人在Kotlin中说@JafarKhQ这可能会帮助他们并节省主题时间:

所以您必须创建一个配套对象以创建新的newInstance函数

您可以根据需要设置函数的参数。使用

 val args = Bundle()

您可以设置您的参数。

现在,您可以使用args.putSomthing,将您作为参数提供的args添加到newInstance函数中。 putString(key:String,str:String)例如添加字符串等等

现在,您可以使用参数 arguments.getSomthing(Key:String) =>arguments.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)
        }
        ...
    }
..

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.