Название SlidingTabLayout и Actionbar

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

Предположим, что у меня есть две вкладки с двумя заголовками ("Первый заголовок" и "Второй заголовок"):

| Action bar       |

| First Title | Second Title |

Когда я впервые ввожу фрагмент, содержащий SlidingTabLayoutзаголовок панели действий выглядит так:

| Firs...      |

| First Title | Second Title |

Когда я проведу пальцем (ко второй вкладке, например), заголовок панели действий станет:

| Second Title       |

| First Title | Second Title |

И остается таким. Кажется, что панель действий берет заголовок последнего фрагмента, загруженного, когда я проведу по крайней мере один раз.

Что я хочу это:

Я хочу показать "Основной заголовок" на панели действий, который никогда не меняется, независимо от того, какой заголовок в SlidingTabLayout является.

Вот некоторые части моего кода:

** Фрагмент, содержащий SlidingTabLayout:

private String mainTitle;
....

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

    // The mainTitle is given to this fragment by another fragment
    Bundle args = getArguments();
    if (args != null) {
        mainTitle = args.getString("TITLE");
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.layout, container, false);
    mViewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
    mSlidingLayout = (SlidingTabLayout) rootView.findViewById(R.id.sliding_layout);
    List<Fragment> listFragments = new ArrayList<>();
    List<String> listTitles = new ArrayList<>();
    for (int i = 0; i < mSize; i++) {
        Bundle bundle = new Bundle();
        ....
        listFragments.add(Fragment.instanciate(getActivity(), CustomFragment.class.getName(), bundle));
        listTitles.add("...");
    }
    mViewPager.setAdapter(new PagerAdapter(getChildFragmentManager(), listFragments, listTitles));

    mSlidingLayout.setDistributedEvenly(true);
    mSlidingLayout.setViewPager(mViewPager);

    return rootView;
}

@Override
public void onResume() {
    super.onResume();
    // I TRY TO SET THE TITLE HERE !!
    getActivity().getSupportActionBar().setTitle(mainTitle);
}

** Адаптер:

class PagerAdapter extends FragmentPagerAdapter {
    List<Fragment> fragments;
    List<String> titles;
    ...
    @Override
    public Fragment getItem(int position) {
        Fragment fragment = fragments.get(position);
        return fragment;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        // maybe the problem is in this method.
        // this method is supposed to provide the titles for the tab
        // but maybe it's also changing the actionbar title
        return titles.get(position);
}

Я устанавливаю заголовок ActionBar в onResume метод каждый раз, когда я ввожу фрагмент.

Спасибо!

РЕДАКТИРОВАТЬ 1:

Я пытался использовать новый SlidingTabLayout который я получил от ввода-вывода Google, и результат все тот же!

Кажется, что заголовок в ActionBar - это сначала подсказка, а затем он меняется на последний загруженный фрагмент, когда я пролистываю другой фрагмент.

Это похоже на загрузку фрагмента, и каждый раз, когда фрагмент загружается, заголовок в ActionBar переопределяется с заголовком этого фрагмента.

РЕДАКТИРОВАТЬ 2:

Я изменил свой код, чтобы опубликовать его последнюю версию (теперь я использую SlidingTabLayout) и показать, как я получу свой mainTitle.

4 ответа

Решение

Нашел это!

Это было действительно глупо с моей стороны (это объясняет, почему у других не было этой проблемы)

Я устанавливал заголовок также в каждом из фрагментов (даже содержащихся во вкладках), поэтому, когда я проводил, вызывался onResume для этих фрагментов, и он изменял заголовок в ActionBar...

Спасибо всем за помощь, я ценю это!

Заголовок actionBar не меняется, потому что onResume() не называется время, когда вы проводите назад.

Это потому, что ViewPager не вызывает фрагмент onResume второй раз. Хотя на самом деле фрагмент возобновляется.

Что вы можете сделать, это переместить настройку заголовка панели действий в родительском фрагменте (который содержит pagertabstrip) в onCreateView вместо.

Для справки:

** Фрагмент, содержащий PagerTabStrip:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.layout, container, false);
    mViewPager = (ViewPager) rootView.findViewById(R.id.viewpager);

    List<Fragment> listFragments = new ArrayList<>();
    List<String> listTitles = new ArrayList<>();

    ...

    // HERE's what you want
    final ActionBar actionBar = getActivity().getSupportActionBar();
    if (actionBar != null) {
        actionBar.setTitle(R.string.main_title);
    }

    mViewPager.setAdapter(new PagerAdapter(getChildFragmentManager(), listFragments));

    return rootView;
}

Вы можете использовать приведенный ниже код, он отлично работает для меня

public class MatchesActivity extends AppCompatActivity implements ActionBar.TabListener {

SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
FloatingActionButton skipButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_matches);
    final ActionBar actionBar = getSupportActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    actionBar.setDisplayHomeAsUpEnabled(true);
    actionBar.setDisplayShowHomeEnabled(true);
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
    // Set up the ViewPager with the sections adapter.
    mViewPager = (ViewPager) findViewById(R.id.pager);
    skipButton = (FloatingActionButton) findViewById(R.id.skip_next);
    skipButton.setVisibility(View.GONE);
    mViewPager.setAdapter(mSectionsPagerAdapter);
    mViewPager.setOffscreenPageLimit(1);
    mViewPager.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            return false;
        }
    });
    mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
        @Override
        public void onPageSelected(int position) {
            actionBar.setSelectedNavigationItem(position);
        }
    });

    actionBar.addTab(
            actionBar.newTab().setText("MATCHES")
                    .setTabListener(this));
    actionBar.addTab(
            actionBar.newTab().setText("PINS")
                    .setTabListener(this));
    actionBar.addTab(
            actionBar.newTab().setText("CHATS")
                    .setTabListener(this));
}

@Override
public void onBackPressed() {
    startActivity(new Intent(MatchesActivity.this, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK & Intent.FLAG_ACTIVITY_CLEAR_TOP));
    MatchesActivity.this.finish();
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == android.R.id.home) {
        onBackPressed();
    }
    return super.onOptionsItemSelected(item);
}

@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    mViewPager.setCurrentItem(tab.getPosition());
}

@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}

@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}

public class SectionsPagerAdapter extends FragmentStatePagerAdapter {

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

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return new MatchesFragment();
            case 1:
                return new PinsFragment();
            case 2:
                return new ConversationFragment();
            default:
                return new MatchesFragment();
        }
    }

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

    @Override
    public CharSequence getPageTitle(int position) {
        Locale l = Locale.getDefault();
        switch (position) {
            case 0:
                return getString(R.string.title_section1).toUpperCase(l);
            case 1:
                return getString(R.string.title_section2).toUpperCase(l);
            case 2:
                return getString(R.string.title_section3).toUpperCase(l);
        }
        return null;
    }
}

}

Я публикую здесь мой код. Это сработало для меня. Внесите необходимые изменения в него и попробуйте. Я использовал библиотеку PagerSlidingTabStrip.

public class DealFragment extends Fragment {


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

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view= inflater.inflate(R.layout.fragment_deal, container, false);
    ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
    viewPager.setAdapter(new SampleFragmentPagerAdapter(getChildFragmentManager()));
    PagerSlidingTabStrip tabsStrip = (PagerSlidingTabStrip)view.findViewById(R.id.tabs);
    tabsStrip.setBackgroundColor(Color.parseColor("#333333"));
    // Attach the view pager to the tab strip
    tabsStrip.setViewPager(viewPager);
    return view;
}
public class SampleFragmentPagerAdapter extends FragmentPagerAdapter {
    final int PAGE_COUNT = 2;
    private final String tabTitles[] = new String[] { "Today's Deals", "Deals Close By" };

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

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

    @Override
    public android.support.v4.app.Fragment getItem(int position) {
        if(position==0)
        {
            return new TodaysDeal();
        }
        else
        {
            return new DealsCloseBy();
        }

    }

    @Override
    public CharSequence getPageTitle(int position) {
        // Generate title based on item position
        return tabTitles[position];
    }
}

}

надеюсь, что это может помочь вам.

Другие вопросы по тегам