根据选定的选项卡在 ActionBar 中显示和隐藏项目
Posted
技术标签:
【中文标题】根据选定的选项卡在 ActionBar 中显示和隐藏项目【英文标题】:Show and hide Item in ActionBar depending on the selected Tab 【发布时间】:2016-02-15 02:35:36 【问题描述】:我需要获取所选选项卡的数字位置,以便在 MainActivity 中显示/隐藏 ActionBar 项。比如我在Tab1,显示写新消息的项,进入Tab2,隐藏新消息项,显示添加用户到通讯录的项... 该应用程序的结构是:带有选项卡布局(4 个选项卡)的 MainActivity 和一个管理所有 Fragment 的 FragmentStatePagerAdapter。
MainActivity
public class MainActivity extends AppCompatActivity
// Declaring Your View and Variables
Toolbar toolbar;
ViewPager pager;
ViewPagerAdapter adapter;
SlidingTabLayout tabs;
CharSequence Titles[]="1","2","3","4";
int Numboftabs =4;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
//getSupportActionBar().setElevation(0);
setContentView(R.layout.activity_main);
// Creating The Toolbar and setting it as the Toolbar for the activity
toolbar = (Toolbar) findViewById(R.id.tool_bar);
//setSupportActionBar(toolbar);
// Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
adapter = new ViewPagerAdapter(getSupportFragmentManager(),Titles,Numboftabs);
// Assigning ViewPager View and setting the adapter
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
// Assiging the Sliding Tab Layout View
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width
// Setting Custom Color for the Scroll bar indicator of the Tab View
tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer()
@Override
public int getIndicatorColor(int position)
return ContextCompat.getColor(getApplicationContext(), R.color.darkgreen);
);
// Setting the ViewPager For the SlidingTabsLayout
tabs.setViewPager(pager);
@Override
public boolean onCreateOptionsMenu(Menu menu)
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
@Override
public boolean onOptionsItemSelected(MenuItem item)
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in androidManifest.xml.
int id = item.getItemId();
switch (id)
case R.id.action_settings:
Intent intentMSett = new Intent(this, MainSettings.class);
startActivity(intentMSett);
break;
case R.id.action_add_user:
Intent intent = new Intent(this, CreateUser.class);
startActivityForResult(intent, 101);
break;
case R.id.action_search:
Toast.makeText(getApplicationContext(),
"search", Toast.LENGTH_SHORT).show();
break;
return super.onOptionsItemSelected(item);
ViewPagerAdapter
public class ViewPagerAdapter extends FragmentStatePagerAdapter
CharSequence Titles[]; // This will Store the Titles of the Tabs which are Going to be passed when ViewPagerAdapter is created
int NumbOfTabs; // Store the number of tabs, this will also be passed when the ViewPagerAdapter is created
private Context context;
// Build a Constructor and assign the passed Values to appropriate values in the class
public ViewPagerAdapter(FragmentManager fm,CharSequence mTitles[], int mNumbOfTabsumb)
super(fm);
this.Titles = mTitles;
this.NumbOfTabs = mNumbOfTabsumb;
//This method return the fragment for the every position in the View Pager
@Override
public Fragment getItem(int position)
if(position == 0) // if the position is 0 we are returning the First tab
Tab1 tab1 = new Tab1();
return tab1;
else if(position == 1)
Tab2 tab2 = new Tab2();
return tab2;
else if(position == 2)
Tab3 tab3 = new Tab3();
return tab3;
else if(position == 3)
Tab4 tab4 = new Tab4();
return tab4;
else
Tab1 tab1 = new Tab1();
return tab1;
// This method return the titles for the Tabs in the Tab Strip
@Override
public CharSequence getPageTitle(int position)
return Titles[position];
// This method return the Number of tabs for the tabs Strip
@Override
public int getCount()
return NumbOfTabs;
搜索解决方案我找到了 MainActivity 的这个方法:
@Override
public boolean onPrepareOptionsMenu(Menu menu)
// TODO Auto-generated method stub
MenuInflater inflater = getMenuInflater();
int currentTab = tabHost.getCurrentTab();
Toast.makeText(getApplicationContext(), currentTab+"", Toast.LENGTH_SHORT);
menu.clear();
if (currentTab == 0)
inflater.inflate(R.menu.first, menu); // menu for photospec.
else
inflater.inflate(R.menu.second, menu); // menu for songspec
return super.onPrepareOptionsMenu(menu);
SlidingTabLayout
public class SlidingTabLayout extends HorizontalScrollView
/**
* Allows complete control over the colors drawn in the tab layout. Set with
* @link #setCustomTabColorizer(TabColorizer).
*/
public interface TabColorizer
/**
* @return return the color of the indicator used when @code position is selected.
*/
int getIndicatorColor(int position);
private static final int TITLE_OFFSET_DIPS = 24;
private static final int TAB_VIEW_PADDING_DIPS = 16;
private static final int TAB_VIEW_TEXT_SIZE_SP = 12;
private int mTitleOffset;
private int mTabViewLayoutId;
private int mTabViewTextViewId;
private boolean mDistributeEvenly;
private ViewPager mViewPager;
private SparseArray<String> mContentDescriptions = new SparseArray<String>();
private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;
private final SlidingTabStrip mTabStrip;
public SlidingTabLayout(Context context)
this(context, null);
public SlidingTabLayout(Context context, AttributeSet attrs)
this(context, attrs, 0);
public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle)
super(context, attrs, defStyle);
// Disable the Scroll Bar
setHorizontalScrollBarEnabled(false);
// Make sure that the Tab Strips fills this View
setFillViewport(true);
mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density);
mTabStrip = new SlidingTabStrip(context);
addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
/**
* Set the custom @link TabColorizer to be used.
*
* If you only require simple custmisation then you can use
* @link #setSelectedIndicatorColors(int...) to achieve
* similar effects.
*/
public void setCustomTabColorizer(TabColorizer tabColorizer)
mTabStrip.setCustomTabColorizer(tabColorizer);
public void setDistributeEvenly(boolean distributeEvenly)
mDistributeEvenly = distributeEvenly;
/**
* Sets the colors to be used for indicating the selected tab. These colors are treated as a
* circular array. Providing one color will mean that all tabs are indicated with the same color.
*/
public void setSelectedIndicatorColors(int... colors)
mTabStrip.setSelectedIndicatorColors(colors);
/**
* Set the @link ViewPager.OnPageChangeListener. When using @link SlidingTabLayout you are
* required to set any @link ViewPager.OnPageChangeListener through this method. This is so
* that the layout can update it's scroll position correctly.
*
* @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)
*/
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener)
mViewPagerPageChangeListener = listener;
/**
* Set the custom layout to be inflated for the tab views.
*
* @param layoutResId Layout id to be inflated
* @param textViewId id of the @link TextView in the inflated view
*/
public void setCustomTabView(int layoutResId, int textViewId)
mTabViewLayoutId = layoutResId;
mTabViewTextViewId = textViewId;
/**
* Sets the associated view pager. Note that the assumption here is that the pager content
* (number of tabs and tab titles) does not change after this call has been made.
*/
public void setViewPager(ViewPager viewPager)
mTabStrip.removeAllViews();
mViewPager = viewPager;
if (viewPager != null)
viewPager.setOnPageChangeListener(new InternalViewPagerListener());
populateTabStrip();
/**
* Create a default view to be used for tabs. This is called if a custom tab view is not set via
* @link #setCustomTabView(int, int).
*/
protected TextView createDefaultTabView(Context context)
TextView textView = new TextView(context);
textView.setGravity(Gravity.CENTER);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
textView.setTypeface(Typeface.DEFAULT_BOLD);
textView.setLayoutParams(new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
TypedValue outValue = new TypedValue();
getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
outValue, true);
textView.setBackgroundResource(outValue.resourceId);
textView.setAllCaps(true);
int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
textView.setPadding(padding, padding, padding, padding);
return textView;
private void populateTabStrip()
final PagerAdapter adapter = mViewPager.getAdapter();
final View.OnClickListener tabClickListener = new TabClickListener();
for (int i = 0; i < adapter.getCount(); i++)
View tabView = null;
TextView tabTitleView = null;
if (mTabViewLayoutId != 0)
// If there is a custom tab view layout id set, try and inflate it
tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
false);
tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
if (tabView == null)
tabView = createDefaultTabView(getContext());
if (tabTitleView == null && TextView.class.isInstance(tabView))
tabTitleView = (TextView) tabView;
if (mDistributeEvenly)
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) tabView.getLayoutParams();
lp.width = 0;
lp.weight = 1;
tabTitleView.setText(adapter.getPageTitle(i));
tabView.setOnClickListener(tabClickListener);
String desc = mContentDescriptions.get(i, null);
if (desc != null)
tabView.setContentDescription(desc);
mTabStrip.addView(tabView);
if (i == mViewPager.getCurrentItem())
tabView.setSelected(true);
private void addIconTab(final int position, int resId)
ImageButton tab = new ImageButton(getContext());
tab.setImageResource(resId);
public void setContentDescription(int i, String desc)
mContentDescriptions.put(i, desc);
@Override
protected void onAttachedToWindow()
super.onAttachedToWindow();
if (mViewPager != null)
scrollToTab(mViewPager.getCurrentItem(), 0);
private void scrollToTab(int tabIndex, int positionOffset)
final int tabStripChildCount = mTabStrip.getChildCount();
if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount)
return;
View selectedChild = mTabStrip.getChildAt(tabIndex);
if (selectedChild != null)
int targetScrollX = selectedChild.getLeft() + positionOffset;
if (tabIndex > 0 || positionOffset > 0)
// If we're not at the first child and are mid-scroll, make sure we obey the offset
targetScrollX -= mTitleOffset;
scrollTo(targetScrollX, 0);
private class InternalViewPagerListener implements ViewPager.OnPageChangeListener
private int mScrollState;
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
int tabStripChildCount = mTabStrip.getChildCount();
if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount))
return;
mTabStrip.onViewPagerPageChanged(position, positionOffset);
View selectedTitle = mTabStrip.getChildAt(position);
int extraOffset = (selectedTitle != null)
? (int) (positionOffset * selectedTitle.getWidth())
: 0;
scrollToTab(position, extraOffset);
if (mViewPagerPageChangeListener != null)
mViewPagerPageChangeListener.onPageScrolled(position, positionOffset,
positionOffsetPixels);
@Override
public void onPageScrollStateChanged(int state)
mScrollState = state;
if (mViewPagerPageChangeListener != null)
mViewPagerPageChangeListener.onPageScrollStateChanged(state);
@Override
public void onPageSelected(int position)
if (mScrollState == ViewPager.SCROLL_STATE_IDLE)
mTabStrip.onViewPagerPageChanged(position, 0f);
scrollToTab(position, 0);
for (int i = 0; i < mTabStrip.getChildCount(); i++)
mTabStrip.getChildAt(i).setSelected(position == i);
if (mViewPagerPageChangeListener != null)
mViewPagerPageChangeListener.onPageSelected(position);
private class TabClickListener implements View.OnClickListener
@Override
public void onClick(View v)
for (int i = 0; i < mTabStrip.getChildCount(); i++)
if (v == mTabStrip.getChildAt(i))
mViewPager.setCurrentItem(i);
return;
但我不知道如何设置 getCurrentTab() 以获取 Tab 位置,而是在 ViewPagerAdapter 中我有位置,但我不知道如何从 MainActivity 获取菜单。解决方案?
【问题讨论】:
【参考方案1】:你可以用setHasOptionMenu(Boolean)
来做;
然后在您的onCreateOptionsMenu()
中创建图标和标题,这是一个示例:
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.your_fragment_menu, menu);
//add the items here.
也看看这个example
编辑
在每个片段上,您可以扩展您的菜单,因为我说您已经创建了两个菜单,所以在onCreateOptionsMenu()
的一个片段中添加第一个,第二个添加第二个,依此类推。
【讨论】:
所以我需要为选项卡的每个框架都有一个菜单?当我选择一个新标签时,一个会覆盖另一个? 这是一个选项 :) 试一试,让我知道它是否有效。 对不起,我出去工作了,现在我可以测试一下,我会尽快通知您! 用更好的方法解决了,看看我的回答,还是谢谢! 哦,好吧,那么您必须将任何答案标记为正确的@MattC :)【参考方案2】:步骤#1:创建一个包含所有操作栏项目的菜单资源。如有必要,请在资源中添加一个或多个 android:visible="false"
。
步骤#2:在onPrepareOptionsMenu()
中,调用findItem()
on the Menu
,在膨胀资源后,检索状态变化的MenuItem
对象。在你的活动领域坚持这些。
步骤#3:将OnPageChangeListener
添加到您的ViewPager
,并根据需要在MenuItem
对象上调用setVisibility()
,以在用户选择不同选项卡时更改其状态。最有可能的是,这将需要更改您从哪里获得 SlidingTabLayout
,因为它也可能设置一个 OnPageChangeListener
,并且每个 ViewPager
只能有一个。
【讨论】:
为了更好地理解,我添加了我的 SlidingTabLayout。完成第 1 步和第 2 步,但我无法覆盖 ViewPager 中的 OnPageChangeListener,因此无法获取菜单并调用 setVisibilty() @MattC:您将需要能够重新组织您的代码,以便您的活动和您的SlidingTabLayout
都可以访问引发并发送到OnPageChangeListener
的事件。例如,SlidingTabLayout
可以有一个 CompositeOnPageChangedListener
,它既调用了它的内部监听器,又调用了另一个你从活动中提供的监听器。
请问你能举个例子吗?我已经在我的帖子中添加了 SlidingTabLayout,我还在学习 android/java,我不是很会..
@MattC:嗯,这有点超出了 SO 答案的范围。另一种方法是让您将不同的操作栏项目移动到构成页面的片段中。我在this sample app 中说明了这种方法。【参考方案3】:
我已经解决了在 MainActivity 中添加一个带有 OnPageChangeListener 的方法,我发布了更新的代码:
MainActivity
public class MainActivity extends AppCompatActivity
// Declaring Your View and Variables
Toolbar toolbar;
ViewPager pager;
ViewPagerAdapter adapter;
SlidingTabLayout tabs;
CharSequence Titles[]="1","2","3","4";
int Numboftabs =4;
Integer tabSelected = 1;
public static Integer MYACTIVITY_REQUEST_CODE = 101;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
//getSupportActionBar().setElevation(0);
setContentView(R.layout.activity_main);
//
// Creating The Toolbar and setting it as the Toolbar for the activity
toolbar = (Toolbar) findViewById(R.id.tool_bar);
//setSupportActionBar(toolbar);
// Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
adapter = new ViewPagerAdapter(getSupportFragmentManager(),Titles,Numboftabs);
// Assigning ViewPager View and setting the adapter
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
// Assiging the Sliding Tab Layout View
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width
// Setting Custom Color for the Scroll bar indicator of the Tab View
tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer()
@Override
public int getIndicatorColor(int position)
return ContextCompat.getColor(getApplicationContext(), R.color.darkgreen);
);
// Setting the ViewPager For the SlidingTabsLayout
tabs.setViewPager(pager);
@Override
public boolean onPrepareOptionsMenu(Menu menu)
MenuInflater inflater = getMenuInflater();
tabSelected = getCurrentTab();
switch (tabSelected)
case 1:
//other..
break;
case 2:
//other..
break;
case 3:
MenuItem addUser = menu.findItem(R.id.action_add_user);
addUser.setVisible(true);
break;
case 4:
MenuItem message = menu.findItem(R.id.action_message);
message.setVisible(true);
break;
return super.onPrepareOptionsMenu(menu);
@Override
public boolean onCreateOptionsMenu(Menu menu)
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
@Override
public boolean onOptionsItemSelected(MenuItem item)
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
switch (id)
case R.id.action_settings:
Intent intentMSett = new Intent(this, MainSettings.class);
startActivity(intentMSett);
break;
case R.id.action_add_user:
Intent intentCUser = new Intent(this, CreateUser.class);
startActivityForResult(intentCUser, 101);
break;
case R.id.action_message:
Intent intentMessage = new Intent(this, CreateMessage.class);
startActivityForResult(intentMessage, 102);
break;
return super.onOptionsItemSelected(item);
public Integer getCurrentTab()
pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener()
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
@Override
public void onPageSelected(int position)
switch (position)
case 0:
tabSelected = 1;
break;
case 1:
tabSelected = 2;
break;
case 2:
tabSelected = 3;
break;
case 3:
tabSelected = 4;
break;
@Override
public void onPageScrollStateChanged(int state)
);
return tabSelected;
【讨论】:
以上是关于根据选定的选项卡在 ActionBar 中显示和隐藏项目的主要内容,如果未能解决你的问题,请参考以下文章
Django:如何根据表单中的选定选项在模板上显示来自 django 数据库的图像?