Android refresh actionbar and title on fragment change - android

in my app i am developing an activity using the actionbar in NAVIGATION_MODE_TABS-mode.
Each tab is showing a fragment (list, detail).
Initially the list-tab is visibile.
The list is implementing setMultiChoicheModeListener() and modifies the ActionBar and the title of the activity if one or more items are selected.
How can i reset the title and the ActionBar to the inital value (title and actions) when the user clicks on the detail-tab without deselecting the items?
BTW Target-Platform is > 4.1 and i am not using the support library.
Thanks.
public class MyActivity extends Activity {
#Override
protected void onCreate (Bundle savedInstanceState) {
this.actionBar = getActionBar();
this.actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
....
for (Tab tab : getTabs())
{
//here are two tabs added (List and Detail)
this.actionBar.addTab(tab);
}
....
}
protected class NavigationTabListener implements ActionBar.TabListener {
private Fragment fragment;
....
public void onTabSelected(Tab tab, FragmentTransaction ft) {
ft.replace(newFragmentResourceId, this.fragment);
}
}
}
public class MyListViewFragment extends LinearLayout implements IListViewFragment {
....
#Override
public void initialize() {
inflate(getContext(), listLayoutResourceId, this);
this.myList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE_MODAL);
this.myList.setMultiChoiceModeListener(new MultiChoiceModeListener() {
....
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu)
{
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(selectedItemsMenuResourceId, menu);
return true;
}
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked)
{
if (checked)
{
this.numberItemsSelected++;
adapter.setNewSelection(position);
}
else
{
this.numberItemsSelected--;
adapter.removeSelection(position);
}
mode.setTitle(getContext().getResources().getQuantityString(
R.plurals.items_selected, this.numberItemsSelected,
Integer.valueOf(this.numberItemsSelected)));
}
....
}
}
I am trying to implement the MVP pattern, but it's still in evaluation phase. The Activity acts as the presenter, the views are in separate classes.
For each Fragment i am also implementing the MVP apttern, but i think this is not interesting to solve the problem.
Some notes to the classes:
MyActivity creates two fragments (one for List, one for Detail view, the detail view has nothing to do with the selected items).
The initial view of the activity is the fragment with the list.
If the user selects some entries I am updating the action bar and the title through the callback of MultiChoiceModeListener.
But the user can now change the fragment by clicking on the "Detail" tab without deselecting the items or clicking to the new elements in the action bar, the result is that the detail fragment is shown, but the title of the activity is still the one I modified in the MultiChoiceModeListener, and there is also the check mark of the action bar visible (auto created by the system).
So the best way is I think to get somehow the current ActionMode, so I can invoke finish() to "reset" the ActionBar and the title.

Make sure you keep reference of the ActionMode in the ActionMode.Callback methods inside your activity which has the ActionBar.TabListener.
When a new tab is selected just finish the action mode, like:
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if(mActionMode != null){
mActionMode.finish();
}
ft.replace(newFragmentResourceId, this.fragment);
}
Make the ActionMode reference back to null when onDestroyActionMode(ActionMode) is called.

Related

Opening bottom sheet when clicked on the overflow menu on a fragment

I am trying to implement behavior of opening bottom sheet when clicked on overflow menu. ex: expected behavior
I may do this on an activity using onMenuOpened as suggested here,
But I want to do this on fragment.
How to achieve this behavior on a fragment?
I am using single activity pattern and navigation architecture component.
Create a interface which will be implemented by your Fragment's
ex:
public interface OnMenuOpenListener(){
boolean onMenuOpened();
}
public class MyFragment extends Fragment implements OnMenuOpenListener{
#Override
public boolean onMenuOpened(){
//open bottom sheet here
}
}
public class MyActivity extends Activity{
#Override
public boolean onMenuOpened(int featureId, Menu menu) {
if(featureId == AppCompatDelegate.FEATURE_SUPPORT_ACTION_BAR && menu != null){
//overflow menu clicked, put code here...
// As you are using navigation component
Fragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host);
//MyFragment
Fragment fragment=navHostFragment.getChildFragmentManager().getFragments().get(0);
if(fragment instanceof OnMenuOpenListener){
((OnMenuOpenListener)fragment).onMenuOpened()
return false;
}
}
return super.onMenuOpened(featureId, menu);
}
}
As Support Action Bar is attached to Activity All the event's are captured by Activity all you need to do is get the Fragment which need's the event and trigger the call using a call back.If you return false onMenuOpened will not open the overflow menu and will trigger bottom sheet menu from your fragment.
P.S- I have not written the code in Editor so might have some error's but you must have got the idea.
Reference:
https://stackoverflow.com/a/51732378/7972699
As discussed here opening bottom sheet when clicked on the overflow menu is bad UX.
Why?
Quoting from the post
Because user have to reach the top of the screen to click the oveflow
menu, then go back to the bottom to click desired action which is on
the bottom sheet.
-
According to Fitt's Law - The time to acquire a target is a function
of the distance to and size of the target. I agree that I think
distance between the menu and the bottom sheet is substantial. This
solution allows placing a lot options in one place.
-
it also doesn't match the user expectation since people are used to
the overflow menu opening in a different manner.
If you have a top action bar, use usual context menu. If you have a bottom action bar you may use bottom sheet.
**You can try the following steps to open bottom sheet dialog:**
1. Just make a function inside Activity where the fragment is replace
public Fragment getCurrentFragment() {
return getSupportFragmentManager().findFragmentById(R.id.frameContainer);
}
Fragment fragment = getCurrentFragment();
if (fragment != null) {
if (fragment instanceof RequiredFragment) {
RequiredFragment.openBottumSheetDialog();
}
}
2. In Side RequiredFragment get your function from activity:
private BottomSheetDialog mBottomSheetDialogFragment;
private void showBottomSheetFilter() {
if (mBottomSheetDialogFragment == null) {
mBottomSheetDialogFragment = mBottomSheetDialogFragment.newInstance(feedSection);
mBottomSheetDialogFragment.setCallBackListener(new OnFeedsTypeSelectedListener() {
#Override
public void onFeedsTypeSelected(int contentType) {
filterByContentTypeId(contentType);
}
}
mBottomSheetDialogFragment.show(getChildFragmentManager(),
mBottomSheetDialogFragment.getTag());
}
3. Create a BottomSheetDialog Dialog fragment.
public class BottomSheetDialog extends BottomSheetDialogFragment {
private String[] feedsFilter;
private ListView listView;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
feedsFilter = getResources().getStringArray(R.array.ideas_filter);
}
#Override
public void setupDialog(final Dialog dialog, int style) {
super.setupDialog(dialog, style);
View contentView = View.inflate(getContext(), R.layout.dialog_idea_filter_bottom_sheet, null);
dialog.setContentView(contentView);
listView = (ListView) contentView.findViewById(R.id.listView);
ArrayAdapter < String > adapter = new ArrayAdapter < String > (getActivity(),
android.R.layout.simple_list_item_1, feedsFilter);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView < ? > parent, View view,
int position, long id) {
if (onFeedsTypeSelected != null) {
onIdeaTypeSelectedListenonFeedsTypeSelecteder.onFeedsTypeSelected(feedsFilter[position]);
}
dismiss();
}
});
}
public void setCallBackListener(onFeedsTypeSelected SelectedListener onFeedsTypeSelected) {
this.onIdeaTypeSelectedLionFeedsTypeSelectedstener = onFeedsTypeSelected;
}
}

Fragment's onCreateOptionsMenu method is never called

I have an application with two activities hosting fragments. My main activity hosts a single fragment, and that fragment is able to define and inflate a menu that goes in the toolbar, no problem.
In the second activity, though, which uses a FragmentStatePagerAdapter to allow horizontal scrolling between items, my fragment does not seem able to define the menu in the toolbar.
Checks:
My whole app is set to use a theme (android:theme="#style/AppTheme") based on Theme.AppCompat.Light.DarkActionBar.
My fragment extends android.support.v4.app.Fragment
setHasOptionsMenu(true); is called from the fragment's onCreate() method
the hosting activity extends AppCompatActivity and does not implement a toolbar menu itself
my fragment overrides void onCreateOptionsMenu(Menu, MenuInflater), but this method seems to never be called
You can have a look at the commit that is supposed to add that menu on GitHub. (Or even look at any part of the code that might be a cause of error.)
Here are the big lines:
CrimeFragment.java:
public class CrimeFragment extends Fragment {
// ...
#Override
public void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate()");
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
UUID id = (UUID) getArguments().getSerializable(ARG_CRIME_ID);
Log.d(TAG, String.format("Crime id in intent's extra: %s", id.toString()));
mCrime = CrimeLab.get(getActivity()).getCrime(id);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
Log.d(TAG, "onCreateOptionsMenu()"); // <= Never shows in the Android Monitor
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.fragment_crime, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_delete_crime:
CrimeLab.get(getActivity()).deleteCrime(mCrime);
getActivity().finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
// ...
}
Is there something I'm doing wrong here?
Alright, it took me the time, but I finally found what was wrong with my code. This was a bit tricky.
In an earlier change, I overrode FragmentStatePagerAdapter#setPrimaryItem() in the hosting activity, in order to be informed every time the user switches between pages.
Unfortunately, in that override, I forgot to call super, and that's what was confusing the application, apparently.
I just had to add that call to super, and my menu item suddenly started to show up.
public class CrimePagerActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_crime_pager);
// ...
FragmentManager fragmentManager = getSupportFragmentManager();
mViewPager.setAdapter(new FragmentStatePagerAdapter(fragmentManager) {
// ...
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object); // <= This line was missing
Crime crime = mCrimes.get(position);
mChangedCrimeIds.add(crime.getId());
}
});
mViewPager.setCurrentItem(CrimeLab.get(this).getPosition(crimeId));
}
// ...
}

How can I control the activity's up button from a contained fragment?

I'm building a pretty simple app. At it's core are 2 screens:
1) list-screen: a list of items
2) detail-screen: a detailed view of an item
I used one Activity (which extends AppCompatActivity) with an Action-Bar, a Navigation-Drawer and a main-content part (a FrameLayout).
I used 2 different fragments for the 2 screens:
When opening the app I inflate the list-fragment into the main-content part.
When an item in the list is clicked I inflate the detail-fragment into the main-content part and it all works well.
On the detail-screen I want the Action-Bar to display an up-button that goes back to the list-screen.
Considering the fact that I am using fragments, rather than separate activites, how can I achieve that?
You can enable the up button each time the Detail Fragment loads, and disable it whenever any of the other Fragments load.
First define these methods in your Activity, which you can call from the Fragments in order to show/hide the up button:
public void showUpButton() {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
public void hideUpButton() {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
}
You will probably want to just enable the up button in on Resume() of the detail Fragment (MainActivity is just an example, change to the name of your Activity) .....
#Override
public void onResume() {
super.onResume();
MainActivity activity = (MainActivity)getActivity();
if (activity != null) {
activity.showUpButton();
}
}
Then in the other Fragments:
#Override
public void onResume() {
super.onResume();
MainActivity activity = (MainActivity)getActivity();
if (activity != null) {
activity.hideUpButton();
}
}
The next thing is to make the up button actually go back. First ensure that you're adding the Fragment with the up button to the back stack, and then add this to that Fragment.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
((MainActivity)getActivity()).onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Then in the Activity, override onBackPressed() and pop from the back stack if the FragmentManager has any entries:
#Override
public void onBackPressed() {
FragmentManager fragmentManager = getSupportFragmentManager();
if (fragmentManager.getBackStackEntryCount() > 1) {
fragmentManager.popBackStackImmediate();
} else {
super.onBackPressed();
}
}

Action items from Viewpager initial fragment not being displayed

In the application I am developing I am using a ViewPager with fragments and each fragment constructs its own menu independently of all of the other fragments in the ViewPager.
The issue is that sometimes the fragments that are initialised by the ViewPager by default (i.e in it's initial state) are not having their items populated into the action items menu. What's worse is that this issue only occurs intermittently. If I swipe through the ViewPager enough so that the fragments are forced to re-initialise them selves, when I swipe back, the menu populates correctly.
Activity code:
package net.solarnz.apps.fragmentsample;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.os.Bundle;
import android.support.v13.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
public class FragmentSampleActivity extends Activity {
private ViewPagerAdapter mViewPagerAdapter;
private ViewPager mViewPager;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if (mViewPagerAdapter == null) {
mViewPagerAdapter = new ViewPagerAdapter(getFragmentManager());
}
mViewPager = (ViewPager) findViewById(R.id.log_pager);
mViewPager.setAdapter(mViewPagerAdapter);
mViewPager.setCurrentItem(0);
}
private class ViewPagerAdapter extends FragmentStatePagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return 8;
}
#Override
public Fragment getItem(int position) {
Fragment f = Fragment1.newInstance(position);
// f.setRetainInstance(true);
f.setHasOptionsMenu(true);
return f;
}
}
}
Fragment code:
package net.solarnz.apps.fragmentsample;
import android.app.Fragment;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
public class Fragment1 extends Fragment {
int mNum;
static Fragment newInstance(int num) {
Fragment1 f = new Fragment1();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
mNum = getArguments() != null ? getArguments().getInt("num") : 0;
}
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_list, menu);
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<android.support.v4.view.ViewPager
android:id="#+id/log_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Menu:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/menu_refresh"
android:title="Refresh"
android:icon="#android:drawable/ic_delete"
android:showAsAction="ifRoom|withText" />
</menu>
Action menu being populated:
http://i.stack.imgur.com/QFMDd.png
Action menu not being populated:
http://i.stack.imgur.com/sH5Pp.png
You should read this (by xcolw...)
Through experimentation it seems like the root cause is invalidateOptionsMenu getting called more than one without a break on the main thread to process queued up jobs. A guess - this would matter if some critical part of menu creation was deferred via a post, leaving the action bar in a bad state until it runs.
There are a few spots this can happen that aren't obvious:
calling viewPager.setCurrentItem multiple times for the same item
calling viewPager.setCurrentItem in onCreate of the activity. setCurrentItem causes an option menu invalidate, which is immediately followed by the activity's option menu invalidate
Workarounds I've found for each
Guard the call to viewPager.setCurrentItem
if (viewPager.getCurrentItem() != position)
viewPager.setCurrentItem(position);
Defer the call to viewPager.setCurrentItem in onCreate
public void onCreate(...) {
...
view.post(new Runnable() {
public void run() {
// guarded viewPager.setCurrentItem
}
}
}
After these changes options menu inside the view pager seems to work as expected. I hope someone can shed more light into this.
source http://code.google.com/p/android/issues/detail?id=29472
The simple answer is to not use menus within fragments in the ViewPager.
If you do need to use menus within the fragments, what I suggest is loading the menu's through the onCreateOptionsMenu method in the parent Activity. Obviously you will need to be able to determine which menu to show.
I was able to achieve this by using class reflection.
You will also need to use the invalidateOptionsMenu method each time you switch pages. You will need a OnPageChangeListener to call this when the ViewPager changes pages.
I also had same issue. In my case I have one activity with viewpager that contains two fragments, every fragment inflate its own action menu but fragment actions menu not shown.
View pager adapter code
public class ScreensAdapter extends FragmentPagerAdapter {
public TrackerScreensAdapter(Context context, FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return 2;
}
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position){
case 0:
fragment = new Fragment1();
break;
case 1:
fragment = new Fragment2();
break;
}
return fragment;
}
}
Activity on create
screensAdapter = new ScreensAdapter(this, getFragmentManager());
viewPager.setAdapter(screensAdapter);
This way my viewPager has two fragments, every fragment fire its own task in onActivityCreated, obtain data and draw its layout based on obtained data. Also every fragment has onCreateOptionsMenu
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
MyTask task = new MyTask();
task.setTaskListener(this);
task.execute();
}
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_menu, menu);
}
Spent many times to solve this problem and figure out why fragment menu not shows.
All that I was need is
screenAdapter = new ScreenAdapter(this, getFragmentManager());
viewPager.post(new Runnable() {
public void run() {
viewPager.setAdapter(screenAdapter);
}
});
In my case I traced the root cause of the issue to what I believe is a bug in FragmentStatePagerAdapter which is calling Fragment#setMenuVisibility to false and failing to properly set it back to true when it restores it's state.
Workarounds:
Use FragmentPagerAdapter instead of FragmentStatePagerAdapter
If you must use FragmentStatePagerAdapter, in your adapter subclass override setPrimaryItem like so:
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
//This is a workaround for a bug in FragmentStatePagerAdapter
Fragment currentItem = getItem(position);
if (currentItem != null) {
currentItem.setMenuVisibility(true);
currentItem.setUserVisibleHint(true);
}
}
First create a method in the sub class of FragmentPagerAdapter to get the current fragment
public SherlockFragment getFragment() {
return currentFragment;
}
#Override
public void onTabSelected(final Tab tab, FragmentTransaction ft) {
((SherlockFragmentActivity) mContext).invalidateOptionsMenu();
Fragment f = ((SherlockFragmentActivity) mContext)
.getSupportFragmentManager().findFragmentByTag(
makeFragmentName(tab.getPosition()));
currentFragment=(SherlockFragment) f;
}
Now override below methods in Main Actvity
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (mTabsAdapter.getPositionOfTabSelected() != 0) {
menu.add("Read").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.add("Write").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.add("Clear").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.add("Factory data reset").setShowAsAction(
MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
return super.onCreateOptionsMenu(menu);
}
Now call the onOptionItemSelected from activity to fragment
#Override
public boolean onOptionsItemSelected(MenuItem item) {
mTabsAdapter.getFragment().onOptionsItemSelected(item);
return super.onOptionsItemSelected(item);
}
I solved a very similar issue in which the Action bar icons assigned by the fragment inside of a ViewPager were disappearing onPause(). They would reappear when the Fragment came back into view and the user swiped left or right, but not immediately. The solution was calling notifyDataSetChanged() on the PagerAdapter in the onResume() method of the fragment.
#Override
public void onResume() {
mPagerAdapter.notifyDataSetChanged();
}
I was having this problem with the Action Bar Items while I was using HorizontalScrollView to show the tabs but I changed to PagerTitleStrip and the problem was solved.
Perhaps this information can help someone else.
My solution to this problem was to only inflate fragment menus if the fragment is currently visible. This solution may be too specific for your purposes, but it might help someone.
In the main activity:
boolean isFragmentVisible(int fragmentIndex) { ... }
In onCreateOptionsMenu() in your fragment:
if ( getActivity().isFragmentVisible(HOME_FRAGMENT_POS) ) {
inflater.inflate(R.menu.menu_home_fragment, menu);
}

android action bar onNavigationItemSelected

I'm developing for android 3+
In my action bar i have a drop-down list(see how to hide/unhide the actionbar list on android 3? for the dropdown i intend). The problem is i need to do a certain action when the user selects something, but Android calls onNavigationItemSelected() as soons as it draws the view, so no selection actually happened.
How can i detect if the user actually pressed something and it is not a fake call from android ?
public class ListDittaListener implements OnNavigationListener{
private BaseActivity activity;
private ListDittaListener()
{
}
public ListDittaListener(BaseActivity activity)
{
this.activity = activity;
}
#Override
public boolean onNavigationItemSelected(int itemPosition, long itemId)
{
MyApp appState = ((MyApp)this.activity.getApplicationContext());
appState.setDittaSelezionata( (int) itemId);
SharedPreferences settings = this.activity.getSharedPreferences(MyApp.PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putInt("ditta_id_selezionata", (int) itemId);
////////restart activity this.activity.recreate();
return false;
}
}
You can easily just ignore the first call to onNavigationItemSelected if you like:
public class Whatever implements OnNavigationListener {
private boolean synthetic = true;
#Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
if (synthetic) {
synthetic = false;
return true;
}
// do whatever you really wanted here
}
}
Method onNavigationItemSelected(int itemPosition, long itemId) will be called anyway by the action bar.
What you may want to do is to tell action bar what itemPosition it should pass to the method on the first call. (In other words, to tell action bar what navigation item should be set after activity is created). Here is the code:
mActionBarMenuSpinnerAdapter = ...;
mActionBar = getActionBar();
mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
mActionBar.setListNavigationCallbacks(mActionBarMenuSpinnerAdapter, this);
mActionBar.setSelectedNavigationItem(###your_default_navigation_item_here###);
After doing this you can solve your problem by applying changes in the onNavigationItemSelected(int itemPosition, long itemId) if only itemPosition is different.
The android system will call onNavigationItemSelected(0, 0) after the activity is setup. (Which means later than onResume()).
As other guys mentioned, you'd better not do any hack like ignore first call, otherwise the android system won't call onNavigationItemSelected() again when you select the first index. (The system thought the first item is already selected)
My solution is call actionbar.setSelectedNavigationItem(the real item# you want) after you setup the actionbar. Then the system will call onNavigationItemSelected() twice. First onNavigationItemSelected(0, 0) and then the onNavigationItemSelected(the real item#).
Well I cannot see anything wrong in your current code.
How did you create your dropdown elements. And what element is "select" by Android after the view is created. And what are your doing in your onCreate method where the ActionBar is initialized.
I did it as instructed here and it worked for me:
http://developer.android.com/guide/topics/ui/actionbar.html#Dropdown
I have viewpager with fragments and I need set custom action bar for every fragment in pager
In desired page I have navigation list, fragment fires onNavigationItemSelected automatically when I swipe pages, want to avoid this behavior and run tasks only if I selected nav item manually.
public class MyFragment extends Fragment implements ActionBar.OnNavigationListener {
private boolead fireReady = false;
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
// every time make it false, this method invoked on swipe action
fireReady = false;
if (isVisibleToUser) {
// setup actionbar, you also can setup action bar in activity
String[] array = getActivity().getResources().getStringArray(R.array.users_order);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_item, array);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
getActivity().getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
getActivity().getActionBar().setListNavigationCallbacks(adapter, this);
}
}
#Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
if (fireReady) {
// task fire only when you directly press navigation item
UsersTask task = new UsersTask(getActivity());
task.setTaskListener(this);
task.execute(usersUrls[itemPosition]);
} else {
// make it true first time when page displayed
fireReady = true;
}
return false;
}
}
}

Categories

Resources