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

Реализация TabListener с использованием библиотеки поддержки

Я пытаюсь реализовать Tab Navigation, но я хочу, чтобы люди, у которых есть старые версии Android, все еще могут использовать мое приложение.

Приложение в виду ATM довольно просто, я просто хочу понять, как реализовать макет, а затем я добавлю недостающие бит.

Во всяком случае, у меня есть активность контейнера, которая расширяет Fragment Activity (для обеспечения совместимости), и эта операция создает TabView с помощью ActionBar (я полагаю, что моя проблема здесь). Приложение попытается создать три вкладки и добавить их в ActionBar, и я хочу, чтобы пользователь мог прокручивать назад и вперед, используя боковую навигацию.

Вот TabListener, который я пытаюсь реализовать:

public static class TabListener<T extends Fragment> implements ActionBar.TabListener {

    private Fragment mFragment;
    private final Activity mActivity;
    private final String mTag;
    private final Class<T> mClass;

    public TabListener(Activity activity, String tag, Class<T> clz) {
        mActivity = activity;
        mTag = tag;
        mClass = clz;
    }

    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        if (mFragment == null) {
            mFragment = Fragment.instantiate(mActivity, mClass.getName());
            ft.add(android.R.id.content, mFragment, mTag);
        } else {
            ft.attach(mFragment);
        }
    }

    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        if (mFragment != null) {
            ft.detach(mFragment);
        }
    }

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

Вот мой импорт, потому что я хотел убедиться, что я использую библиотеку поддержки:

import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.view.Menu;

Однако Eclipse дает мне проблемы с методами TabListener. Он говорит мне следующее: "Тип LayoutContainer.TabListener должен реализовать унаследованный абстрактный метод ActionBar.TabListener.onTabSelected(ActionBar.Tab, FragmentTransaction)"

Когда я выбираю Добавить нереализованные методы, Eclipse в основном добавляет методы OnTabSelected OnTabReselected и OnTabUnselected, но на этот раз передача версии без поддержки фрагмента (android..app.Fragment) в качестве параметра.

Любые идеи о том, как сделать другую реализацию боковой навигации через библиотеку поддержки, чтобы обеспечить совместимость?

4b9b3361

Ответ 1

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

actionBar.setDisplayShowHomeEnabled(false);
actionBar.setDisplayShowTitleEnabled(false);

tabA = actionBar.newTab().setText("");
tabB = actionBar.newTab().setText("");

Fragment fragmentA = new AFragmentTab();
Fragment fragmentB = new BFragmentTab();

tabA.setTabListener(new MyTabsListener(fragmentA));
tabB.setTabListener(new MyTabsListener(fragmentB));

actionBar.addTab(tabA);
actionBar.addTab(tabB);

Слушатель табуляции выглядит следующим образом:

protected class MyTabsListener implements ActionBar.TabListener{
    private Fragment fragment;

    public MyTabsListener(Fragment fragment){
        this.fragment = fragment;
    }
    public void onTabSelected(Tab tab, FragmentTransaction ft){
        ft.add(R.id.layout2, fragment, null);
    }
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
    }
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        ft.remove(fragment);
    }
}

а затем вы создадите класс для каждой вкладки:

public class BFragmentTab extends Fragment {

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

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

Ответ 2

Ммм. в то время как Малек работает, он прямо не отвечает на вопрос.

Вы можете просто проигнорировать транзакцию фрагмента, которую вы получаете в обратном вызове, и использовать свой собственный:

android.support.v4.app.FragmentTransaction fft = mActivity.getSupportFragmentManager().beginTransaction();

Просто убедитесь, что ваша активность - это FragmentActivity, и вы сможете начать новую транзакцию фрагмента.

Кроме того, метод replace() в фрагментеTransaction гораздо удобнее, чем add() и remove()

Ответ 3

Ключ должен использовать

import android.support.v7.app.ActionBar;

... а не...

import android.app.ActionBar;

Это позволяет избежать умного обходного пути Нельсона Рамиреса.

Следующий полный пример, основанный на официальной документации, был протестирован для работы с Android 3.0, API 11

package com.example.myapp;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.*;
import android.widget.TextView;

public class NavigationTabsBasicDemoActivity extends ActionBarActivity {

    static public class TabListener<T extends Fragment> implements ActionBar
            .TabListener {

        private Fragment mFragment;
        private final Activity mActivity;
        private final String mTag;
        private final Class<T> mClass;

        /**
         * Constructor used each time a new tab is created.
         *
         * @param activity The host Activity, used to instantiate the
         *                 fragment
         * @param tag      The identifier tag for the fragment
         * @param pClass   The fragment Class, used to instantiate the
         *                 fragment
         * @see <a
         * href="http://developer.android.com/guide/topics/ui/actionbar
         * .html#Tabs">
         * Developers Guide > Action Bar > Adding Navigation Tabs</a>
         */
        public TabListener(Activity activity, String tag, Class<T> pClass) {
            mActivity = activity;
            mTag = tag;
            mClass = pClass;
        }

        @Override
        public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
            if (mFragment == null) {
                mFragment = Fragment.instantiate(mActivity, mClass.getName());
                ft.add(android.R.id.content, mFragment, mTag);
            } else {
                // If it exists, attach it in order to show it
                ft.attach(mFragment);
            }
        }

        @Override
        public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
            if (mFragment != null) {
                // Detach the fragment, because another one is about to be
                // attached.
                ft.detach(mFragment);
            }
        }

        @Override
        public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
            // Do nothing.
        }
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // No need for setContentView() to be used, Instead  we use the root
        // android.R.id.content as the container for each fragment,
        // which is set in the TabListener

        ActionBar actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        actionBar.setDisplayShowTitleEnabled(true);

        ActionBar.Tab tab = actionBar.newTab().setText("Artist").setTabListener(
                new TabListener<PlaceholderFragment>(this,
                                                     "artist",
                                                     PlaceholderFragment
                                                             .class));
        actionBar.addTab(tab);

        tab = actionBar.newTab().setText("Album").setTabListener(
                new TabListener<PlaceholderFragment>(
                    this,
                    "album",
                    PlaceholderFragment.class));
        actionBar.addTab(tab);
    }

    /**
     * In this example use one Fragment but display different data based on
     * which
     * tab is shown. In production you'd probably use a separate fragment.
     */
    public static class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate(
                    R.layout.fragment_navigation_tabs_basic_demo,
                                             container,
                                             false);
            TextView outputTextView = (TextView) rootView.findViewById(
                                        R.id.output_textView);
            outputTextView.setText("Hello " + getTag());
            return rootView;
        }
    }
}

Ответ 4

Я хотел реализовать @nelson-ramirez, но имел ошибку доступа к mActivity, так что это комбинация этих двух ответов и работает для моего проекта, который использует навигацию на вкладке с входом в Facebook (для чего требуется библиотека support.v4), ключи, создавая приватную мобильность, которую вы затем передаете и назначаете при запуске слушателя, и создаете собственную транзакцию фрагментов, не используя одну из аргументов. Также измените основное действие на FragmentActivity, используя библиотеку v4, которая позволяет получить доступ к getSupportFragmentManager().

public class MyTabListener implements ActionBar.TabListener{
    private Fragment fragment;
    private FragmentActivity mActivity;

    public MyTabListener(Fragment fragment, FragmentActivity activity){
        this.fragment = fragment;
        this.mActivity = activity;
    }

    @Override
    public void onTabSelected(ActionBar.Tab tab, android.app.FragmentTransaction ft) {
        android.support.v4.app.FragmentTransaction fft = mActivity.getSupportFragmentManager().beginTransaction();
        fft.replace(R.id.fragment_container, fragment);
        fft.commit();
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab, android.app.FragmentTransaction ft) {
        android.support.v4.app.FragmentTransaction fft = mActivity.getSupportFragmentManager().beginTransaction();
        fft.remove(fragment);
    }

    @Override
    public void onTabReselected(ActionBar.Tab tab, android.app.FragmentTransaction ft) {

    }
}

Ответ 5

Любые идеи о том, как сделать еще одну реализацию боковой навигации через библиотеку поддержки для обеспечения совместимости?

Альтернативное решение

По состоянию на 29 мая 2015 года вы можете использовать библиотеку поддержки дизайна Android. Он включает в себя вкладку Layout и поддерживает устройства Android 2.1 или выше.