Подтвердить что ты не робот

Actionbarsherlock + вкладки + несколько фрагментов?

Я так старался, чтобы заставить actionbarsherlock + вкладки + фрагменты работать.

Я могу заставить этот набор работать как статический, я хотел бы создать это как приложение для Android-Android (движение салфетки).

Я застреваю, когда вам нужно раздуть макет с несколькими фрагментами внутри.

В Support4demos я получил пример FragmentsTabsPager.

4b9b3361

Ответ 1

Вам нужны правильные библиотеки для реализации того, что вы хотите.

В принципе, библиотека ViewPager - это то, что вам не хватает. Мои предложения:

1. ActionBarSherlock

Он настолько мертв - легко работать с этим, я не буду его объяснять.

2. ViewPagerExtensions

Здесь вы можете найти здесь. Загрузите файлы ZIP и создайте из него новый проект.

Я могу заставить этот набор работать как статический, я хотел бы создать его как приложение для Android (swype movement).

Внесите com.astuetz.viewpager.extensions.SwipeyTabsView из этого проекта. Существуют простые примеры. он делает именно то, что вы хотите. Есть даже другие стили вкладок на выбор (включая новую вкладку "Люди", которая поставляется с ICS). Кроме того, очень легко стилизовать его, чтобы он соответствовал вашему приложению.

3. FragmentPagerAdapter

Наконец, этот класс из библиотеки поддержки (v4).

Удачи и позвольте мне спросить, нужна ли вам дополнительная помощь.


Вам не нужно переопределять instantiateItem в FragmentPagerAdapter, если вы используете то, что я предложил. Вам нужно только

  • Предоставить конструктор с FragmentManager и вызвать супер-реализацию;
  • Переопределить getCount, чтобы вернуть количество фрагментов в вашем пейджере и
  • getItem, , который будет использоваться для возврата ваших фрагментов для создания.

Это пример из кода, который у меня есть (полный рабочий, производственный пример). Это внутренний класс для активности, реализующей пейджер:

static class MyFragmentPagerAdapter extends FragmentPagerAdapter {

    public MyFragmentPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public int getCount() {
        return 2;
    }

    @Override
    public Fragment getItem(int position) {
        Fragment f;
        switch(position) {
        case 0:
            f= new ItemSalesDataFragment();
            break;
        case 1:
            f= new DepartmentChooserFragment();
            break;
        default:
            throw new IllegalArgumentException("not this many fragments: " + position);
        }
        return f;
    }
}

Как вы можете видеть, этот пейджер обрабатывает две "страницы", слева - данные продаж. Правильный выбор позволяет выбрать какой отдел. Они возвращаются в методе getItem. Собственные фрагменты (вы можете использовать все фрагменты, которые у вас уже есть, никаких изменений не требуется).

Как и ожидалось, вы объединяете все это вместе: 1) создаете объект, который создает экземпляр MyFragmentPagerAdapter и 2), устанавливая адаптер для вашего объекта ViewPager таким классом, который вы только что создали. Как вы можете видеть, его метод getItem "даст" пейджер всем фрагментам, которые вам нужны. Пример:

mFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mFragmentPagerAdapter);

Конечно, есть и другие вещи, такие как создание самих кнопок вкладок и объединение всего этого для кросс-общения. Я предлагаю посмотреть примеры, представленные в ZIP файле ViewPagerExtensions, который вы загружаете из GitHub. Это только ответ на вопрос в вашем комментарии. Как вы можете видеть, это не так много кода, используя эту библиотеку.

Ответ 2

Мне действительно удалось заставить эту работу работать не что иное, как библиотека ABS и библиотека поддержки. Вот мой код:

public class ActionBarTabs extends SherlockFragmentActivity {
CustomViewPager mViewPager;
TabsAdapter mTabsAdapter;
TextView tabCenter;
TextView tabText;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);

    mViewPager = new CustomViewPager(this);
    mViewPager.setId(R.id.pager);

    setContentView(mViewPager);
    ActionBar bar = getSupportActionBar();
    bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);

    mTabsAdapter = new TabsAdapter(this, mViewPager);

    mTabsAdapter.addTab(bar.newTab().setText("Home"),
            ToolKitFragment.class, null);
    mTabsAdapter.addTab(bar.newTab().setText("FujiSan"),
            FujiFragment.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(SherlockFragmentActivity activity, ViewPager pager) {
        super(activity.getSupportFragmentManager());
        mContext = activity;
        mActionBar = activity.getSupportActionBar();
        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();
    }

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

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

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

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

    @Override
    public void onPageScrollStateChanged(int state) {
    }

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

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

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

Вы загружаете содержимое своей вкладки на основе следующего.

mTabsAdapter.addTab(bar.newTab().setText("Home"),
            YOURFRAGMENTHERE.class, null);  

Это даст вам прекрасный эффект "swipey tab", как вы его называете, с ABS, библиотекой поддержки и фрагментами. ABS действительно делает это почти таким же, как работа с родными библиотеками. Я на самом деле скопировал этот код прямо из примера вкладок поискового вызова Google и немного изменил его для АБС.

Надеюсь, это поможет!

Ответ 3

Множество примеров обычно генерирует исключение (IllegalStateException: The specified child already has a parent. You must call removeView() on the child parent first) при переходе на ранее выбранную вкладку.

Мне нравится адаптировать пример Google с помощью FragmentStatePageAdapter вместо простого FragmentPageAdapter, который заменит фрагменты для вас и устранит эту ошибку. Обычно это уничтожит фрагменты, которые, по его мнению, могут быть удалены, чтобы сэкономить место; переопределите destroyItem(ViewGroup, int, Object) с пустым блоком, если вы хотите всегда держать свои фрагменты.

Вот пример:

public class ActionBarTabs extends SherlockFragmentActivity {
    CustomViewPager mViewPager;
    TabsAdapter mTabsAdapter;
    TextView tabCenter;
    TextView tabText;
    ActionBar mActionBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);

        mViewPager = new CustomViewPager(this);
        mViewPager.setId(R.id.pager);

        setContentView(mViewPager);
        mActionBar = getSupportActionBar();
        mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        mActionBar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);

        mTabsAdapter = new TabsAdapter(this, mViewPager);

        mTabsAdapter.addTab(mActionBar.newTab().setText("Page 1"), 
            YOURFRAGMENT_A.class, null);
        mTabsAdapter.addTab(mActionBar.newTab().setText("Page 2"), 
            YOURFRAGMENT_B.class, null);
        mTabsAdapter.addTab(mActionBar.newTab().setText("Page 3"), 
            YOURFRAGMENT_C.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(SherlockFragmentActivity activity, ViewPager pager) {
            super(activity.getSupportFragmentManager());
            mContext = activity;
            mActionBar = activity.getSupportActionBar();
            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();
        }

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

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

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

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

        @Override
        public void onPageScrollStateChanged(int state) {
        }

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

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

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

Хорошо работает с ABS и относительно прост в применении.