टुकड़े से संवाद दिखाएं?


119

मेरे कुछ अंश हैं जिन्हें एक नियमित संवाद दिखाने की आवश्यकता है। इन संवादों पर उपयोगकर्ता हां / ना में उत्तर चुन सकता है, और फिर टुकड़ा को तदनुसार व्यवहार करना चाहिए।

अब, Fragmentकक्षा में onCreateDialog()ओवरराइड करने की कोई विधि नहीं है , इसलिए मुझे लगता है कि मुझे बाहर के संवादों को लागू करना होगा, जिसमें शामिल हैं Activity। यह ठीक है, लेकिन फिर Activityखंड को चुने गए उत्तर को किसी तरह वापस रिपोर्ट करने की आवश्यकता है। मैं निश्चित रूप से यहां कॉलबैक पैटर्न का उपयोग कर सकता हूं, इसलिए यह खंड Activityएक श्रोता वर्ग के साथ ही रजिस्टर करता है , और गतिविधि जवाब को फिर से, या कुछ इस तरह से रिपोर्ट करेगी।

लेकिन यह एक साधारण कार्य के लिए काफी बड़ी गड़बड़ी प्रतीत होती है क्योंकि एक टुकड़े में "सरल" हां-नहीं संवाद प्रदर्शित करना। इसके अलावा, इस तरह से मेरा Fragmentकम आत्म-निहित होगा।

क्या ऐसा करने के लिए कुछ क्लीनर तरीका है?

संपादित करें:

इस प्रश्न का उत्तर वास्तव में विस्तार से नहीं बताता है कि किसी को फ़्रैगमेंट से संवाद प्रदर्शित करने के लिए डायलॉगफ्रैगमेंट का उपयोग कैसे करना चाहिए। तो AFAIK, जाने का रास्ता है:

  1. एक टुकड़ा प्रदर्शित करें।
  2. जब जरूरत होती है, तो एक DialogFragment को तुरंत करें।
  3. मूल संवाद को इस DialogFragment के लक्ष्य के रूप में सेट करें, के साथ .setTargetFragment()
  4. मूल फ़्रैगमेंट से .show () के साथ DialogFragment दिखाएँ।
  5. जब उपयोगकर्ता इस DialogFragment पर कुछ विकल्प चुनता है, तो इस चयन के बारे में मूल फ़्रैगमेंट को सूचित करें (जैसे उपयोगकर्ता ने 'हाँ' पर क्लिक किया), आप .getTarget () के साथ मूल फ़्रैगमेंट का संदर्भ प्राप्त कर सकते हैं।
  6. डायलॉगफ्रेग्मेंट को खारिज करें।

1
आपकी तकनीक तब काम करती है, जब एक स्क्रीन रोटेशन होता है। मुझे तब बल मिलता है। कोई विचार?
वेस्टन

@Weston Zsombor द्वारा पहला जवाब देखें: stackoverflow.com/questions/8235080/…
mayimaus

जवाबों:


37

आपको इसके बजाय DialogFragment का उपयोग करना चाहिए ।


9
दुर्भाग्य से यह दृष्टिकोण पिछले Android संशोधनों के क्लासिक प्रबंधित संवाद दृष्टिकोण की तुलना में थोड़ा अधिक है, लेकिन यह अब पसंदीदा तरीका है। के तरीकों और तरीकों का Activityउपयोग करके आप पूरी तरह से संदर्भित करने से बच सकते हैं , जिससे कॉल करने वाले टुकड़े को सीधे रिपोर्ट करने की अनुमति मिलती है (उन्मुखीकरण परिवर्तनों के बाद भी)। putFragmentgetFragmentFragmentManagerDialogFragment
डेव

क्या होगा अगर आपके पास एक ListFragment है जिसे Dialogs प्रदर्शित करने की आवश्यकता है, उन दोनों को विस्तारित नहीं कर सकता है
marchinram

16
लिस्ट फ़्रेग्मेंट उपवर्ग डायलॉग फ़्रेग्मेंटेशन का उपयोग करेगा, नए लोगों को तत्काल डायलॉग फ़्रेग्मेंट करने के लिए, न कि डायलॉग फ़्रेग्मेंट्स का उपयोग करके। (डायलॉगफ्रैगमेंट एक ऐसा डायलॉग है, जिसे फ्रैगमेंट के रूप में लागू किया गया है, न कि एक फ्रैगमेंट, जो
डायलॉग्स

4
कृपया कुछ स्निपेट जोड़ें ताकि हम उत्सुकता से समझ सकें
अर्पित पटेल

35

मुझे पहले से स्वीकार किए गए उत्तर पर सावधानीपूर्वक संदेह करना चाहिए कि डायलॉगफ्रैगमेंट का उपयोग करना सबसे अच्छा विकल्प है। इरादा (प्राथमिक) DialogFragment के प्रयोजन के टुकड़े कि प्रदर्शित करने के लिए हो रहा है कर रहे हैं संवाद खुद को, प्रदर्शन टुकड़े कि करने के लिए नहीं है प्रदर्शित करने के लिए संवाद।

मेरा मानना ​​है कि संवाद और टुकड़े के बीच मध्यस्थता के लिए टुकड़े की गतिविधि का उपयोग करना बेहतर विकल्प है।


10
चूंकि प्रबंधित संवाद ( onCreateDialog) दृष्टिकोण जल्द ही पदावनत होने वाला है, मैं असहमत हूं और कहूंगा कि DialogFragmentवास्तव में जाने का रास्ता है।
डेव

4
स्वीकृत उत्तर का मतलब है कि डायलॉग के बजाय डायलॉगफ्रैगमेंट का उपयोग करें, लिस्टफ्रेगमेंट के बजाय एएफएआईसीएस।
एनएमआर

वास्तव में एक संवाद खंड का उपयोग एक संवाद और एक सामान्य खंड दोनों के रूप में किया जा सकता है - एम्बेडिंग डेवलपर
क्लाइव जेफरीज़

@CliveJefferies यह हो सकता है, लेकिन अभी भी अपने भीतर से अन्य संवाद दिखाने के लिए नहीं है। मुझे लगता है कि यहां लोग सवाल गलत कर रहे हैं।
Marcel Bro

@anoniim यह इस बात पर निर्भर करता है कि संवाद खंड का उपयोग कैसे किया जा रहा है। अगर इसे नियमित टुकड़े के रूप में इस्तेमाल किया जाए तो यह ठीक है। यदि यह एक संवाद के रूप में उपयोग किया जा रहा है, तो हाँ, आपको दूसरा संवाद नहीं दिखाना चाहिए।
क्लाइव जेफरीज़

24

यहाँ एक हाँ / नहीं DialogFragment का एक पूर्ण उदाहरण है:

कक्षा:

public class SomeDialog extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new AlertDialog.Builder(getActivity())
            .setTitle("Title")
            .setMessage("Sure you wanna do this!")
            .setNegativeButton(android.R.string.no, new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // do nothing (will close dialog)
                }
            })
            .setPositiveButton(android.R.string.yes,  new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // do something
                }
            })
            .create();
    }
}

संवाद शुरू करने के लिए:

        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        // Create and show the dialog.
        SomeDialog newFragment = new SomeDialog ();
        newFragment.show(ft, "dialog");

आप क्लास को onClickListener को लागू करने और एम्बेडेड श्रोताओं के बजाय इसका उपयोग करने दे सकते हैं।

कॉलबैक टू एक्टिविटी

यदि आप कॉलबैक लागू करना चाहते हैं तो यह कैसे किया जाता है: आपकी गतिविधि में:

YourActivity extends Activity implements OnFragmentClickListener

तथा

@Override
public void onFragmentClick(int action, Object object) {
    switch(action) {
        case SOME_ACTION:
        //Do your action here
        break;
    }
}

कॉलबैक क्लास:

public interface OnFragmentClickListener {
    public void onFragmentClick(int action, Object object);
}

फिर एक टुकड़े से कॉलबैक करने के लिए आपको यह सुनिश्चित करने की आवश्यकता है कि श्रोता इस तरह से जुड़ा हुआ है:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mListener = (OnFragmentClickListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString() + " must implement listeners!");
    }
}

और इस तरह एक कॉलबैक किया जाता है:

mListener.onFragmentClick(SOME_ACTION, null); // null or some important object as second parameter.

4
यह व्याख्या नहीं करता है कि इसे फ्रैगमेंट से कैसे शुरू किया जाए
akohout

@raveN आप बस अपनी गतिविधि के लिए एक कॉलबैक करेंगे जो तब टुकड़ा शुरू करेगा।
वारपज़िट

@ व्यापक उत्तर के लिए धन्यवाद। मैं फ्रैगमेंट मैनजर को छूता हूं, जो मैं पहले से ही अनजाने में काम कर रहा हूं ... मैं कैसे (गैर-डायलॉग) फ्रैगमेंट पर वापस क्लिक कर सकता हूं जिसे उपयोगकर्ता इनपुट की आवश्यकता है? BTW, क्या लेनदेन को बैकस्टैक में नहीं जोड़ा जाना चाहिए?
१२:०४ बजे का।

गतिविधि से @kaay आप दिए गए टुकड़े में किसी भी सार्वजनिक विधि को कॉल कर सकते हैं जिसे नए इनपुट की आवश्यकता है। वहाँ से यह नई सामग्री के साथ बहुत आसान अद्यतन होना चाहिए।
तानाज़ित

1
@RichardLeMesurier वास्तव में, टुकड़े उतार चढ़ाव हैं।
वॉर्पज़िट

13

मेरे लिए, यह निम्नलिखित था-

MyFragment:

public class MyFragment extends Fragment implements MyDialog.Callback
{
    ShowDialog activity_showDialog;

    @Override
    public void onAttach(Activity activity)
    {
        super.onAttach(activity);
        try
        {
            activity_showDialog = (ShowDialog)activity;
        }
        catch(ClassCastException e)
        {
            Log.e(this.getClass().getSimpleName(), "ShowDialog interface needs to be     implemented by Activity.", e);
            throw e;
        }
    }

    @Override
    public void onClick(View view) 
    {
        ...
        MyDialog dialog = new MyDialog();
        dialog.setTargetFragment(this, 1); //request code
        activity_showDialog.showDialog(dialog);
        ...
    }

    @Override
    public void accept()
    {
        //accept
    }

    @Override
    public void decline()
    {
        //decline
    }

    @Override
    public void cancel()
    {
        //cancel
    }

}

MyDialog:

public class MyDialog extends DialogFragment implements View.OnClickListener
{
    private EditText mEditText;
    private Button acceptButton;
    private Button rejectButton;
    private Button cancelButton;

    public static interface Callback
    {
        public void accept();
        public void decline();
        public void cancel();
    }

    public MyDialog()
    {
        // Empty constructor required for DialogFragment
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        View view = inflater.inflate(R.layout.dialogfragment, container);
        acceptButton = (Button) view.findViewById(R.id.dialogfragment_acceptbtn);
        rejectButton = (Button) view.findViewById(R.id.dialogfragment_rejectbtn);
        cancelButton = (Button) view.findViewById(R.id.dialogfragment_cancelbtn);
        acceptButton.setOnClickListener(this);
        rejectButton.setOnClickListener(this);
        cancelButton.setOnClickListener(this);
        getDialog().setTitle(R.string.dialog_title);
        return view;
    }

    @Override
    public void onClick(View v)
    {
        Callback callback = null;
        try
        {
            callback = (Callback) getTargetFragment();
        }
        catch (ClassCastException e)
        {
            Log.e(this.getClass().getSimpleName(), "Callback of this class must be implemented by target fragment!", e);
            throw e;
        }

        if (callback != null)
        {
            if (v == acceptButton)
            {   
                callback.accept();
                this.dismiss();
            }
            else if (v == rejectButton)
            {
                callback.decline();
                this.dismiss();
            }
            else if (v == cancelButton)
            {
                callback.cancel();
                this.dismiss();
            }
        }
    }
}

गतिविधि:

public class MyActivity extends ActionBarActivity implements ShowDialog
{
    ..

    @Override
    public void showDialog(DialogFragment dialogFragment)
    {
        FragmentManager fragmentManager = getSupportFragmentManager();
        dialogFragment.show(fragmentManager, "dialog");
    }
}

DialogFragment लेआउट:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/dialogfragment_textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="10dp"
        android:text="@string/example"/>

    <Button
        android:id="@+id/dialogfragment_acceptbtn"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_centerHorizontal="true"
        android:layout_below="@+id/dialogfragment_textview"
        android:text="@string/accept"
        />

    <Button
        android:id="@+id/dialogfragment_rejectbtn"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_alignLeft="@+id/dialogfragment_acceptbtn"
        android:layout_below="@+id/dialogfragment_acceptbtn"
        android:text="@string/decline" />

     <Button
        android:id="@+id/dialogfragment_cancelbtn"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="20dp"
        android:layout_alignLeft="@+id/dialogfragment_rejectbtn"
        android:layout_below="@+id/dialogfragment_rejectbtn"
        android:text="@string/cancel" />

     <Button
        android:id="@+id/dialogfragment_heightfixhiddenbtn"
        android:layout_width="200dp"
        android:layout_height="20dp"
        android:layout_marginTop="10dp"
        android:layout_marginBottom="20dp"
        android:layout_alignLeft="@+id/dialogfragment_cancelbtn"
        android:layout_below="@+id/dialogfragment_cancelbtn"
        android:background="@android:color/transparent"
        android:enabled="false"
        android:text=" " />
</RelativeLayout>

जैसा कि नाम से dialogfragment_heightfixhiddenbtnपता चलता है, मैं सिर्फ यह तय करने का एक तरीका नहीं निकाल सका कि नीचे के बटन की ऊंचाई कहने के बावजूद आधी कट गई थी wrap_content, इसलिए मैंने आधे में "कट" होने के बजाय एक छिपा हुआ बटन जोड़ा। हैक के लिए क्षमा करें।


1
+1 के साथ सेट किया गया संदर्भ setTargetFragment()सिस्टम द्वारा सही ढंग से फिर से बनाया गया है जब यह रोटेशन के बाद गतिविधि / फ्रैगमेंट सेट को पुनरारंभ करता है। तो संदर्भ नए लक्ष्य को स्वचालित रूप से इंगित करेगा।
रिचर्ड ले मेसियर

मैं अपने आप को नाक में अब दिन में वापस बटरकॉइन का उपयोग नहीं करने के लिए पंच करूंगा। ButterKnife का प्रयोग करें, यह आपके विचार को बहुत सुंदर बनाता है।
एपिकपांडाफॉर्स

और आप Fragment से Activity तक घटना भेजने के लिए ओटो का उपयोग कर सकते हैं, ताकि आपको इंटरफ़ेस अटैच जादू की आवश्यकता न हो। ओटो का उदाहरण यहां: stackoverflow.com/a/28480952/2413303
एपिकपांडाफार्स

@EpicPandaForce कृपया, क्या आप "ShowDialog" इंटरफ़ेस / वर्ग जोड़ सकते हैं? यह केवल आपके उदाहरण में गायब है।
ntrch

@ यह थाpublic interface ShowDialog { void showDialog(DialogFragment dialogFragment); }
इपिक पांडाफर्स

3
 public void showAlert(){


     AlertDialog.Builder alertDialog = new AlertDialog.Builder(getActivity());
     LayoutInflater inflater = getActivity().getLayoutInflater();
     View alertDialogView = inflater.inflate(R.layout.test_dialog, null);
     alertDialog.setView(alertDialogView);

     TextView textDialog = (TextView) alertDialogView.findViewById(R.id.text_testDialogMsg);
     textDialog.setText(questionMissing);

     alertDialog.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
         public void onClick(DialogInterface dialog, int which) {
             dialog.cancel();
         }
     });
     alertDialog.show();

}

जहाँ .test_dialog xml कस्टम का है


2

मैं खुद एक शुरुआत हूं और मैं ईमानदारी से एक संतोषजनक जवाब नहीं पा सका हूं जिसे मैं समझ सकता हूं या लागू कर सकता हूं।

तो यहाँ एक बाहरी लिंक है जो मैंने वास्तव में मुझे वह हासिल करने में मदद की जो मैं चाहता था। यह बहुत सीधे आगे है और साथ ही पालन करने में आसान है।

http://www.helloandroid.com/tutorials/how-display-custom-dialog-your-android-application

मुझे इस कोड के साथ प्राप्त करने की क्या आवश्यकता है:

मेरे पास एक MainActivity है जो एक Fragment को होस्ट करती है। मैं चाहता था कि उपयोगकर्ता इनपुट के लिए लेआउट के शीर्ष पर एक संवाद दिखाई दे और फिर उसी के अनुसार इनपुट को संसाधित करें। एक स्क्रीनशॉट देखें

यहाँ मेरे टुकड़े का onCreateView क्या दिखता है

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragment_home_activity, container, false);

    Button addTransactionBtn = rootView.findViewById(R.id.addTransactionBtn);

    addTransactionBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Dialog dialog = new Dialog(getActivity());
            dialog.setContentView(R.layout.dialog_trans);
            dialog.setTitle("Add an Expense");
            dialog.setCancelable(true);

            dialog.show();

        }
    });

मुझे आशा है कि यह आपकी मदद करेगा

अगर कोई गड़बड़ है तो मुझे बताएं। :)


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.