przekazanie argumentu do DialogFragment

Odpowiedzi:

299

Za pomocą 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;
}

I zdobądź Args w ten sposób

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

Zobacz pełny przykład tutaj
http://developer.android.com/reference/android/app/DialogFragment.html

JafarKhQ
źródło
Czy możesz po prostu ustawić zmienne prywatne w MyDialogFragment zamiast używać pakietu?
SIr Codealot
10
@SIrCodealot efekt byłby taki sam, jak ustawienie zmiennych w działaniu lub fragmencie. Jeśli napotkasz coś, co niszczy i odtwarza DialogDragment, takie jak zmiana rotacji, utracisz wszystkie zmienne.
inmyth
2
Dla wszystkich, którzy zastanawiają się, dlaczego przeciążony konstruktor nie jest używany w tym przypadku, zobacz kolejną dyskusję na ten temat, która jest wysoce pouczająca: stackoverflow.com/questions/14011808/…
HondaGuy
Zajęło mi chwilę, zanim zauważyłem, że parametr saveInstanceState nie jest używany.
Odys
25

Kiedyś wysyłałem wartości z mojego widoku listy

Jak wysłać

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

Jak odebrać wewnątrz metodę onCreate () DialogFragment

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

// Przesyłanie 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")

// odbierz

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (getArguments() != null) {
            val mArgs = arguments
            var myDay= mArgs.getString("title")
        }
    }
Sam
źródło
1
Lepsza odpowiedź!
user55924
1
Dziękuję Ci ! Wersja Kotlin pomogła.
ArdenDev
6

Są więc dwa sposoby przekazywania wartości z fragmentu / aktywności do fragmentu okna dialogowego: -

  1. Utwórz obiekt fragmentu okna dialogowego za pomocą metody make setter i przekaż wartość / argument.

  2. Przekaż wartość / argument przez pakiet.

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

Uwaga: - To nie jest najlepszy sposób

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

Uwaga: - To najlepszy sposób.

duggu
źródło
Możesz nawet użyć biblioteki Gson do przekazywania obiektów lub ArrayList <Objects> jako ciągów znaków w pakiecie.
Jeffrey,
@duggu, dlaczego getter i setter nie są najlepszym sposobem na zrobienie tego?
sky91
5

jako ogólny sposób pracy z fragmentami, jak zauważył JafarKhQ, nie należy przekazywać parametrów w konstruktorze, ale z rozszerzeniem Bundle.

wbudowaną metodą tego w Fragmentklasie jest setArguments(Bundle)i getArguments().

po prostu tworzysz paczkę ze wszystkimi Parcelableprzedmiotami i wysyłasz je dalej.
z kolei Twój Fragment dostanie te przedmioty do siebie onCreatei zrobi z nimi magię.

sposób pokazany w DialogFragmentlinku był jednym ze sposobów zrobienia tego w wielokrotnie pojawiającym się fragmencie z jednym określonym typem danych i działa dobrze przez większość czasu, ale możesz to również zrobić ręcznie.

łapa
źródło
0

W moim przypadku żaden z powyższych kodów nie bundle-operatedziała; Oto moja decyzja (nie wiem, czy to poprawny kod, czy nie, ale w moim przypadku działa):

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
źródło
1) Zapisując bodyText statycznie, skutecznie uniemożliwiasz jednoczesne posiadanie dwóch instancji tej klasy z różnymi tekstami. Nie ma powodu, aby zamiast tego przechowywać ją jako zmienną instancji. 2) Cały cel wysyłania argumentów za pomocą setArguments (Bundle) polega na tym, że system operacyjny może następnie odtworzyć fragment na wypadek, gdyby został utracony w sytuacji małej ilości pamięci itp. Dzięki rozwiązaniu fragment zostanie odtworzony, a tekst podstawowy być jakąkolwiek ostatnią używaną instancją okna dialogowego (ponieważ jest statyczna). Prawidłowym rozwiązaniem jest ustawienie tekstu podstawowego jako parametru pakietu.
JHH
0

Po prostu chcę pokazać, jak zrobić to, co powiedział @JafarKhQ w Kotlin dla tych, którzy używają kotlin, który może im pomóc i zaoszczędzić czas na temat:

więc musisz utworzyć obiekt towarzyszący, aby utworzyć nową funkcję newInstance

możesz ustawić dowolne parametry funkcji. za pomocą

 val args = Bundle()

możesz ustawić swoje argumenty.

Możesz teraz użyć args.putSomthingdo dodania argumentów, które podajesz jako parametr w funkcji newInstance. putString(key:String,str:String)na przykład dodać ciąg i tak dalej

Teraz, aby uzyskać argument, możesz użyć arguments.getSomthing(Key:String)=> likearguments.getString("1")

tutaj jest pełny przykład

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

    }
  ...
}

Teraz, jak stworzyć swoje okno dialogowe, możesz zrobić coś takiego w innej klasie

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

tak na przykład

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
źródło