Übergabe des Arguments an DialogFragment

116

Ich muss einige Variablen übergeben DialogFragment, damit ich eine Aktion ausführen kann. Eclipse schlägt vor, dass ich verwenden sollte

Fragment#setArguments(Bundle)

Aber ich weiß nicht, wie ich diese Funktion verwenden soll. Wie kann ich damit Variablen an meinen Dialog übergeben?

giozh
quelle
Schauen Sie sich den Beispielcode an: androidxref.com/4.4.2_r1/xref/development/samples/ApiDemos/src/…
IgorGanapolsky

Antworten:

299

Verwenden von 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;
}

Und hol die Args so

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

Das vollständige Beispiel finden Sie hier
http://developer.android.com/reference/android/app/DialogFragment.html

JafarKhQ
quelle
Können Sie einfach private Variablen in MyDialogFragment festlegen, anstatt das Bundle zu verwenden?
SIr Codealot
10
@SIrCodealot Der Effekt entspricht dem Festlegen von Variablen für Aktivität oder Fragment. Wenn Sie auf etwas stoßen, das das DialogDragment zerstört und neu erstellt, wie z. B. eine Rotationsänderung, verlieren Sie alle Variablen.
Inmyth
2
Für alle, die sich fragen, warum in diesem Fall kein überladener Konstruktor verwendet wird, finden Sie eine weitere Diskussion zu diesem Thema, die sehr lehrreich ist: stackoverflow.com/questions/14011808/…
HondaGuy,
Ich habe eine Minute gebraucht , um festzustellen , dass der savedInstanceState nicht verwendet wird.
Odys
25

Ich habe einige Werte aus meiner Listenansicht gesendet

Wie senden

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

So empfangen Sie die onCreate () -Methode von DialogFragment

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

// Kotlin hochladen

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

// erhalten

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (getArguments() != null) {
            val mArgs = arguments
            var myDay= mArgs.getString("title")
        }
    }
Sam
quelle
1
Die bessere Antwort!
user55924
1
Danke ! Die Kotlin-Version hat geholfen.
ArdenDev
6

Es gibt also zwei Möglichkeiten, Werte von Fragment / Aktivität an Dialogfragment zu übergeben: -

  1. Erstellen Sie ein Dialogfragmentobjekt mit der Methode make setter und übergeben Sie den Wert / das Argument.

  2. Übergeben Sie Wert / Argument durch Bundle.

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

Hinweis: - Dies ist nicht der beste Weg

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

Hinweis: - Dies ist der beste Weg.

Duggu
quelle
Sie können sogar die Gson-Bibliothek verwenden, um Objekte oder ArrayList <Objekte> als Zeichenfolgen im Bundle zu übergeben.
Jeffrey
@duggu, warum ist Getter und Setter nicht der beste Weg, dies zu tun?
sky91
5

Als allgemeine Methode zur Arbeit mit Fragmenten sollten Sie, wie JafarKhQ feststellte, die Parameter nicht im Konstruktor übergeben, sondern mit a Bundle .

Die in der FragmentKlasse integrierte Methode dafür ist setArguments(Bundle)undgetArguments() .

Im Grunde genommen richten Sie ein Bündel mit all Ihren ParcelableArtikeln ein und senden sie weiter.
Im Gegenzug erhält Ihr Fragment diese GegenständeonCreate und zaubert sie.

Die im DialogFragmentLink gezeigte Methode war eine Möglichkeit, dies in einem mehrfach erscheinenden Fragment mit einem bestimmten Datentyp zu tun, und funktioniert die meiste Zeit einwandfrei. Sie können dies jedoch auch manuell tun.

thepoosh
quelle
0

In meinem Fall bundle-operatefunktioniert keiner der obigen Codes mit ; Hier ist meine Entscheidung (ich weiß nicht, ob es sich um richtigen Code handelt oder nicht, aber in meinem Fall funktioniert er):

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

[...]
}
Kirill
quelle
1) Indem Sie den bodyText statisch speichern, machen Sie es effektiv unmöglich, zwei Instanzen dieser Klasse gleichzeitig mit unterschiedlichen Körpertexten zu haben. Es gibt keinen Grund, es stattdessen nicht als Instanzvariable zu speichern. 2) Der gesamte Zweck des Sendens von Argumenten mit setArguments (Bundle) besteht darin, dass das Betriebssystem das Fragment neu erstellen kann, falls es in einer Situation mit wenig Arbeitsspeicher usw. verloren geht. Mit Ihrer Lösung wird das Fragment neu erstellt und der Haupttext wird erstellt sei unabhängig von der zuletzt verwendeten Instanz des Dialogfelds (da es statisch ist). Die richtige Lösung besteht darin, den Textkörper als Bündelparameter festzulegen.
JHH
0

Nur dass ich zeigen möchte, wie man das macht, was @JafarKhQ in Kotlin gesagt hat, für diejenigen, die Kotlin verwenden , die ihnen helfen und auch Themenzeit sparen könnten:

Sie müssen also ein Begleitobjekt erstellen , um eine neue newInstance- Funktion zu erstellen

Sie können den Paremter der Funktion beliebig einstellen. mit

 val args = Bundle()

Sie können Ihre Argumente einstellen.

Sie können jetzt args.putSomthingArgumente hinzufügen, die Sie als Parameter in Ihrer newInstance-Funktion angeben. putString(key:String,str:String)um zum Beispiel einen String hinzuzufügen und so weiter

Nun erhalten Sie das Argument, das Sie verwenden können arguments.getSomthing(Key:String) => like verwendenarguments.getString("1")

Hier ist ein vollständiges Beispiel

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

    }
  ...
}

Wie Sie nun Ihren Dialog erstellen, können Sie in einer anderen Klasse so etwas tun

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

so zum Beispiel

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

}
DINA TAKLIT
quelle