it-swarm.com.ru

ActionBar Вкладки с несколькими фрагментами

Я пытался обновить свое приложение и начать работу с фрагментами, панелью действий и всеми другими функциями пользовательского интерфейса, которые мне не хватает. Я понимаю, что у меня может быть несколько фрагментов в деятельности, разные макеты, основанные на устройстве и все такое хорошее, но я изо всех сил пытаюсь получить некоторые вкладки так, как мне хочется. Я понимаю, как добавлять вкладки, переключаясь между ними, но как мне иметь более одного фрагмента на вкладке? Так, например, у меня, по сути, два экрана, и я хочу, чтобы пользователь мог легко переключаться между ними (почему я хочу использовать вкладки). Если у меня есть два отдельных действия, я могу указать это в файлах xml и использовать setContentView, используя макеты ниже

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>

Я могу преобразовать второй макет в использование вкладок, поскольку он содержит только один фрагмент, но я не уверен, как получить первый макет в одной вкладке. Это разрешено? Заранее спасибо,

Джейсон Пренгер

12
StackJP

Я оставлю это открытым, если у кого-то есть упрощение или лучшая идея ...

В конце концов, у меня был обходной путь, состоящий из базовой компоновки с 3 макетами кадров ...

<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>

Затем в своей работе с вкладками я создал собственный TabListener, который обрабатывал изменения между ними. Код, который я использовал ниже (я использую actionbarsherlock, поэтому он будет немного отличаться от обычного)

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

Это то же самое, что и выбранный ответ, за исключением того, что я НЕ использовал библиотеки поддержки.


Есть две вкладки A и B.

Вкладка A содержит яблоки и абрикосы

Вкладка B содержит бананы и ягоды


Я использую FrameLayout в качестве контейнера для хранения этих детей

<?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 - обрабатывает присоединение и отсоединение операций.

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

Здесь у нас есть (пустое) тело каждого фрагмента. Я показал только одно 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);
    }
}

Я вам удалось реализовать это, похлопать себя по заднице и получить несколько булочек с корицей с кофе и побаловать себя к отличным фотографиям кошек

1
Reno

Вот мое решение:

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

Очевидно, что после всего этого мы должны посмотреть, как создается фрагмент (включая раздувание отдельного файла макета). По сути, в методе onCreateView () каждого фрагмента он возвращает return inflater.inflate (R.layout.THISFRAGMENTSLAYOUT, container, false); Вот код:

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