Il frammento di Android viene visualizzato come dialogfragment o frammento normale

Quello che sto cercando di ottenere è di avere un frammento che sul tablet mostri come un DialogFragment , mentre sullo smartphone dovrebbe essere mostrato come un normale frammento. Sono consapevole che esiste già un post simile , ma non sono in grado di farlo funzionare, applicare lo stile al frammento.

Per mostrare le cose dall’alto in basso, MainActivity.java:

 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 non è molto:

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

il suo layout:

  

e l’interessante DetailedFragment :

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

… e il suo layout:

    

In onCreateView ho provato a impostare lo stile personalizzato ma non sembra funzionare per tablet.

Messa in piega

res / values ​​/ styles.xml contiene:

      

while res / values-large / styles.xml:

     

Ho nidificato MyDialogTheme da Theme.Dialog , ma non sembra aiutare.

Su smartphone quando si tocca la voce del menu della barra delle azioni “SUCCESSIVO” Vedo l’attività dettagliata (istantanea da un SG2): istantanea da un SG2

mentre tocca la stessa voce di menu “NEXT” dal tablet non fa nulla (eccetto la visualizzazione del messaggio su Logcat: Yes, I am seeing this line ). inserisci la descrizione dell'immagine qui

Cosa dovrei aggiungere di più in styles.xml o nel codice per vedere DetailedFragment come una finestra di dialogo per tablet?

MODIFICARE

Ho provato la soluzione proposta da Little Child (per avere un DialogFragment contiene il mio frammento iniziale e mostrarlo). Quindi, ho aggiunto un 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); } } 

il suo layout:

    

Il codice da MainActivity cambia in:

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

ma quando sto cercando di aggiungere questo DialogFragment sto ottenendo il seguente crash:

 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 

Questo problema può essere risolto facilmente se invece di cercare di far apparire un Fragment come un DialogFragment , guarderei dall’angolo opposto: fai sembrare un Fragment DialogFragment come un Fragment – dopotutto, un DialogFragment è un Fragment !

La chiave di questa correzione è chiamare o non DialogFragment.setShowsDialog();

Quindi, cambiando il DetailedFragment a:

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

il suo layout rimane come era, DetailedActivity cambia in:

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

il suo layout pure:

  

e l’attività del chiamante fa solo:

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

OK, ci sono stato e l’ho fatto. Per creare un DialogFragment è necessario un layout definito in XML. Dì, per questo hai LinearLayout come root. In questo LinearLayout puoi aggiungere una fragment class="...." e quando visualizzi il tuo DialogFragment , sarà lo stesso Fragment hai visualizzato fianco a fianco sul tablet ora visualizzato in un DialogFragment .

    

Così. E DialogFragment nel tuo DialogFragment

Per visualizzare un object DialogFragment come un normale Fragment , chiama add() o replace() utilizzando un ID risorsa per il contenitore dei frammenti, ad esempio

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

Ma per visualizzare DialogFragment come una finestra di dialogo, chiama add(fragment, "Fragment Tag") . Dietro le quinte ciò comporta una chiamata da add(resId, fragment) , impostando l’ID risorsa per il contenitore del frammento su 0, che fa sì che DialogFragment imposti l’opzione showAsDialog su true.

Di conseguenza è ansible utilizzare un frammento di dialogo come una finestra di dialogo o un normale frammento, a seconda delle esigenze, senza la necessità di creare alcuna logica speciale per farlo.