SlidingTabLayout 和 Actionbar 标题
SlidingTabLayout and Actionbar title
我在我的应用程序中使用 SlidingTabLayout
(来自 Google 来源)在不同片段之间导航。
我可以很好地在内容之间滑动,但我面临的问题是操作栏的标题表现得很奇怪。
假设我有两个带有两个标题的选项卡('First Title' 和 'Second Title'):
| Action bar |
| First Title | Second Title |
当我第一次进入包含SlidingTabLayout
的Fragment时,Actionbar的标题是这样的:
| Firs... |
| First Title | Second Title |
当我滑动(例如到第二个选项卡)时,操作栏的标题变为:
| Second Title |
| First Title | Second Title |
并保持这样。当我至少滑动一次时,Actionbar 似乎采用了最后加载的片段的 标题 。
我要的是这个:
我想在 Actionbar 中显示一个 'Main 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);
}
每次输入 Fragment 时,我都在 onResume
方法中设置 ActionBar 的标题。
谢谢!
编辑 1:
我尝试使用从 Google I/O 获得的新 SlidingTabLayout
,结果还是一样!
好像ActionBar里面的Title一开始是个提示,后来滑动到另一个fragment的时候就变成了上次加载的fragment。
就像加载片段一样,每次加载片段时,ActionBar 中的标题都会被该片段的标题覆盖。
编辑 2:
我将我的代码更改为 post 它的最新版本(我现在使用的是 SlidingTabLayout)并展示我如何获得我的 mainTitle。
你可以使用下面的代码,它对我来说很好用
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;
}
}
}
我在这里发布了 mine.It 的代码,用于 me.Make 所需的更改,并尝试 it.I 在其中使用 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];
}
}
}
希望对您有所帮助。
actionBar 标题不会改变,因为 onResume()
在您向后滑动时不会被调用。
这是因为ViewPager 没有第二次调用fragment 的onResume
。即使实际上片段已恢复。
您可以将 parent 片段(包含 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;
}
找到了!
我真是傻了(这解释了为什么其他人没有这个问题)
我也在每个片段中设置标题(甚至是选项卡中包含的片段),所以当我滑动时,这些片段上的 onResume 被调用并且它改变了 ActionBar 中的标题...
谢谢大家的帮助,我很感激!
我在我的应用程序中使用 SlidingTabLayout
(来自 Google 来源)在不同片段之间导航。
我可以很好地在内容之间滑动,但我面临的问题是操作栏的标题表现得很奇怪。
假设我有两个带有两个标题的选项卡('First Title' 和 'Second Title'):
| Action bar |
| First Title | Second Title |
当我第一次进入包含SlidingTabLayout
的Fragment时,Actionbar的标题是这样的:
| Firs... |
| First Title | Second Title |
当我滑动(例如到第二个选项卡)时,操作栏的标题变为:
| Second Title |
| First Title | Second Title |
并保持这样。当我至少滑动一次时,Actionbar 似乎采用了最后加载的片段的 标题 。
我要的是这个:
我想在 Actionbar 中显示一个 'Main 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);
}
每次输入 Fragment 时,我都在 onResume
方法中设置 ActionBar 的标题。
谢谢!
编辑 1:
我尝试使用从 Google I/O 获得的新 SlidingTabLayout
,结果还是一样!
好像ActionBar里面的Title一开始是个提示,后来滑动到另一个fragment的时候就变成了上次加载的fragment。
就像加载片段一样,每次加载片段时,ActionBar 中的标题都会被该片段的标题覆盖。
编辑 2:
我将我的代码更改为 post 它的最新版本(我现在使用的是 SlidingTabLayout)并展示我如何获得我的 mainTitle。
你可以使用下面的代码,它对我来说很好用
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;
}
}
}
我在这里发布了 mine.It 的代码,用于 me.Make 所需的更改,并尝试 it.I 在其中使用 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];
}
}
}
希望对您有所帮助。
actionBar 标题不会改变,因为 onResume()
在您向后滑动时不会被调用。
这是因为ViewPager 没有第二次调用fragment 的onResume
。即使实际上片段已恢复。
您可以将 parent 片段(包含 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;
}
找到了!
我真是傻了(这解释了为什么其他人没有这个问题)
我也在每个片段中设置标题(甚至是选项卡中包含的片段),所以当我滑动时,这些片段上的 onResume 被调用并且它改变了 ActionBar 中的标题...
谢谢大家的帮助,我很感激!