I have two fragments one is list fragment and the other one i'm using it as dialog once and as fragment my problem here with option menu, in list fragment there's an item menu given show always action and in dialog fragment i don't want this item to be visible and i don't want option menu to be visible too, i have tried to
setHasOptionMenu(false)
but it didn't work and tried to setHasOptionMenu(true) and clear all items in menu but it didn't work neither.
Also, my parent activity doesn't have any code for option menu.
here's my code:
#SuppressLint("InflateParams")
public class FormGeneratorActivity extends DialogFragment {
Control mControl;
boolean doChangeTitle;
private boolean isDialog;
public static int CreatedNum = 0;
public static FormGeneratorActivity getInstance(Control mControl, boolean doChangeTitle) {
FormGeneratorActivity frag = new FormGeneratorActivity();
Bundle b = new Bundle();
b.putParcelable("control", mControl);
b.putBoolean("changeTitle", doChangeTitle);
frag.setArguments(b);
return frag;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
doChangeTitle = getArguments().getBoolean("changeTitle");
}
setHasOptionsMenu(false);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
#Override
public void onPrepareOptionsMenu(Menu menu) {
menu.clear();
activity.invalidateOptionsMenu();
super.onPrepareOptionsMenu(menu);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
}
public void setDoChangeTitle(boolean doChangeTitle) {
this.doChangeTitle = doChangeTitle;
}
View view;
boolean isInflated = false;
ParentActivity activity;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (view == null) {
mControl = getArguments().getParcelable("control");
view = inflater.inflate(R.layout.form_generator_fragment, container, false);
container = (LinearLayout) view.findViewById(R.id.cont);
isInflated = true;
} else {
if (view.getParent() != null)
((ViewGroup) view.getParent()).removeAllViews();
isInflated = false;
}
return view;
}
String headerPageTitle = null;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
activity = (ParentActivity) getActivity();
activity.getSupportActionBar().invalidateOptionsMenu();
CreatedNum++;
}
#Override
public void onResume() {
super.onResume();
activity.setPageTitle(headerPageTitle);
setHasOptionsMenu(false);
activity.getSupportActionBar().invalidateOptionsMenu();
}
public void isDialog(boolean b) {
isDialog = b;
}
}
Option menu in DialogFragment(Fragment) with Search(SearchView) action:
MenuDialogFragment.class
public class MenuDialogFragment extends DialogFragment {
Toolbar toolbar;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.custom_dialog_layout, container, false);
toolbar = view.findViewById(R.id.custom_dialog_layout_toolbar);
toolbar.inflateMenu(R.menu.menu_custom_dialog);
Menu menu = toolbar.getMenu();
SearchView searchView = (SearchView) menu.findItem(R.id.menu_searchview).getActionView();
// DO whatever you need with menu items
return view;
}
}
menu_custom_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<item
android:id="#+id/menu_searchview"
android:icon="#drawable/ic_search"
android:title="Search"
app:showAsAction="always|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"
/>
</menu>
custom_dialog_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.v7.widget.Toolbar
android:id="#+id/custom_dialog_layout_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
/>
</LinearLayout>
you can try to set parent fragment like: fragment.setTargetFragment(getSupportFragmentManager().findFragmentById(R.id.frame), 1);
and in child fragment you perform (in onAttach/onDetach methods)
getTargetFragment().setMenuVisibility(true);
Maybe try to use one of the dialog themes when you call this fragment as dialog.
To do this you can use this constructor:
AlertDialog.Builder(Context context, int theme)
ie
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(),
theme)
Some more explanation:
Theme not applying to DialogFragment on Android
i found out that dialog fragment only needs time to know that the option menu doesn't exist any more so i had to post delay using handler before i start the fragment
Related
I'm doing a mobile application in Android with JAVA using a DialogFragment with Toolbar.
I want to hide a menu item conditionally.
Menu
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/action_favorite"
android:title="favorite"
android:icon="#drawable/ic_favorite_white_off_24dp"
app:showAsAction="always" />
<item
android:id="#+id/action_delete"
android:title="delete"
android:icon="#drawable/ic_delete_white_24dp"
app:showAsAction="always" />
<item
android:id="#+id/action_save"
android:title="save"
app:showAsAction="always" />
</menu>
Layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:paddingStart="6dp"
android:paddingEnd="16dp"
app:contentInsetStartWithNavigation="0dp"
app:navigationIcon="#drawable/ic_close_black_24dp" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<!-- EditText's and buttons ..... -->
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
DialogFragment
public class MyDialogFragment extends DialogFragment implements Toolbar.OnClickListener, Toolbar.OnMenuItemClickListener {
public static final String TAG = "my_dialog";
private Toolbar toolbar;
public static MyDialogFragment display(FragmentManager fragmentManager) {
NewPersonDialogFragment exampleDialog = new NewPersonDialogFragment();
exampleDialog.show(fragmentManager, TAG);
return exampleDialog;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(NewPersonDialogFragment.STYLE_NORMAL, R.style.AppTheme_FullScreenDialog);
}
#Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
if (dialog != null) {
int width = ViewGroup.LayoutParams.MATCH_PARENT;
int height = ViewGroup.LayoutParams.MATCH_PARENT;
dialog.getWindow().setLayout(width, height);
dialog.getWindow().setWindowAnimations(R.style.AppTheme_Slide);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.dialog_fragment_new_person, container, false);
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
toolbar = view.findViewById(R.id.toolbar);
toolbar.inflateMenu(R.menu.new_person_dialog_menu);
toolbar.setNavigationOnClickListener(this);
toolbar.setOnMenuItemClickListener(this);
toolbar.setTitle("Add new");
}
#Override
public void onClick(View v) {
// This is working fine
}
#Override
public boolean onMenuItemClick(MenuItem item) {
// This is working fine
switch (item.getItemId()) {
case R.id.action_favorite:
return true;
case R.id.action_delete:
return true;
case R.id.action_save:
return true;
default:
return false;
}
}
#Override
public void onCreateOptionsMenu(#NonNull Menu menu, #NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
// Removing item doesn't work!
menu.removeItem(R.id.action_delete);
}
}
I open the DialogFragment like this:
MyDialogFragment.display(getActivity().getSupportFragmentManager());
When I open the DialogFragment, the menu item is not hidden.
As other topics says, I have tried:
setHasOptionsMenu(true) in onActivityCreated method.
getActivity().invalidateOptionsMenu() in onPrepareOptionsMenu method.
My goal is to hide/remove a menu item based on a condition when the user opens the DialogFragment.
I am trying to add ActionBar (Toolbar) inside fragment and then set Button to "end" of this action bar and add onClickListener on that button.
Cannot use support.v7.widget.ToolBar (I dont know why but I could not implement it)so I had to use androidx.appcompat.widget.Toolbar instead.
I could not find any source to follow.
app_bar_layout.xml:
<androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_app_toolbar"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
</androidx.appcompat.widget.Toolbar>
Fragment's design fragment_wall.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".WallFragment"
android:background="#color/colorWhite">
<include
android:id="#+id/update_wall_page_toolbar"
layout="#layout/app_bar_layout"></include>
</FrameLayout>
Code in WallFragment.java
public class WallFragment extends Fragment {
public WallFragment() {
// Required empty public constructor
}
private Toolbar TopActivityToolbar;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_wall, container, false);
TopActivityToolbar = v.findViewById(R.id.update_wall_page_toolbar);
TopActivityToolbar.setTitle("Príspevky");
TopActivityToolbar.setLogo(ContextCompat.getDrawable(getActivity(),R.drawable.ic_add_circle_black_24dp));
return v;
}
}
so what was the successfull answer for me:
Inside onCreate method just add setHasOptionsMenu(true);
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Inside my WallFragment.java in onCreateView I added setOnMenuItemClickListener just right after initializing the Toolbar
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View inflatedView = inflater.inflate(R.layout.fragment_wall, container, false);
TopActivityToolbar = inflatedView.findViewById(R.id.update_wall_page_toolbar);
TopActivityToolbar.setTitle("someTitle");
TopActivityToolbar.inflateMenu(R.menu.menu_app_actionbar_wall);
// and finally set click listener
TopActivityToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
// Your code inside Toolbar onClick...
return false;
}
});
return inflatedView;
}
Do not forget to to INFLATE the menu from res/menu/...
Add Toolbar inside fragment (AndroidX),you should use the onCreateOptionsMenu() method inside fragment.
#Override
public void onCreateOptionsMenu(
Menu menu, MenuInflater inflater) {inflater.inflate(R.menu.example_menu, menu);
}
First,you have to call setHasOptionsMenu() within the fragment's onCreate() method:
setHasOptionsMenu(true);
//For handling item selection
You can handle menu item clicks in the onOptionsItemSelected() method:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.itemId:
//action
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Full Example code is below:
In this example One activity: Main activity:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="200dp"
android:id="#+id/fragment_id"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click"
android:onClick="changeFragment"
android:layout_gravity="center"/>
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
FrameLayout frameLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadFragment(new FirstFragment());
}
private void loadFragment(Fragment fragment) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_id, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
public void changeFragment(View view) {
loadFragment(new SecondFragment());
}
}
There is two fragment in this example:
FirstFragment and SecondFragment.
FirstFragment.java :
public class FirstFragment extends Fragment {
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.first_layout,container,false);
return view;
}
#Override
public void onCreateOptionsMenu(
Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.first_item_menu, menu);
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
//For handling item selection
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.itemId:
Toast.makeText(getContext(),"First Fragment item",Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
SecondFragment.java
public class SecondFragment extends Fragment {
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.second_frag,container,false);
return view;
}
#Override
public void onCreateOptionsMenu(
Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.second_item_menu, menu);
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
//For handling item selection
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.itemId1:
Toast.makeText(getContext(),"Second Fragment item",Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
In menu file,app:showAsAction="ifRoom" in your menu item.Below is example code for menu file.
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/itemId"
android:icon="#drawable/ic_apps_black_24dp"
android:title="First"
app:showAsAction="ifRoom">
</item>
</menu>
First of all, to make it work you need to call this code in onCreateView callback of fragment that is needed to have a menu;
setHasOptionsMenu(true);
Then you are able to inflate the menu and set listener to handle clicks on item:
inflater.inflate(*R.menu.your_menu_resource*, menu);
After that you are able to override onCreateOptionsMenu and onOptionsItemSelected to provide logic that is needed:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.toolbar, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.toolbar_seetings) {
Toast.makeText(getContext(), "Menu item was clicked", Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
After that you just need to handle App Bar visibility, so you need to place the code in onCreateView and it will look like that:
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setHasOptionsMenu(true);
((AppCompatActivity) getActivity()).getSupportActionBar().show();
return inflater.inflate(R.layout.fragment_home, container, false);
}
I am working with ViewPager with Circle Page Indicator.
And I am following this link for sample
Here in below I mentioned my class details.
HelpScreen.java
This Activity had one fragment called HelpScreenFragment.java
public class HelpScreen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.help_screen);
HelpScreenFragment helpScreenFragment = new HelpScreenFragment();
FragmentTransaction transaction = getFragmentManager()
.beginTransaction().add(R.id.frame_helpscreen_container,
helpScreenFragment);
transaction.commit();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.help_screen, 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();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
help_screen.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<FrameLayout
android:id="#+id/frame_helpscreen_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
SlidePagerAdapter.java
This class extends PagerAdapter and used to inflate the
public class SlidePagerAdapter extends PagerAdapter {
ImageView helpScreenImage;
List<Integer> drawableBitmap;
int gallery_grid_Images[] = { R.drawable.sample1, R.drawable.sample2,
R.drawable.sample3, R.drawable.sample4, R.drawable.sample5, };
private Context mContext;
Activity activity;
public SlidePagerAdapter(Activity mContext) {
super();
this.activity = mContext;
}
#Override
public int getCount() {
return 0;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.viewpager_layout, container,
false);
helpScreenImage = (ImageView) view.findViewById(R.id.helpscreen_image);
helpScreenImage.setImageResource(gallery_grid_Images[position]);
((ViewPager) container).addView(helpScreenImage);
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
}
viewpager_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/helpscreen_image"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
HelpScreenFragment.java
public class HelpScreenFragment extends Fragment {
ViewPager helpScreenPager;
CirclePageIndicator mCirclePageIndicator;
SlidePagerAdapter mSlidePagerAdapter;
Activity activity;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity = getActivity();
};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.helpscreen_fragment, container,
false);
initializeWidgets(view);
mSlidePagerAdapter = new SlidePagerAdapter(activity);
helpScreenPager.setAdapter(mSlidePagerAdapter);
mCirclePageIndicator.setViewPager(helpScreenPager);
return view;
}
private void initializeWidgets(View view) {
helpScreenPager = (ViewPager) view.findViewById(R.id.pager);
mCirclePageIndicator = (CirclePageIndicator) view
.findViewById(R.id.page_indicator);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
And in helpscreen_fragment.xml contains only ViewPager and CirclePageIndicator
helpscreen_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.example.viewpagerdemo"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!--
<ViewFlipper
android:id="#+id/helpscreen_flipper"
android:layout_width="match_parent"
android:layout_height="match_parent" /> -->
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.example.viewpagerdemo.CirclePageIndicator
android:id="#+id/page_indicator"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/view_pager"
android:padding="10dip" />
</FrameLayout>
When executing the project I am getting only blank screen.
What I did wrong? What changes have to made.
Could anybody help on this?
[1]: http://androidopentutorials.com/android-image-slideshow-using-viewpager/
[2]: http://i.stack.imgur.com/pSold.jpg
Here
#Override
public int getCount() {
return 0;
}
Currently getCount method of SlidePagerAdapter retuning 0 so no item is visible in ViewPager. return gallery_grid_Images array size from getCount() :
#Override
public int getCount() {
return gallery_grid_Images.length;
}
I have a small problem with my application which uses a FragmentStatePagerAdapter when scrolling between pages.
First I'll describe how the application is built with a stripped down version.
App description
I have one Activity which holds everything together. This Activity in turn hosts a Fragment, in this case called Pager.
This Pager-class has a ViewPager within, with a FragmentStatePagerAdapter as an inner class which is used to provide the fragments for the ViewPager. The fragments provided to the ViewPager are instances of FragmentA.
FragmentA has its own content and its own items on the ActionBar, but can also in turn open other fragments. In my "Real" application this can be done either by clicking some item in a ListView or by clicking a button on the ActionBar. In this simplified case FragmentA can open up FragmentB via a button.
So far this works just as it should.
Problem
When FragmentB is opened from any of the FragmentA-fragments it is properly displayed with its own content and menu in the ActionBar, replacing the menu of FragmentA. However, when navigating back via the back-button the ActionBar for FragmentA is never restored to the state the FragmentA-actionbar had prior to opening FragmentB, instead it's empty.
Possibly strange behaviour
When I change so that MainPagerAdapter extends FragmentPagerAdapter instead of FragmentStatePagerAdapter, all of a sudden it works just fine, and I really don't understand why this is. Also, manually calling supportInvalidateOptionsMenu() did not work at all when the Fragment was contained within a FragmentStatePagerAdapter.
I looked in to the source of both of the adaptertypes but I couldn't figure out why one of them worked while the other didn't.
MainActivity.java
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager()
.beginTransaction()
.addToBackStack("Start")
.replace(R.id.container, new Pager())
.commit();
}
public void openB() {
getSupportFragmentManager()
.beginTransaction()
.addToBackStack("Start1")
.replace(R.id.container, new FragmentB())
.commit();
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/container">
</RelativeLayout>
Pager.java
public class Pager extends Fragment {
ViewPager mViewPager;
MainPagerAdapter mainPagerAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
setHasOptionsMenu(true);
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.wrapper_layout, null);
mViewPager = (ViewPager)v.findViewById(R.id.viewpager);
mainPagerAdapter = new MainPagerAdapter(getChildFragmentManager());
mViewPager.setAdapter(mainPagerAdapter);
return v;
}
private class MainPagerAdapter extends FragmentStatePagerAdapter {
public MainPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return new FragmentA();
}
#Override
public int getCount() {
return 2;
}
}
}
wrapper_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
FragmentA.java
public class FragmentA extends Fragment {
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
menu.add("A-Menu");
}
#Override
public void onCreate(Bundle savedInstanceState) {
setHasOptionsMenu(true);
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.a, null);
Button b = (Button)v.findViewById(R.id.button2);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().supportInvalidateOptionsMenu();
}
});
Button b2 = (Button)v.findViewById(R.id.button);
b2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((MainActivity)getActivity()).openB();
}
});
return v;
}
}
a.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="B"
android:id="#+id/button"
android:layout_gravity="center_horizontal"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Invalidate"
android:id="#+id/button2"
android:layout_gravity="right"
/>
</LinearLayout>
FragmentB.java
public class FragmentB extends Fragment{
#Override
public void onCreate(Bundle savedInstanceState) {
setHasOptionsMenu(true);
super.onCreate(savedInstanceState);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
menu.add("B-Menu");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.b, null);
return v;
}
}
I want to show a Button and a PieChart below in a tab.
Thats the code I worked with: https://github.com/JakeWharton/ActionBarSherlock/blob/master/samples/fragments/src/com/actionbarsherlock/sample/fragments/FragmentTabs.java
Instead of the CountingFragment etc. I implemented my own.
I'm not sure what to
My xml:
fragment_graph_categories.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_graph_categories"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/button_filter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_filter" />
</LinearLayout>
And that's my "Tab" attached to the TabManger
public class GraphCategories extends SherlockFragmentActivity {
GraphCategoriesFragment mCategoriesFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_graph_categories);
if (savedInstanceState == null) {
// Do first time initialization -- add initial fragment.
mCategoriesFragment = GraphCategoriesFragment.newInstance(1);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.fragment_graph_categories, mCategoriesFragment).commit();
} else {
//mStackLevel = savedInstanceState.getInt("level");
}
}
#Override
protected void onResume() {
if(mCategoriesFragment != null) {
//mCategoriesFragment.onResumeRedraw();
}
}
//notice Inner class
public static class GraphCategoriesFragment extends SherlockFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//View mChartView = inflater.inflate(R.layout.hello_world, container, false);
View rlayout = inflater.inflate(R.layout.fragment_graph_categories, container, false);
//? rlayout = new LinearLayout(getActivity());
return rlayout;
}
}
}
But im not sure what to inflate at the fragments onCreateView or if I need a FrameLayout in my xml?
I tried some options but don't figured it out.