Reputation: 181
I have a ViewPager with fragments in my Android app. I want to show Action Bar menu item depending the fragment of the ViewPager. I have readen some questions about this but I can´t find the correct solution. My ViewPager´s code is this:
public class My_Activity extends ActionBarActivity {
private ViewPager mViewPager;
String idioma;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_main);
ActionBar actionBar = getSupportActionBar(); // || getActionBar();
actionBar.setIcon(getResources().getDrawable(R.drawable.navbar_logo));
actionBar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#CC3333")));
actionBar.setTitle("Hello");
mViewPager = (ViewPager) findViewById(R.id.viewpager);
PagerTabStrip pagerTabStrip = (PagerTabStrip) findViewById(R.id.pagerTabStrip);
pagerTabStrip.setTabIndicatorColor(getResources().getColor(R.color.blanco));
Title_Liga_Adapter titleAdapter = new Title_Liga_Adapter(getSupportFragmentManager());
mViewPager.setAdapter(titleAdapter);
mViewPager.setCurrentItem(0);
getSupportActionBar().setIcon(R.drawable.navbar_logo);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (mViewPager.getCurrentItem() == 4) {
getMenuInflater().inflate(R.menu.menu_comunidad,
menu);
} else {
}
return true;
}
/* *
* Called when invalidateOptionsMenu() is triggered
*/
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.action_search)
.setVisible(true);
return super.onPrepareOptionsMenu(menu);
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
this.finish();
return true;
case R.id.action_search:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
I want that when CurrentItem is 4 for example show menu items icons.
Upvotes: 3
Views: 5814
Reputation: 769
Activity Menu
Set up your main menu excluding the menu items that are related to your fragments. ie.
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<item
android:id="@+id/action_settings"
android:title="@string/action_settings"
android:orderInCategory="300"
app:showAsAction="never" />
<item
android:id="@+id/action_help"
android:title="@string/action_help"
android:orderInCategory="400"
app:showAsAction="never"
android:visible="true"/>
</menu>
First Fragment Menu (mine is for assets)
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<item
android:id="@+id/action_add_asset"
android:title="@string/add_new_asset"
android:orderInCategory="100"
app:showAsAction="never" />
<item
android:id="@+id/action_edit_asset_type"
android:title="@string/edit_asset_types"
android:orderInCategory="200"
app:showAsAction="never" />
</menu>
Second fragment menu (liabilities)
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<item
android:id="@+id/action_add_liability"
android:title="@string/add_new_liability"
android:orderInCategory="100"
app:showAsAction="never" />
<item
android:id="@+id/action_edit_liability_type"
android:title="@string/edit_liability_types"
android:orderInCategory="200"
app:showAsAction="never" />
</menu>
Fragment Code (for both)
In your onActivityCreated in each fragment:
setHasOptionsMenu(true);
Fragment 1 Code
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
try {
inflater.inflate(R.menu.menu_asset, menu)
} catch (e: NullPointerException) {
e.printStackTrace()
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val id = item.itemId
if (id == R.id.action_add_asset) {
startNewActivity(NewAssetActivity::class.java)
return true
} else if (id == R.id.action_edit_asset_type) {
startNewActivity(AssetTypeActivity::class.java)
return true
}
return false
}
Fragment 2 code
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
try {
inflater.inflate(R.menu.menu_liability, menu)
} catch (e: NullPointerException) {
e.printStackTrace()
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val id = item.itemId
if (id == R.id.action_add_liability) {
startNewActivity(NewLiabilityActivity::class.java)
return true
} else if (id == R.id.action_edit_liability_type) {
startNewActivity(LiabilityTypeActivity::class.java)
return true
}
return false
}
When you swipe between fragments using the view pager, the menus will change automatically.
Use the orderInCategory to show the correct order of the menus.
Nothing else is required, you dont need to hide/show anything.
Upvotes: 0
Reputation: 181
I answer my own question:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_comunidad,
menu);
return true;
}
// Called when invalidateOptionsMenu() is triggered
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (mViewPager.getCurrentItem() == 4) {
menu.findItem(R.id.action_search)
.setVisible(true);
} else {
menu.findItem(R.id.action_search)
.setVisible(false);
}
return super.onPrepareOptionsMenu(menu);
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
this.finish();
return true;
case R.id.action_search:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Upvotes: 2
Reputation: 156
First create addOnPageChangeListener in onCreate method
ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ...
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
invalidateOptionsMenu();
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
Then you override onCreateOptionMenu()
@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);
if (mViewPager.getCurrentItem()==0){
menu.findItem(R.id.action_search).setVisible(true);
} else if(mViewPager.getCurrentItem()==1){
menu.findItem(R.id.action_search).setVisible(false);
} else if(mViewPager.getCurrentItem()==2){
// configure
} else if(mViewPager.getCurrentItem()==3){
// configure
}
return super.onCreateOptionsMenu(menu);
}
Upvotes: 7
Reputation: 13657
OK..you will have to play with the ViewPager.OnPageChangeListener where you will monitor the method onPageSelected() that will be triggered whenever you change the page of the ViewPager. You will have to keep track of what is the current page AND dispatch a call to the ActivityCompat.invalidateOptionsMenu every time the onPageSelected() is called. This invalidateOptionsMenu() is the key to make it work, it will be responsible for triggering the 'refresh' of options menu..that will indirectly call the onCreateOptionsMenu() method will be called and you have the opportunity to 'hide' or 'show' a different set of items according to the selected tab.
For instance:
public boolean onCreateOptionsMenu(Menu menu) {
///
if (currentPageIdx == 4) {
// inflate menu for page 4
// configure the menus
} ....
return super.onCreateOptionsMenu(menu);
}
Upvotes: 1