2012-02-09 18 views
12

He intentado actualizar mi aplicación y continuar con los fragmentos, la barra de acción y todas las demás características de la interfaz de usuario que me estoy perdiendo. I entiendo que puedo tener múltiples fragmentos en una actividad, tengo diseños diferentes basados ​​en el dispositivo y todas esas cosas buenas, pero Tengo problemas para obtener algunas pestañas de la manera que quiero. I entiendo cómo agregar pestañas, cambiando entre ellas, pero ¿cómo tengo más de un fragmento en una pestaña? Así que, por ejemplo, tengo esencialmente dos pantallas Quiero que el usuario pueda cambiar fácilmente de (por qué quiero usar pestañas). Si tengo dos actividades separadas que puede especificar esto en archivos XML y utilizar setContentView usando los diseños debajoActionBar Tabs con múltiples fragmentos

tab1_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 
    <fragment 
     android:name="com.example.tabrefactor.Fragment1" 
     android:id="@+id/fragment_1" 
     android:layout_height="wrap_content" 
     android:layout_width="wrap_content"/> 
    <fragment 
     android:name="com.example.tabrefactor.Fragment2" 
     android:id="@+id/fragment_2" 
     android:layout_height="wrap_content" 
     android:layout_width="wrap_content"/> 
    <fragment 
     android:name="com.example.tabrefactor.Fragment3" 
     android:id="@+id/fragment_3" 
     android:layout_height="wrap_content" 
     android:layout_width="wrap_content"/> 
</LinearLayout> 

tab2_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 
    <fragment 
     android:name="com.example.tabrefactor.Fragment4" 
     android:id="@+id/fragment_4" 
     android:layout_height="wrap_content" 
     android:layout_width="wrap_content"/> 
</LinearLayout> 

puedo convertir el segundo diseño para usar pestañas ya que solo contiene un fragmento pero no estoy seguro de cómo obtener el primer diseño en una única pestaña . ¿Es eso algo permitido? Gracias de antemano,

Jason Prenger

+0

También se discutió en http://groups.google.com/group/android-developers/browse_thread/thread/f74d80f1b11e3cb3/8e 15c70ce86a4041 # 8e15c70ce86a4041 – StackJP

Respuesta

6

Voy a dejar esta cuestión en caso que alguien tiene una simplificación o una idea mejor ...

Con el tiempo se fue con una solución de tener un diseño de base con 3 diseños de trama ...

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

    <FrameLayout 
     android:id="@+id/fragment_sb" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content"/> 
    <FrameLayout 
     android:id="@+id/fragment_local" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content"/> 
    <FrameLayout 
     android:id="@+id/fragment_rest" 
     android:layout_width="fill_parent" 
     android:layout_height="0dp" 
     android:layout_weight="1"/> 

</LinearLayout> 

Luego en mi actividad con las pestañas hice un TabListener personalizado que manejaba los cambios entre. El código que he utilizado es inferior a (estoy usando ActionBarSherlock lo que va a tener un aspecto ligeramente diferente de las cosas normales)

public class TabActivity extends FragmentActivity { 

    Fragment1 fragment1; 
    Fragment2 fragment2; 
    Fragment3 fragment3; 
    Fragment4 fragment4; 

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

     final ActionBar bar = getSupportActionBar(); 
     bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 
     bar.setDisplayShowTitleEnabled(true); 
     bar.setDisplayShowHomeEnabled(false); 
     bar.setTitle("Title"); 

     bar.addTab(bar.newTab() 
       .setIcon(R.drawable.ic_list_tab_selected) 
       .setTabListener(new ListTabListener(this))); 
     bar.addTab(bar.newTab() 
       .setIcon(R.drawable.ic_map_tab_selected) 
       .setTabListener(new MapTabListener(this))); 

     if (savedInstanceState != null) { 
      bar.setSelectedNavigationItem(savedInstanceState.getInt("tab", 0)); 
     } 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putInt("tab", getSupportActionBar().getSelectedNavigationIndex()); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.test_menu, menu); 

     return super.onCreateOptionsMenu(menu); 
    } 

    public static class ListTabListener implements ActionBar.TabListener { 
     private static final String fragment1Tag = "fragment1_tag"; 
     private static final String fragment2Tag = "fragment2_tag"; 
     private static final String fragment3Tag = "fragment3_tag"; 

     private FragmentActivity activity; 
     private Fragment1 fragment1; 
     private Fragment2 fragment2; 
     private Fragment3 fragment3; 

     public ListTabListener(FragmentActivity activity) { 
      this.activity = activity; 

      FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction(); 
      fragment1 = (Fragment1) activity.getSupportFragmentManager().findFragmentByTag(fragment1Tag); 
      if (fragment1 != null && !fragment1.isDetached()) { 
       ft.detach(fragment1); 
      } 

      fragment2 = (Fragment2) activity.getSupportFragmentManager().findFragmentByTag(fragment1Tag); 
      if (fragment2 != null && !fragment2.isDetached()) { 
       ft.detach(fragment2); 
      } 

      fragment3 = (Fragment3) activity.getSupportFragmentManager().findFragmentByTag(fragment1Tag); 
      if (fragment3 != null && !fragment3.isDetached()) { 
       ft.detach(fragment3); 
      } 

      ft.commit(); 
     } 

     @Override 
     public void onTabReselected(Tab tab, FragmentTransaction nullFt) { 
      //Reselected don't do anything   
     } 

     @Override 
     public void onTabSelected(Tab tab, FragmentTransaction nullFt) { 
      FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction(); 

      if(fragment1 == null) { 
       fragment1 = new Fragment1(); 
       ft.add(R.id.fragment_sb, fragment1, fragment1Tag); 
      } else { 
       ft.attach(fragment1); 
      } 

      if(fragment2 == null) { 
       fragment2 = new Fragment2(); 
       ft.add(R.id.fragment_local, fragment2, fragment2Tag); 
      } else { 
       ft.attach(fragment2); 
      } 

      if(fragment3 == null) { 
       fragment3 = new Fragment3(); 
       ft.add(R.id.fragment_rest, fragment3, fragment3Tag); 
      } else { 
       ft.attach(fragment3); 
      } 

      ft.commit(); 
     } 

     @Override 
     public void onTabUnselected(Tab tab, FragmentTransaction nullFt) { 
      FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction(); 

      if(fragment1 != null) 
       ft.detach(fragment1); 
      if(fragment2 != null) 
       ft.detach(fragment2); 
      if(fragment3 != null) 
       ft.detach(fragment3); 

      ft.commit(); 
     } 
    } 

    public static class MapTabListener implements ActionBar.TabListener { 
     private static final String fragment4Tag = "fragment4_tag"; 

     private FragmentActivity activity; 
     private Fragment4 fragment4; 

     public MapTabListener(FragmentActivity activity) { 
      this.activity = activity; 

      FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction(); 
      fragment4 = (Fragment4) activity.getSupportFragmentManager().findFragmentByTag(fragment4Tag); 
      if (fragment4 != null && !fragment4.isDetached()) { 
       ft.detach(fragment4); 
      } 
      ft.commit(); 
     } 

     @Override 
     public void onTabReselected(Tab tab, FragmentTransaction nullFt) { 
      //Reselected don't do anything   
     } 

     @Override 
     public void onTabSelected(Tab tab, FragmentTransaction nullFt) { 
      FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction(); 

      if(fragment4 == null) { 
       fragment4 = new Fragment4(); 
       ft.add(R.id.fragment_rest, fragment4, fragment4Tag); 
      } else { 
       ft.attach(fragment4); 
      } 

      ft.commit(); 
     } 

     @Override 
     public void onTabUnselected(Tab tab, FragmentTransaction nullFt) { 
      FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction(); 

      if(fragment4 != null) 
       ft.detach(fragment4); 

      ft.commit(); 
     } 
    } 
} 
+0

Sí ... No estoy muy contento con este enfoque ... pero es básicamente en lo que aterricé ... Ojalá los fragmentos anidados fueran mejor compatibles ... entonces cada pestaña podría ser un fragmento que a su vez podría gestionar sus fragmentos componentes en el diseño que desee .... – danb

1

Aquí está mi solución:

import java.util.ArrayList; 
import library.DatabaseHandler; 
import org.json.JSONObject; 
import android.app.ActionBar; 
import android.app.ActionBar.Tab; 
import android.app.AlertDialog; 
import android.app.Dialog; 
import android.app.ProgressDialog; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuInflater; 
import android.view.MenuItem; 
import android.view.MenuItem.OnMenuItemClickListener; 
import android.view.View.OnClickListener; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.Switch; 
import android.widget.TextView; 
import android.widget.Toast; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.FragmentPagerAdapter; 
import android.support.v4.app.FragmentTransaction; 
import android.support.v4.view.ViewPager; 
import android.support.v4.view.ViewPager.OnPageChangeListener; 

public class Polling extends FragmentActivity { 
    private ViewPager mViewPager; 
    private TabsAdapter mTabsAdapter; 

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    mViewPager = new ViewPager(this); 
    mViewPager.setId(R.id.pager); 
    setContentView(mViewPager); 
    final ActionBar bar = getActionBar(); 
    bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 
    bar.setDisplayShowTitleEnabled(false); 
    bar.setDisplayShowHomeEnabled(false); 

    mTabsAdapter = new TabsAdapter(this, mViewPager); 
    mTabsAdapter.addTab(bar.newTab().setText(R.string.login), 
      LoginFragment.class, null); 
    mTabsAdapter.addTab(bar.newTab().setText(R.string.economics), 
      EconFragment.class, null); 
    mTabsAdapter.addTab(bar.newTab().setText(R.string.elections), 
      ElectionsFragment.class, null); 
    mTabsAdapter.addTab(bar.newTab().setText(R.string.politics), 
      PoliticsFragment.class, null); 
    mTabsAdapter.addTab(bar.newTab().setText(R.string.science), 
      ScienceFragment.class, null); 
    mTabsAdapter.addTab(bar.newTab().setText(R.string.finance), 
      FinanceFragment.class, null); 
    mTabsAdapter.addTab(bar.newTab().setText(R.string.religion), 
      ReligionFragment.class, null); 
    mTabsAdapter.addTab(bar.newTab().setText(R.string.military), 
      MilitaryFragment.class, null); 
    mTabsAdapter.addTab(bar.newTab().setText(R.string.international), 
      InternationalFragment.class, null); 
} 

public static class TabsAdapter extends FragmentPagerAdapter 
    implements ActionBar.TabListener, ViewPager.OnPageChangeListener { 
     private final Context mContext; 
     private final ActionBar mActionBar; 
     private final ViewPager mViewPager; 
     private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); 

     static final class TabInfo { 
      private final Class<?> clss; 
      private final Bundle args; 

      TabInfo(Class<?> _class, Bundle _args) { 
       clss = _class; 
       args = _args; 
      } 
     } 

     public TabsAdapter(FragmentActivity activity, ViewPager pager) { 
      super(activity.getSupportFragmentManager()); 
      mContext = activity; 
      mActionBar = activity.getActionBar(); 
      mViewPager = pager; 
      mViewPager.setAdapter(this); 
      mViewPager.setOnPageChangeListener(this); 
     } 

     public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) { 
      TabInfo info = new TabInfo(clss, args); 
      tab.setTag(info); 
      tab.setTabListener(this); 
      mTabs.add(info); 
      mActionBar.addTab(tab); 
      notifyDataSetChanged(); 
     } 


     public int getCount() { 
      return mTabs.size(); 
     } 

     public Fragment getItem(int position) { 
      TabInfo info = mTabs.get(position); 
      return Fragment.instantiate(mContext, info.clss.getName(), info.args); 
     } 


     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 
     } 


     public void onPageSelected(int position) { 
      mActionBar.setSelectedNavigationItem(position); 
     } 


     public void onPageScrollStateChanged(int state) { 
     } 


     public void onTabSelected(Tab tab, FragmentTransaction ft) { 
      mViewPager.setCurrentItem(tab.getPosition()); 
      Log.v(TAG, "clicked"); 
      Object tag = tab.getTag(); 
      for (int i=0; i<mTabs.size(); i++) { 
       if (mTabs.get(i) == tag) { 
        mViewPager.setCurrentItem(i); 
       } 
      } 
     } 

     public void onTabUnselected(Tab tab, FragmentTransaction ft) {} 

     public void onTabReselected(Tab tab, FragmentTransaction ft) {} 

     public void onTabReselected(Tab tab, android.app.FragmentTransaction ft) {} 

     @Override 
     public void onTabSelected(Tab tab, android.app.FragmentTransaction ft) {  
      Object tag = tab.getTag(); 
      for (int i=0; i<mTabs.size(); i++) { 
       if (mTabs.get(i) == tag) { 
        mViewPager.setCurrentItem(i); 
       } 
      } 
     } 

     public void onTabUnselected(Tab tab, android.app.FragmentTransaction ft) {} 
    } 

Así que, obviamente, después de todo eso, tener que ver cómo se hace un fragmento (incluido inflar un archivo de diseño por separado). Básicamente, en el método onCreateView() de cada fragmento, lo haces devolver inflater.inflate (R.layout.THISFRAGMENTSLAYOUT, container, false); Aquí está el código:

public class EconFragment extends Fragment { 


    private TableLayout questionContainer; 

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     Log.d("Econ", "onCreateView"); 

     return inflater.inflate(R.layout.econfragment, container, false); 
    } 

    public void onResume() { 
     super.onResume(); 

     LayoutInflater inflater = (LayoutInflater) getActivity(). 
     getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     questionContainer = (TableLayout)getActivity().findViewById(R.id.questionContainer); 

     int leftMargin=5; 
     int topMargin=5; 
     int rightMargin=5; 
     int bottomMargin=5; 
     while (pos < 10) { 
     View question = inflater.inflate(R.layout.question, null); 
     question.setId(pos); 
     TextView title = (TextView) question.findViewById(R.id.questionTextView); 
     title.setText(titles[pos]); 
     Button charts = (Button) question.findViewById(R.id.chartsButton); 
     charts.setId(pos); 
     charts.setOnClickListener(chartsListener); 
     TableRow tr = (TableRow) question; 
     TableLayout.LayoutParams trParams = new TableLayout.LayoutParams(
       TableLayout.LayoutParams.MATCH_PARENT, 
       TableLayout.LayoutParams.WRAP_CONTENT); 
     trParams.setMargins(leftMargin, topMargin, rightMargin, bottomMargin); 
     tr.setLayoutParams(trParams); 

     questionContainer.addView(tr); 
     pos++; 
     } 
     Log.d("Econ", "onResume"); 
    } 
+0

Esto no resuelve el problema –

1

Esto es lo mismo que la respuesta seleccionada, excepto que NO he usado las librerías de soporte.


Hay dos pestañas A y B.

Tab A contiene manzanas y albaricoques

Tab B contiene los plátanos y bayas


he utilizar un FrameLayout como recipiente para contener estos bebés

<?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:orientation="vertical" > 
<FrameLayout 
    android:id="@+id/container_widgets" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"/> 
</LinearLayout> 

MultiFragsInTabsJelly.java - maneja las operaciones de adjuntar y desconectar.

import java.util.ArrayList; 
import java.util.Iterator; 

import android.app.ActionBar; 
import android.app.Activity; 
import android.app.Fragment; 
import android.app.FragmentTransaction; 
import android.app.ActionBar.Tab; 
import android.os.Bundle; 
import android.util.Log; 

public class MultiFragsInTabsJelly extends Activity { 

    public static String TAG = "EPE"; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

    // setup action bar for tabs 
     setContentView(R.layout.main_layout_jelly); 

     ActionBar actionBar = getActionBar(); 
     actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 
     actionBar.setDisplayShowTitleEnabled(false); 

     actionBar.setTitle("A and B"); 

     Tab tabA = actionBar 
       .newTab() 
       .setText("A"); 
     tabA.setTabListener(new TabAListener(this)); 

     actionBar.addTab(tabA); 

     Tab tabB = actionBar 
        .newTab() 
        .setText("B"); 
     tabB.setTabListener(new TabBListener(this)); 
     actionBar.addTab(tabB); 
    } 


public static class TabAListener implements ActionBar.TabListener { 

     // FIXME: is this really needed? 
     private static final String appleTag = "apple"; 
     private static final String apricotTag = "apricot"; 

     private final Activity  mActivity; 
     private ArrayList<Fragment> fragList; 

     public TabAListener(Activity activity) { 
      mActivity = activity; 
      fragList = null; 
     } 

     public void onTabReselected(Tab tab, FragmentTransaction ft) { 
      // Reselected don't do anything 
      Log.d(TAG, "Tab A: on Tab reselected"); 
     } 

     public void onTabSelected(Tab tab, FragmentTransaction ft) { 

      Log.d(TAG, "Tab A: on Tab Selected"); 

      // attach all the fragments 
      if(fragList == null) { 

       fragList = new ArrayList<Fragment>(); 
       RecordingFragment appleFrag = new RecordingFragment(); 
       ApricotFragment apricotFrag = new ApricotFragment(); 
       ft.add(R.id.container_widgets, appleFrag, appleTag); 
       ft.add(R.id.container_widgets, apricotFrag, apricotTag); 
       fragList.add(appleFrag); 
       fragList.add(apricotFrag); 
       Log.d(TAG, "Tab A: Added fragments to the ArrayList"); 

      } else { 

       Iterator iter = fragList.iterator(); 

       while (iter.hasNext()) 
       { 
        Log.d(TAG, "Tab A: Attaching fragments"); 
        ft.attach((Fragment) iter.next()); 
       } 
      } 
     } 

     public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
      Log.d(TAG, "Tab A: on Tab Unselected"); 

      if(fragList != null) 
      { 
       Iterator iter = fragList.iterator(); 
       while (iter.hasNext()) 
       { 
        Log.d(TAG, "Tab A: Fragments detached"); 
        ft.detach((Fragment) iter.next()); 
       } 
      } 
     } 
    } 

    public static class TabBListener implements ActionBar.TabListener { 

     // FIXME: is this really needed? 
     private static final String bananaTag = "banana"; 
     private static final String berryTag = "berry"; 

     private final Activity mActivity; 
     private ArrayList<Fragment> fragList; 

     public TabBListener(Activity activity) { 
      mActivity = activity; 
      fragList = null; 
     } 

     public void onTabReselected(Tab tab, FragmentTransaction ft) { 
      // Reselected don't do anything 
      Log.d(TAG, "Tab B: on Tab reselected"); 
     } 

     public void onTabSelected(Tab tab, FragmentTransaction ft) { 

      Log.d(TAG, "Tab B: on Tab Selected"); 

      // attach all the fragments 
      if (fragList == null) { 

       fragList = new ArrayList<Fragment>(); 
       BananaFragment bananaFrag = new BananaFragment(); 
       BerryFragment berryFrag = new BerryFragment(); 
       ft.add(R.id.container_widgets, bananaFrag, bananaTag); 
       ft.add(R.id.container_widgets, berryFrag, berryTag); 
       fragList.add(bananaFrag); 
       fragList.add(berryFrag); 
       Log.d(TAG, "Tab B: Added fragments to the ArrayList"); 

      } else { 

       Iterator iter = fragList.iterator(); 
       while (iter.hasNext()) { 
        Log.d(TAG, "Tab B: Attaching fragments"); 
        ft.attach((Fragment) iter.next()); 
       } 
      } 
     } 

     public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
      Log.d(TAG, "Tab B: on Tab Unselected"); 

      if (fragList != null) { 
       Iterator iter = fragList.iterator(); 
       while (iter.hasNext()) { 
        Log.d(TAG, "Tab B: Fragments detached"); 
        ft.detach((Fragment) iter.next()); 
       } 
      } 
     } 
    } 
} 

Aquí tenemos el cuerpo (vacío) de cada fragmento. Sólo he mostrado una ApricotFragment

apricot_fragment.xml

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

    <TextView 
     android:layout_width="200dip" 
     android:layout_height="wrap_content" 
     android:padding="6dip" 
     android:text="Apricot" /> 

</RelativeLayout> 

ApricotFragment.java

import android.app.Fragment; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 

public class ApricotFragment extends Fragment { 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     // Inflate the layout for this fragment 
     return inflater.inflate(R.layout.apricot_fragment, container, false); 
    } 
} 

he te he logrado implementar este date una palmada en el trasero y conseguir algo rollos de canela con café y dese el gusto to excellent pictures of cats

+0

la buena idea de este oyente es usar getFragmentManager(). beginTransaction(). add() en lugar de getFragmentManager(). beginTransaction () .replace() que es habitual en la mayoría de las muestras :) – VSB