11

एक टुकड़ा है कि टैबलेट पर यह एक DialogFragment के रूप में दिखाता है, जबकि स्मार्टफोन पर यह एक नियमित रूप से टुकड़ा रूप में दिखाया जाएगा करने के लिए मैं क्या हासिल करने की कोशिश कर रहा हूँ। मुझे पता है कि पहले से ही similar post है, लेकिन मैं यह काम नहीं कर पा रहा हूं - शैली को टुकड़े में लागू करें।एंड्रॉयड टुकड़ा शो dialogfragment या हमेशा की तरह टुकड़ा के रूप में

दिखाने के लिए बातें, नीचे ऊपर MainActivity.java:

public class DetailedActivity extends ActionBarActivity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.detailed_activity); 
    } 
} 

अपने लेआउट:

<fragment xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/root_container" 
    android:name="com.myapps.sampleandroid.DetailedFragment" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 

और दिलचस्प DetailedFragment:

public class MainActivity extends ActionBarActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     if (item.getItemId() == R.id.action_next) { 
      decideToNext(); 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    private void decideToNext() { 
     String device = getString(R.string.device); 
     if ("normal".equalsIgnoreCase(device)) { 
      Intent intent = new Intent(this, DetailedActivity.class); 
      startActivity(intent); 
     } else if ("large".equalsIgnoreCase(device)) { 
      Log.d("SOME_TAG", "Yes, I am seeing this line on tablet only"); 
      DetailedFragment fragment = DetailedFragment.newInstance(); 
      getSupportFragmentManager().beginTransaction().add(fragment, "MAGIC_TAG").commit(); 
     } 
    } 

} 

DetailedActivity ज्यादा कुछ भी नहीं है

public class DetailedFragment extends Fragment { 

    public static DetailedFragment newInstance() { 
     return new DetailedFragment(); 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     Context contextThemeWrapper = new ContextThemeWrapper(getActivity(), R.style.MyDialogTheme); 
     LayoutInflater localInflater = inflater.cloneInContext(contextThemeWrapper); 
     return localInflater.inflate(R.layout.detailed_fragment, container, false); 
    } 
} 

... और उसके लेआउट:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 

    <TextView 
     android:id="@+id/textView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Regular Text" /> 

    <TextView 
     android:id="@+id/textView2" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Large Text" 
     android:textAppearance="?android:attr/textAppearanceLarge" /> 

    <Button 
     android:id="@+id/button1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Button Dummy" /> 

</LinearLayout> 

onCreateView में मैं कस्टम स्टाइल सेट करने की कोशिश की है, लेकिन यह टैबलेट के लिए काम करने के लिए प्रतीत नहीं होता।

स्टाइलिंग

res/values ​​/ styles.xml शामिल हैं:

<resources> 

    <style name="AppTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar"> 
    </style> 

    <style name="MyDialogTheme" /> 

</resources> 

जबकि res/values-बड़े/styles.xml:

<resources> 
    <!-- Is there anything I should add here? --> 
    <style name="MyDialogTheme" parent="@android:style/Theme.Dialog"/> 
</resources> 

मैं MyDialogTheme नेस्ट किया है Theme.Dialog से, लेकिन यह मदद नहीं लगता है।

स्मार्टफोन पर जब "अगला" क्रिया बार मेनू आइटम मैं विस्तृत गतिविधि देख रहा हूँ (एक SG2 से स्नैपशॉट) पर दोहन: snapshot from an SG2

जबकि गोली ऐसा नहीं से एक ही "अगला" मेनू आइटम पर दोहन कुछ भी नहीं (Logcat पर संदेश देखने के अलावा: Yes, I am seeing this line)। enter image description here

टैबलेट के लिए एक संवाद के रूप में DetailedFragment देखने के लिए मुझे शैलियों.एक्सएमएल या कोड में और क्या जोड़ना चाहिए?

संपादित

मैं समाधान छोटा बच्चा प्रस्तावित की कोशिश की है (एक DialogFragment मेरी प्रारंभिक खंड और यह दिखाने के लिए)।तो, मैं जोड़ दिया है एक WrapperDetailedFragment:

public class WraperDetailedFragment extends DialogFragment { 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.wrap_detailed_fragment, container, false); 
    } 
} 

अपने लेआउट:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/root_container_dialog" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 

    <fragment 
     android:id="@+id/wrapped_fragment_id" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     class="com.myapps.sampleandroid.DetailedFragment" /> 

</LinearLayout> 

MainActivity से कोड में परिवर्तन:

private void decideToNext() { 
    String device = getString(R.string.device); 
    if ("normal".equalsIgnoreCase(device)) { 
     Intent intent = new Intent(this, DetailedActivity.class); 
     startActivity(intent); 
    } else if ("large".equalsIgnoreCase(device)) { 
     Log.d("SOME_TAG", "Yes, I am seeing this line ..."); 
     WraperDetailedFragment fragment = new WraperDetailedFragment(); 
     fragment.show(getSupportFragmentManager(), "MAGICAL_TAG"); 
    } 
} 

लेकिन जब मैं इस DialogFragment जोड़ने के लिए कोशिश कर रहा हूँ मुझे निम्न क्रैश मिल रहा है:

android.view.InflateException: Binary XML file line #8: Error inflating class fragment 
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704) 
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:746) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java:489) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java:396) 
    at com.myapps.sampleandroid.WraperDetailedFragment.onCreateView(WraperDetailedFragment.java:12) 
    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1478) 
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927) 
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1082) 
    at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:304) 
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:676) 
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:746) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java:489) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java:396) 
    at com.myapps.sampleandroid.WraperDetailedFragment.onCreateView(WraperDetailedFragment.java:12) 
    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1478) 
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927) 
    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104) 
    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682) 
    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1460) 
    at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440) 
    at android.os.Handler.handleCallback(Handler.java:615) 
    at android.os.Handler.dispatchMessage(Handler.java:92) 
    at android.os.Looper.loop(Looper.java:137) 
    at android.app.ActivityThread.main(ActivityThread.java:4745) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:511) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
    at dalvik.system.NativeStart.main(Native Method) 
Caused by: java.lang.IllegalArgumentException: Binary XML file line #8: Duplicate id 0x7f050047, tag null, or parent id 0x0 with another fragment for com.myapps.sampleandroid.DetailedFragment 
    at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:290) 
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:676) 
    ... 28 more 

उत्तर

21

यह समस्या आसानी से ठीक किया जा सकता में इस बढ़ बजाय एक DialogFragment मैं विपरीत कोण से विचार करेंगे की तरह एक Fragment देखो बनाने की कोशिश कर के यदि: एक Fragment की तरह एक DialogFragment देखो बनाने - सब के बाद, एक DialogFragment है एक Fragment!

public class DetailedFragment extends DialogFragment { 

    private static final String ARG_SHOW_AS_DIALOG = "DetailedFragment.ARG_SHOW_AS_DIALOG"; 

    public static DetailedFragment newInstance(boolean showAsDialog) { 
     DetailedFragment fragment = new DetailedFragment(); 
     Bundle args = new Bundle(); 
     args.putBoolean(ARG_SHOW_AS_DIALOG, showAsDialog); 
     fragment.setArguments(args); 
     return fragment; 
    } 

    public static DetailedFragment newInstance() { 
     return newInstance(true); 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     Bundle args = getArguments(); 
     if (args != null) { 
      setShowsDialog(args.getBoolean(ARG_SHOW_AS_DIALOG, true)); 
     } 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.detailed_fragment, container, false); 
    } 
} 

अपने लेआउट बनी हुई है के रूप में यह था, DetailedActivity परिवर्तन करने के लिए:

public class DetailedActivity extends ActionBarActivity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.detailed_activity); 
     if (savedInstanceState == null) { 
      DetailedFragment fragment = DetailedFragment.newInstance(false); 
      getSupportFragmentManager().beginTransaction().add(R.id.root_layout_details, fragment, "Some_tag").commit(); 
     } 
    } 
} 

यह सुधार के प्रमुख कॉल करने के लिए है या नहीं DialogFragment.setShowsDialog();

तो DetailedFragment के लिए बदल रहा है इसके लेआउट के साथ-साथ:

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

और फोन करने वाले गतिविधि केवल करता है:

private void decideToNext() { 
    String device = getString(R.string.device); 
    if ("normal".equalsIgnoreCase(device)) { 
     Intent intent = new Intent(this, DetailedActivity.class); 
     startActivity(intent); 
    } else if ("large".equalsIgnoreCase(device)) { 
     DetailedFragment fragment = DetailedFragment.newInstance(); 
     fragment.show(getSupportFragmentManager(), "Tablet_specific"); 
    } 
} 
1

ठीक है, मैं वहां गया हूं और ऐसा किया है। DialogFragment बनाने के लिए आपको XML में परिभाषित एक लेआउट की आवश्यकता है। कहें, इसके लिए आपके पास रूट के रूप में LinearLayout है। इस LinearLayout में आप fragment class="...." जोड़ सकते हैं और जब आप अपना DialogFragment प्रदर्शित करते हैं, तो यह Fragment होगा जो आपने टैबलेट पर एक तरफ प्रदर्शित किया है जो अब DialogFragment में प्रदर्शित होता है।

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> 
<fragment class="com.example.tqafragments.FeedFragment" android:id="@+id/feedFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1"/> 
</LinearLayout> 

ऐसा ही। और अपने DialogFragment

+0

मुझे नहीं लगता कि आप इस प्रश्न को समझ गए हैं: मुझे टेबलेट के लिए 'डायलॉग फ्रैगमेंट' के रूप में प्रदर्शित होने के लिए एक टुकड़ा की आवश्यकता है, लेकिन एक ही टुकड़ा स्मार्टफोन के लिए एक गैर-संवाद प्रारूप होना चाहिए।आपके द्वारा प्रदान किया गया जवाब दिखाता है कि एक टुकड़ा कैसे प्रदर्शित करें - वैसे भी, मुझे लगता है कि यदि आप 'फीडफ्रैगमेंट' एक 'डायलॉगफ्रैगमेंट' है, तो आपको 'अवैध अर्ग्यूमेंट अपवाद' मिलेगा: 'डायलॉग फ्रैगमेंट' को कंटेनर व्यू से जोड़ा नहीं जा सकता है। रूट बनाने के बाद एक डायलॉग फ्रैगमेंट केवल फ्रैगमेंट ट्रान्सेशन ऐड/प्रतिस्थापन विधि के माध्यम से जोड़ा जा सकता है। – gunar

+0

बिलकुल नहीं। आपको छोटे फोन और टैबलेट के लिए अलग-अलग लेआउट को परिभाषित करना होगा। मुझे उम्मीद है कि आप जानते हैं कि आप ऐसा कर सकते हैं :) गोलियों के लिए, टुकड़े साइड-बाय-साइड प्रदर्शित किए जाएंगे। जो आपने याद किया वह है .. 'डायलॉग फ्रैगमेंट' ** में **' फ्रैगमेंट 'होगा। –

+0

तो अगर मैं आपको सही समझता हूं: आप एक संवादप्रवाह बनाने का सुझाव दे रहे हैं और इसके अंदर मैं फ्रेगमेंट दिखाने में रूचि रखता हूं? – gunar

1

एक नियमित Fragment के रूप में एक DialogFragment शो बनाने के लिए, टुकड़ा कंटेनर के लिए एक संसाधन आईडी का उपयोग कर add() या replace() फोन, जैसे

beginTransaction().add(R.id.fragment_container, fragment) 

लेकिन डायलॉगफ्रेगमेंट को एक संवाद के रूप में प्रदर्शित करने के लिए, add(fragment, "Fragment Tag") पर कॉल करें। दृश्यों के पीछे add(resId, fragment) पर कॉल के परिणामस्वरूप, 0 के लिए DialogFragment को showAsDialog विकल्प को सही करने के लिए DialogFragment का कारण बनता है।

परिणामस्वरूप आप एक संवाद के रूप में एक संवाद खंड या नियमित टुकड़े का उपयोग कर सकते हैं - आपकी आवश्यकताओं के आधार पर - इसे करने के लिए कोई विशेष तर्क बनाने की आवश्यकता के बिना।

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