2013-02-01 15 views
5

से बुलाया जाता है, तो मेरा डायलॉग फ्रैगमेंट क्लासकास्ट एक्सेप्शन फ्रेगमेंट से बुलाया जाता है, जबकि यह सामान्य रूप से गतिविधि से बुलाया जाता है। मैंने पहले ही इसी तरह की समस्या के साथ कुछ अन्य प्रश्नों को देखा है और मूल रूप से वे आयात से संबंधित हैं, लेकिन मैं इसे अपने कार्यान्वयन में हल करने में सक्षम नहीं हूं। डायलॉग फ्रैगमेंट के लिए मेरा कार्यान्वयन यहां दिया गया है।डायलॉग फ्रैगमेंट क्लासकास्टएक्सप्शन को फ्रेगमेंट

02-01 13: 11: 32.750: ई/AndroidRuntime (

 
import android.app.AlertDialog; 
import android.app.DialogFragment; 
import android.support.v4.app.Fragment; 
import com.xxx.yyy.ui.compontent.dialog.HotspotScanDialog; 
import com.xxx.yyy.ui.compontent.dialog.HotspotScanDialog.SetupHotspotDialogListener; 

public class SmartMode extends Fragment implements SetupHotspotDialogListener { 

    private void showWifiSelectionDialog() { 
     DialogFragment setupWifiSelectionDialog = new HotspotScanDialog(); 

     /* 
     * using getFragmentManager() only says "The method 
     * show(FragmentManager, String) in the type DialogFragment is not 
     * applicable for the arguments (FragmentManager, String)" 
     */ 

     setupWifiSelectionDialog.show(getActivity().getFragmentManager(), 
       Keys.TAG.toString()); 
    } 

    @Override 
    public void onHotspotSelectedListener(String selection) { 
     // Log.d(TAG,selection); 
    } 
} 

यह त्रुटि लॉग है:

 
import android.app.AlertDialog; 
import android.app.Dialog; 
import android.app.DialogFragment; 

public class HotspotScanDialog extends DialogFragment { 

    SetupHotspotDialogListener mListener; 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     ... 

     .setAdapter(hotspotAdapter, new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       mListener.onHotspotSelectedListener(hotspotAdapter.getItem(
         which).toString()); 
      } 
     })... 
    } 

    public interface SetupHotspotDialogListener { 
     public void onHotspotSelectedListener(String selection); 

    } 

    @Override 
    public void onAttach(Activity activity) { 
     super.onAttach(activity); 

     try { 
      mListener = (SetupHotspotDialogListener) activity; 
     } catch (ClassCastException ignore) { 
      // Just to make sure if anyone will be pointing at my throwing 
      // ClassCastException myself I have tried without this code as well. 
      throw new ClassCastException(activity.toString() 
        + " must implement NoticeDialogListener"); 
     } 
    } 
} 

यहाँ मेरी टुकड़ा है कि ऊपर DialogFragment उपयोग कर रहा है 15061): अंतिम अपवाद: मुख्य 02-01 13: 11: 32.750: ई/एंड्रॉइड रनटाइम (15061): java.lang.ClassCastException: [email protected] को नोटिसडिअलॉग लिस्टनर 02-01 13:11 लागू करना होगा: 32.750: ई/एन droidRuntime (15061): com.xxx.yyy.ui.compontent.dialog.HotspotScanDialog.onAttach (HotspotScanDialog.java:122) 02-01 13: 11: 32.750: ई/एंड्रॉइड रनटाइम (15061): android.app पर। FragmentManagerImpl.moveToState (FragmentManager.java:787) 02-01 13: 11: 32.750: ई/एंड्रॉइड रनटाइम (15061): android.app.FragmentManagerImpl.moveToState (FragmentManager.java:1035) 02-01 13:11: 32.750: ई/AndroidRuntime (15061): पर android.app.BackStackRecord.run (BackStackRecord.java:635) 02-01 13: 11: 32.750: ई/AndroidRuntime (15061): android.app.FragmentManagerImpl.execPendingActions पर (FragmentManager.java:1397) 02-01 13: 11: 32.750: ई/एंड्रॉइड रनटाइम (15061): android.app.FragmentManagerImpl $ 1.run (FragmentManager.java:426) 02-01 13: 11: 32.750: E/एंड्रॉइड रनटाइम (15061): android.os.Handler.handleCallback पर (हैंडलर.जावा:615) 02-01 13: 11: 32.750: ई/AndroidRuntime (15061): android.os.Handler.dispatchMessage (Handler.java:92) पर 02-01 13: 11: 32.750: ई/AndroidRuntime (15061): में android.os.Looper.loop (Looper.java:137) 02-01 13: 11: 32.750: ई/AndroidRuntime (15061): android.app.ActivityThread.main (ActivityThread.java:4898) पर 02-01 13: 11: 32.750: ई/AndroidRuntime (15061): 11:: 32.750: ई/AndroidRuntime (15061): java.lang.reflect पर java.lang.reflect.Method.invokeNative (मूल निवासी विधि) 02-01 13 पर .Method.invoke (Method.java:5211) 02-01 13: 11: 32.750: ई/एंड्रॉइड रनटाइम (15061): com.android.internal.os.ZygoteInit $ methodAndArgsCaller.run (ZygoteInit.java:1006) 02-01 13: 11: 32.750: ई/AndroidRuntime (15061): 11:: 32.750: ई/एंड्रॉयड com.android.internal.os.ZygoteInit.main (ZygoteInit.java:773) 02-01 13 पर रनटाइम (15061): dalvik.system.NativeStart.main (मूल विधि)

मुझे आश्चर्य है कि कोई भी इस मुद्दे के बारे में संकेत दे सकता है।

उत्तर

10

docs से:

onAttach(Activity) called once the fragment is associated with its activity. 

अपने कोड में

mListener = (SetupHotspotDialogListener) activity; 

लाइन ClassCastException फेंकता है क्योंकि अपनी गतिविधि SetupHotspotDialogListener इंटरफ़ेस को लागू नहीं है। (Fragment सीधे उस गतिविधि से जुड़ा हुआ है जिसमें DialogFragment है क्योंकि DialogFragmentFragment बढ़ाता है)।

docs

In some cases, you might need a fragment to share events with the activity. A good way to do that is to define a callback interface inside the fragment and require that the host activity implement it. When the activity receives a callback through the interface, it can share the information with other fragments in the layout as necessary.

तो आप बनाना चाहते हैं, तो से फिर

FragmentDialogFragment से मैं गतिविधि के लिए कॉलबैक के माध्यम से इसे व्यवस्थित करने के लिए सुझाव:

  1. अपने SmartModeFragment वर्ग में कॉलबैक इंटरफ़ेस बनाने (जैसा कि आप संवाद में करते हैं) createDialogRequest() जैसे एक विधि के साथ।
  2. अपनी गतिविधि है कि इंटरफ़ेस
  3. लागू तब, जब आप संवाद बनाने के लिए, Activity

में "शो संवाद लॉजिक्स" FragmentActivity

  • जगह से कॉलबैक भेजने की जरूरत है यह गतिविधि पूछना टुकड़ा की तरह लग रहा है चलो संवाद बनाने के लिए, गतिविधि संवाद दिखाता है।

    संपादित: मुझे लगता है कि आपको जो चाहिए उसे बेहतर कार्यान्वयन मिला है। मैंने fragment dialog कॉलबैक घटनाओं को खंड में प्राप्त करने के साथ fragment dialog को टुकड़े से बनाने का एक सरल उदाहरण लिखा है।

    गतिविधि:

    public class MyFragmentActivity extends FragmentActivity { 
    
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_my_fragment); 
    
        // first start of activity 
        if (savedInstanceState == null) { 
         // put fragment to activity layout 
         MyFragment fragment = new MyFragment(); 
         FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
         ft.replace(R.id.fragmentContainer, fragment, "fragment"); 
         ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
         ft.commit(); 
        } 
    }} 
    

    टुकड़ा:

    public class MyFragment extends Fragment implements MyDialogInterface { 
    
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
        super.onCreateView(inflater, container, savedInstanceState); 
    
        View fragmentView = inflater.inflate(R.layout.fragment, null); 
    
        // button which shows dialog 
        Button showDialogButton = (Button) fragmentView.findViewById(R.id.showDialog); 
        showDialogButton.setOnClickListener(new OnClickListener() { 
    
         @Override 
         public void onClick(View v) { 
          // create fragment dialog. 
          FragmentDialog dialog = FragmentDialog.getInstance(MyFragment.this); 
          dialog.show(getActivity().getSupportFragmentManager(), "dialog"); 
         } 
        }); 
        return fragmentView; 
    } 
    
    @Override 
    public void onClickEvent() { 
        // receive click events from dialog fragment 
        Log.e(getClass().getSimpleName(), "onClickEvent"); 
    } 
    

    }

    FragmentDialog:

    public class FragmentDialog extends DialogFragment { 
    
    public interface MyDialogInterface extends Serializable { 
        public void onClickEvent(); 
    } 
    
    private MyDialogInterface callbackListener; 
    
    /** 
    * dialogInterface - instance of MyDialogInterface which will handle 
    * callback events 
    */ 
    public static FragmentDialog getInstance(MyDialogInterface dialogInterface) { 
        FragmentDialog fragmentDialog = new FragmentDialog(); 
    
        // set fragment arguments 
        Bundle args = new Bundle(); 
        args.putSerializable("dialogInterface", dialogInterface); 
        fragmentDialog.setArguments(args); 
    
        return fragmentDialog; 
    } 
    
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setStyle(STYLE_NO_TITLE, 0); 
    } 
    
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    
        View pushDialogView = getActivity().getLayoutInflater().inflate(R.layout.fragment_dialog, null); 
    
        // get reference to MyDialogInterface instance from arguments 
        callbackListener = (MyDialogInterface) getArguments().getSerializable("dialogInterface"); 
    
        Button cancelButton = (Button) pushDialogView.findViewById(R.id.button); 
        cancelButton.setOnClickListener(new OnClickListener() { 
         @Override 
         public void onClick(View v) { 
          // send click event 
          callbackListener.onClickEvent(); 
         } 
        }); 
    
        return pushDialogView; 
    }} 
    

    मैं समर्थन 4 पुस्तकालय टुकड़े (android.support.v4.app.Fragment, 012 का इस्तेमाल किया, android.support.v4.app.FragmentActivity)।

    और लेआउट:

    activity_my_fragment.xml:

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/fragmentContainer" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 
    

    fragment.xml:

    <?xml version="1.0" encoding="utf-8"?> 
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#a00" 
    android:orientation="vertical" > 
    <Button 
        android:id="@+id/showDialog" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="show doalog" /> 
    </LinearLayout> 
    

    fragment_dialog.xml:

    <?xml version="1.0" encoding="utf-8"?> 
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="#fe3" 
    android:orientation="vertical" > 
    
    <Button 
        android:id="@+id/button" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="click me" /> 
    </LinearLayout> 
    

    विचार इंटरफेस को संदर्भ भेजना है जो कॉलबैक घटनाओं को पकड़ लेगा।

  • +0

    यदि आप मेरे कोड पर उचित रूप से देखते हैं तो यह स्पष्ट रूप से कहता है "पब्लिक क्लास स्मार्टमोड फ्रैगमेंट लागू करता है SetupHotspotDialogListener"। यह कोड गतिविधि के साथ पूरी तरह से काम करता है और यह कॉलबैक इंटरफ़ेस भी कार्यान्वित किया जाता है। क्या आपका मतलब है कि मुझे इन टुकड़ों को होस्ट करने वाली मुख्य गतिविधि इंटरफ़ेस को कार्यान्वित करना है? – Milan

    +0

    जो मैंने सोचा था, वह उत्साहजनक नहीं था, लेकिन उन टुकड़ों को होस्ट करने वाली गतिविधि में उन इंटरफेस को लागू करने से मेरी समस्या हल हो गई। हालांकि यह सीमित हो सकता है यदि आप उस संवाद को बुलाए गए वास्तविक खंड में संवाद सूची प्राप्त करने का प्रयास कर रहे हैं। संकेत के लिए वैसे भी धन्यवाद। – Milan

    +1

    मैंने अपना जवाब संपादित कर लिया है।मुझे लगता है कि मेरे उत्तर का पहला भाग सबसे अच्छा समाधान नहीं है। –

    संबंधित मुद्दे