I am using ActionBarSherlock to display fragmented tabs on Android 2.2
The problem I am having is that I am not able to display my custom OptionsMenu on the Google Maps fragment. I set setHasOptionsMenu(true); in the onCreate method, but it still does not appear.
This is my google maps fragment3.java
public class Fragment3 extends SherlockFragment {
private MapView mMapView;
private int group1Id = 1;
int homeId = Menu.FIRST;
int profileId = Menu.FIRST +1;
int searchId = Menu.FIRST +2;
int dealsId = Menu.FIRST +3;
int helpId = Menu.FIRST +4;
int contactusId = Menu.FIRST +5;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment3, container, false);
mMapView = (MapView) view.findViewById(R.id.mapview);
// inflat and return the layout
mMapView.onCreate(savedInstanceState);
mMapView.onResume();// needed to get the map to display immediately
try {
MapsInitializer.initialize(getActivity());
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
GoogleMap googleMap = mMapView.getMap();
googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
googleMap.moveCamera( CameraUpdateFactory.newLatLngZoom(new LatLng(54.902815,23.9500459) , 16.0f) );
// googleMap.setMyLocationEnabled(true);
googleMap.getUiSettings().setZoomControlsEnabled(true);
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
setHasOptionsMenu(true);
}
/*
* Using a mapview in a fragment requires you to 'route'
* the lifecycle events of the fragment to the mapview
*/
#Override
public void onResume() {
super.onResume();
if (null != mMapView)
mMapView.onResume();
}
#Override
public void onPause() {
super.onPause();
if (null != mMapView)
mMapView.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
if (null != mMapView)
mMapView.onDestroy();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (null != mMapView)
mMapView.onSaveInstanceState(outState);
}
#Override
public void onLowMemory() {
super.onLowMemory();
if (null != mMapView)
mMapView.onLowMemory();
}
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(group1Id, homeId, homeId, "").setIcon(R.drawable.action_about);
menu.add(group1Id, profileId, profileId, "").setIcon(R.drawable.action_about);
menu.add(group1Id, searchId, searchId, "").setIcon(R.drawable.action_about);
menu.add(group1Id, dealsId, dealsId, "").setIcon(R.drawable.action_about);
menu.add(group1Id, helpId, helpId, "").setIcon(R.drawable.action_about);
menu.add(group1Id, contactusId, contactusId, "").setIcon(R.drawable.action_about);
return onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 1:
........
case 6:
//code here
default:
break;
}
return super.onOptionsItemSelected(item);
}
}
does it not appear because it's in a fragment? Is there any way I can enable my own custom menu inside the google map fragment?
All answers and discussions are welcome,
let me know if you need to view any of my adapter classes that handle the fragments, or the .xml files.
you could try to save your menu in menu folder and can inflate that menu like this
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main, menu);
super.onCreateOptionsMenu(menu, inflater);
}
Related
I'm trying to build with only fragments.
The App opens with a Activity blank that only has a ActionBar upon clicking the hamburger icon it opens a drawer that give you a menu option.
Upon clicking on one of the Menu Items it opens the First Fragment which has a Recycler/Card View. Upon clicking one of the Cards it opens a new fragment with more details of the selected cards.
Now the problem is the detail fragment shows home icon cause I enable setDisplayHomeAsUpEnabled(true) but when I click on the back arrow it does not do anything. The hardware back button does take me back to the previous (Recycler/Card View) fragment.
I also have setHasOptionsMenu(true) in the detail fragment.
I put log tags everywhere to see when the home button reacts but nothing.
Hope someone can give me a hand.
Activity:
public class AppStart extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
ActionBarDrawerToggle actionBarDrawerToggle;
final String TAG = "AppSart: onBackPressed";
final String TAG1 = "AppSart: resetActionBar";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_app_start);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
#Override
public void onBackPressed() {
int stack = getSupportFragmentManager().getBackStackEntryCount();
Log.d(TAG,Integer.toString(stack));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return false;
}
public void resetActionBar(boolean childAction)
{
Log.d(TAG1,Boolean.toString(childAction));
if (childAction) {
actionBarDrawerToggle.setDrawerIndicatorEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} else {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
actionBarDrawerToggle.setDrawerIndicatorEnabled(true);
}
}
}
Recycler Fragment:
public class ProductFragment extends Fragment {
final String TAG1 = "ProdFrag: onCreate";
final String TAG2 = "ProdFrag: onCreateView";
final String TAG3 = "ProdFrag: onResume";
final String TAG6 = "ProdFrag: ActionSetting";
final String TAG7 = "ProdFrag: home";
public ProductFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
int stack = getActivity().getSupportFragmentManager().getBackStackEntryCount();
Log.d(TAG1,Integer.toString(stack));
boolean canback = stack>0;
((AppStart)getActivity()).resetActionBar(canback);
}
#Override
public void onResume() {
super.onResume();
int stack = getActivity().getSupportFragmentManager().getBackStackEntryCount();
Log.d(TAG3,Integer.toString(stack));
boolean canback = stack>0;
((AppStart)getActivity()).resetActionBar(canback);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view=inflater.inflate(R.layout.fragment_product,container,false);
int stack = getActivity().getSupportFragmentManager().getBackStackEntryCount();
Log.d(TAG2,Integer.toString(stack));
return view;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Inflate the menu; this adds items to the action bar if it is present.
inflater.inflate(R.menu.toolbar_menu, menu);
super.onCreateOptionsMenu(menu,inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int stack = getActivity().getSupportFragmentManager().getBackStackEntryCount();
switch (item.getItemId()) {
case R.id.action_settings:
Log.d(TAG6,Integer.toString(stack));
return true;
default:
break;
}
return false;
}
}
Detail Fragment:
public class ProductTabsFragment extends Fragment {
final String TAG1 = "TabFrag: onCreate";
final String TAG2 = "TabFrag: onResume";
final String TAG3 = "TabFrag: ActionSettings";
final String TAG4 = "TabFrag: home";
final String TAG5 = "TabFrag: onBckStkChng";
final String TAG6 = "TabFrag: onNavigateUp";
public ProductTabsFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
int stack = getActivity().getSupportFragmentManager().getBackStackEntryCount();
Log.d(TAG1,Integer.toString(stack));
boolean canback = stack>0;
((AppStart)getActivity()).resetActionBar(canback);
}
#Override
public void onResume() {
super.onResume();
int stack = getActivity().getSupportFragmentManager().getBackStackEntryCount();
Log.d(TAG2,Integer.toString(stack));
boolean canback = stack>0;
((AppStart)getActivity()).resetActionBar(canback);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_product_tabs, container, false);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Inflate the menu; this adds items to the action bar if it is present.
inflater.inflate(R.menu.toolbar_menu, menu);
super.onCreateOptionsMenu(menu,inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int stack = getActivity().getSupportFragmentManager().getBackStackEntryCount();
switch (item.getItemId()) {
case R.id.action_settings:
Log.d(TAG3,Integer.toString(stack));
return true;
case android.R.id.home:
Log.d(TAG4,Integer.toString(stack));
//getActivity().onBackPressed();
return true;
default:
break;
}
return false;
}
}
Also this is the code in the recycler adapter for when a card is click to load the detail Fragment:
cvProduct.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
ProductTabsFragment productTabsFragment = new ProductTabsFragment();
AppCompatActivity activity = (AppCompatActivity) view.getContext();
FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container,productTabsFragment);
transaction.addToBackStack(null);
transaction.commit();
}
});
For those who might have this problem. Turns out that when ActionBarDrawerToggle is used setToolbarNavigationClickListener needs to be used for the backarrow.
The R.id.home in optionitemselected seems to be disabled. Hope this helps!
so what I did was remove from the onOptionsItemSelected(MenuItem item):
case android.R.id.home:
Log.d(TAG4,Integer.toString(stack));
return true;
and modified resetActionBar(boolean childAction) in the main Activity which is called in the oncreate of fragmentA and fragmentB.
public void resetActionBar(boolean childAction)
{
Log.d(TAG1,Boolean.toString(childAction));
if (childAction) {
actionBarDrawerToggle.setDrawerIndicatorEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
actionBarDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Log.d(TAG4,"Clicked");
onBackPressed();
}
});
} else {
getSupportActionBar().setHomeButtonEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
actionBarDrawerToggle.setDrawerIndicatorEnabled(true);
}
}
I was converting my UserListing Activity to a fragment when i received this error in myOnCreateOptionsMenu.
This is my Fragment Activity.
public class UserListingActivity extends Fragment implements LogoutContract.View {
private Toolbar mToolbar;
private TabLayout mTabLayoutUserListing;
private ViewPager mViewPagerUserListing;
private LogoutPresenter mLogoutPresenter;
public static void startActivity(Context context) {
Intent intent = new Intent(context, UserListingActivity.class);
context.startActivity(intent);
}
public static void startActivity(Context context, int flags) {
Intent intent = new Intent(context, UserListingActivity.class);
intent.setFlags(flags);
context.startActivity(intent);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
bindViews();
init();
setHasOptionsMenu(true);
return super.onCreateView(inflater, container, savedInstanceState);
}
// #Override
// protected void onCreate(Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_user_listing);
// bindViews();
// init();
// }
private void bindViews() {
mToolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
mTabLayoutUserListing = (TabLayout) getActivity().findViewById(R.id.tab_layout_user_listing);
mViewPagerUserListing = (ViewPager) getActivity().findViewById(R.id.view_pager_user_listing);
}
private void init() {
// set the toolbar
setSupportActionBar(mToolbar);
// set the view pager adapter
UserListingPagerAdapter userListingPagerAdapter = new UserListingPagerAdapter(getFragmentManager());
mViewPagerUserListing.setAdapter(userListingPagerAdapter);
// attach tab layout with view pager
mTabLayoutUserListing.setupWithViewPager(mViewPagerUserListing);
mLogoutPresenter = new LogoutPresenter(this);
}
// #Override
// public boolean onCreateOptionsMenu(Menu menu) {
// getActivity().getMenuInflater().inflate(R.menu.menu_user_listing, menu);
// return super.onCreateOptionsMenu(menu);
// }
#Override
public boolean onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
getActivity().getMenuInflater().inflate(R.menu.menu_user_listing, menu);
return super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_logout:
logout();
break;
}
return super.onOptionsItemSelected(item);
}
private void logout() {
new AlertDialog.Builder(this)
.setTitle(R.string.logout)
.setMessage(R.string.are_you_sure)
.setPositiveButton(R.string.logout, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
mLogoutPresenter.logout();
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.show();
}
#Override
public void onLogoutSuccess(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
LoginActivity.startIntent(this,
Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
}
#Override
public void onLogoutFailure(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
#Override
public void onBackPressed() {
super.onBackPressed();
startActivity(new Intent(this, MainActivity.class));
}
}
What has to be changed to solve this and what more has to be changed to covert it into a Fragment. I am beginner so detailed help would be appreciated.
Thanks
Method signature in fragment should be as below
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
The problem is with the return type of the method, make it void and error will be gone as the super-type returns void.
I am using options menu in message fragment where I can add friends from menu. I can navigate to this fragment from activity or fragment. When I launch this message fragment, menu is working fine. When I do navigate through other screen and come to message fragment menu disappears. After using/navigating in the application for 4-5 minutes, menu starts behaving randomly.
Strange behavior is, when I do launch message fragment from activity, menu always works well. This behaves randomly when I launch it from fragment.
Here is my code
public class MessagesFragment extends BaseFragment{
private static final String TAG = MessagesFragment.class.getSimpleName();
Context mContext;
View mView;
private ListView listBuddy;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mContext = activity;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
((InnerActivity)getActivity()).setActionbarTitle(getResources().getString(R.string.my_buddies));
View v = inflater.inflate(R.layout.fragment_messages, container, false);
listBuddy = (ListView) v.findViewById(R.id.listViewFindBuddy);
this.mView = v;
return v;
}
#Override
public void onDetach() {
// TODO Auto-generated method stub
super.onDetach();
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
}
#Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
}
#Override
public void onStop() {
// TODO Auto-generated method stub
super.onStop();
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
// TODO Auto-generated method stub
super.setUserVisibleHint(isVisibleToUser);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.messages, menu);
}
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.action_add:
break;
}
return super.onOptionsItemSelected(item);
}
Activity
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
return super.onPrepareOptionsMenu(menu);
}
add the following code in your activity :
#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;
}
For some reason the overflow dots do not appear on my tablet for my master detail application when I select a list item but yet they do on my handset. I'm not sure why is occurring despite using the necessary code. Does anyone there is any code missing or that shouldn't be there?
MainActivity.java
public class MainActivity extends ActionBarActivity {
private boolean mTwoPane;
#Override
protected void onCreate(Bundle savedInstanceState) {
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
if (menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
}
catch (Exception e) {
e.printStackTrace();
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getSupportActionBar();
actionBar.setTitle(getResources().getString(R.string.greeting));
FragmentMainList newFragment = new FragmentMainList();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.master_container, newFragment);
transaction.commit();
if (findViewById(R.id.detail_container) != null) {
mTwoPane = true;
}
}
}
Activity Class
public class MyProductActivity extends ActionBarActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_fragment);
if (savedInstanceState == null) {
FragmentProduct newFragment = new FragmentProduct();
FragmentTransaction transaction = this.getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.detail_container, newFragment);
transaction.commit();
}
ActionBar actionBar = getSupportActionBar();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.my_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
final Intent intent = NavUtils.getParentActivityIntent(this);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
NavUtils.navigateUpTo(this, intent);
return true;
}
return super.onOptionsItemSelected(item);
}
}
Fragment Class
public class FragmentProduct extends android.support.v4.app.Fragment {
public FragmentProduct() {}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_product, container, false);
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
View v = getView();
super.onActivityCreated(savedInstanceState);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
final Intent intent = NavUtils.getParentActivityIntent(getActivity());
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
NavUtils.navigateUpTo(getActivity(), intent);
return true;
}
int id = item.getItemId();
if (id == R.id.action_options) {
}
return super.onOptionsItemSelected(item);
}
}
The dots will be shown only for devices which don't have hardware Menu button. For devices with a hardware Menu button no overflow dots are shown since tapping on the menu button will do the same.
For more here
Edit
If for some reason you really want to show it, you can add below code in your Application.onCreate() or main (launcher) activity onCreate()
// force show actionbar 'overflow' button on devices with hardware menu button
try {
ViewConfiguration config = ViewConfiguration.get(this);
Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
if (menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
}
catch (Exception e) {
e.printStackTrace();
}
i implemented a contextual action mode bar in a nested fragement. This fragment is part of a view pager and the view pager is also a fragment and part of a navigation drawer.
My Problem: I want to close the contextual action mode bar if the fragment is no more focused. So, if I swipe through the view pager the action mode bar should close. But if I use the onPause() method of the nested fragment, the method is not called directly. Often it waits until i swiped two or three times forward... Here are some pictures:
In the second picture you can see that the action mode bar is still there. So my question is:
In which method should I call my actionModeBar.finish() method, to close directly the action mode bar if i leave the fragment?
Maybe the code of the fragment helps you:
public class EditorFragment extends Fragment {
private static final String KEY_POSITION="position";
ListView listView;
private boolean isMultipleList = false;
private ActionMode acMode;
private int counterChecked = 0;
private ActionMode.Callback modeCallBack = new ActionMode.Callback() {
public boolean onPrepareActionMode(ActionMode mode, Menu menu){
return false;
}
public void onDestroyActionMode(ActionMode mode) {
listView.clearChoices();
for (int i = 0; i < listView.getChildCount(); i++)
listView.setItemChecked(i, false);
listView.post(new Runnable() {
#Override
public void run() {
listView.setChoiceMode(ListView.CHOICE_MODE_NONE);
}
});
isMultipleList = false;
counterChecked = 0;
mode = null;
}
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.setTitle("1 Aufgabe");
mode.getMenuInflater().inflate(R.menu.actionmode, menu);
return true;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.actionmode_delete:
int choiceCount = listView.getCount();
SparseBooleanArray spBoolArray = listView.getCheckedItemPositions();
DBAufgaben db = new DBAufgaben(MainActivity.getMContext());
db.open();
for (int i = 0; i < choiceCount; i++) {
if(spBoolArray.get(i)){
db.deletContact(listView.getItemIdAtPosition(i));
}
}
Cursor cursor = db.getAllRecords();
AdapterEingang adapterE = new AdapterEingang(MainActivity.getMContext(), cursor, 0);
listView.setAdapter(adapterE);
db.close();
mode.finish();
break;
case R.id.actionmode_cancel:
mode.finish();
break;
}
return false;
}
};
//......//
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = null;
int position = getArguments().getInt(KEY_POSITION, -1);
switch(position){
case 0:
rootView = inflater.inflate(R.layout.pager_list, null);
listView = (ListView) rootView.findViewById(R.id.pager_list);
Context context = MainActivity.getMContext();
DBAufgaben db = new DBAufgaben(context);
db.open();
Cursor cursor = db.getAllRecords();
AdapterEingang adapterE = new AdapterEingang(context, cursor, 0);
listView.setAdapter(adapterE);
db.close();
listView.setOnItemLongClickListener(new OnItemLongClickListener(){
#Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view,
int position, long id) {
if(!isMultipleList){
acMode = MainActivity.getInstance().startActionMode(modeCallBack);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setItemChecked(position, true);
isMultipleList = true;
counterChecked++;
setNewTitle();
} else {
listView.setItemChecked(position, true);
counterChecked++;
setNewTitle();
}
return true;
}
});
listView.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position,
long id) {
Log.d(getTag(), "Datensatz: "+String.valueOf(id));
if(isMultipleList){
if(listView.isItemChecked(position)){
listView.setItemChecked(position, true);
counterChecked++;
setNewTitle();
} else {
listView.setItemChecked(position, false);
counterChecked--;
setNewTitle();
}
}
}
});
break;
default:
rootView = inflater.inflate(R.layout.frag_dummy, null);
TextView txt = (TextView) rootView.findViewById(R.id.dummy_txt);
txt.setText(String.valueOf(position));
break;
}
return(rootView);
}
public void setNewTitle(){
if(counterChecked == 1){
acMode.setTitle(counterChecked+" Aufgabe");
} else {
acMode.setTitle(counterChecked+" Aufgaben");
}
}
#Override
public void onPause(){
super.onPause();
if(isMultipleList){
acMode.finish();
}
}
}
ViewPagers keep multiple pages active at any one time (by default, the page before and page after the currently shown page), hence why onPause() is not called until you swipe two pages away.
Your best bet would be to use a ViewPager.OnPageChangeListener, and show and hide the ActionMode in onPageSelected(..) (i.e. if the page selected isn't the one with the ActionMode, hide the ActionMode). You'll likely have to implement this in the Activity which hosts your ViewPager.
Here's what worked for me --
Hold a static reference to the action mode in MyFragment:
public static ActionMode mActionMode;
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mActionMode = mode;
return true;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
}
Set ViewPager.OnPageChangeListener in MyViewPagerActivity.
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
....
#Override
public void onPageScrollStateChanged(int state) {
if(MyFragment.mActionMode != null) MyFragment.mActionMode.finish();
}
});
This worked for me:
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
if (!isVisibleToUser && this.listView != null) {
//HACK this is done in order to finish the contextual action bar
int choiceMode = this.listView.getChoiceMode();
this.listView.setChoiceMode(choiceMode);
}
}
I combined code from the OP with the override suggested by user pomber:
I save the ActionMode to a class field when the action mode is created.
I set the field back to null when the action mode is destroyed.
I override setUserVisibleHint in my fragment and call ActionMode#finish() if the fragment isn't visible in the view pager.
I also call ActionMode#finish() in the onPause() method of the fragment to close the fragment if the user navigates elsewhere.
Code:
#Nullable
ActionMode mActionMode = null;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Start out with a progress indicator.
setListShownNoAnimation(false);
setEmptyText(getText(R.string.no_forms_in_progress));
getListView().setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE_MODAL);
getListView().setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
// Here you can do something when items are selected/de-selected,
// such as update the title in the CAB
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context_saved_item, menu);
inflater.inflate(R.menu.context_instance_list, menu);
mActionMode = mode;
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.action_delete:
confirmDelete(getListView().getCheckedItemIds());
return true;
case R.id.action_print:
print(getListView().getCheckedItemIds());
return true;
}
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
}
});
}
#Override
public void onPause() {
super.onPause();
if (mActionMode != null) {
mActionMode.finish();
}
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (mActionMode != null && !isVisibleToUser) {
mActionMode.finish();
}
}
You can use the onDestroyOptionsMenu() method inside your Fragment:
public void onDestroyOptionsMenu() {
super.onDestroyOptionsMenu();
if (mActionMode != null) {
mActionMode.finish();
mActionMode = null;
}
}