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);
}
Related
The structure of my app , an Activity with fragments that use navigationcomponent.
In the toolbar of my HomeFragment there is a toolbar with a search icon as a menu. This clicked icon leads to the search activity.
HomeFragment
Browsing in my app and changing fragment up to the ProfileFragment, I have the opportunity to view my lists and clicking on one of these opens another fragment to show the contents of that list
ProfileFragment, ShowListContent.
Now here's the magic
If I click on the toolbar icon to change the description of my list everything is perfect and we are delighted but ...
New HomeFragment
If I go back to the HomeFragment, the icon in the toolbar is no longer the same and I cannot go to the SearchActivity.
What can I do to avoid this problem?
Code time
public class HomeFragment extends Fragment{
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View view = inflater.inflate(R.layout.fragment_home, container,
false);
initToolbar(view);
//other code
return view;
}
private void initToolbar(View view) {
Toolbar toolbar = view.findViewById(R.id.app_bar);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
toolbar.inflateMenu(R.menu.menu_main_toolbar);
}
#Override
public void onCreateOptionsMenu(#NotNull Menu menu, #NotNull MenuInflater
inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.menu_main_toolbar, menu);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
if (id == R.id.menu_search) {
Intent intent = new Intent(getActivity(), SearchActivity.class);
startActivity(intent);
}
return true;
}
}
fragment_home.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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:background="#141a32"
tools:context=".fragments.HomeFragment">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/app_bar"
style="#style/toolbar"
app:menu="#menu/menu_main_toolbar"
app:titleTextAppearance="#style/Toolbar.TitleText"
app:titleTextColor="#color/white" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/appBarLayout">
//other code
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
ShowContentListFragment
public class ShowContentListFragment extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View view = inflater.inflate(R.layout.fragments_layout_lists, container, false);
setHasOptionsMenu(true);
getDataFromSafeArgs();
initWidgets(view);
initToolbar();
return view;
}
private void initToolbar() {
toolbar.setVisibility(View.VISIBLE);
toolbar.setNavigationIcon(R.drawable.ic_friend_list_back_button);
toolbar.inflateMenu(R.menu.menu_profile_edit_list);
toolbar.setNavigationOnClickListener(v -> {
Navigation.findNavController(getView())
.navigate(R.id.action_showContentListFragment_to_profileFragmentOriginal);
movies_into_list.clear();
getAndPostMovieIntoLIstModel.clearPersonalList();
});
toolbar.setOnMenuItemClickListener(item -> {
if (item.getItemId() == R.id.menu_edit) {
dialogModifyDescription();
return true;
} else {
return false;
}
});
}
#Override
public void onCreateOptionsMenu(#NonNull Menu menu, #NonNull MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.menu_profile_edit_list, menu);
super.onCreateOptionsMenu(menu, inflater);
}
}
fragment_showListContent.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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:background="#color/big_stone"
tools:context=".fragments.MyListsFragment">
<include
layout="#layout/layout_toolbar"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
//other code
</androidx.constraintlayout.widget.ConstraintLayout>
You should have 1 toolbar and maybe 1 menu and instead disable/enable icons using menu.findItem(R.id.menu_edit).setVisible(true/false);
Maybe you could try calling requireActivity().invalidateOptionsMenu() as well.
I have an activity in which i desire to retrieve data (the text in some edit texts) when i click a button in my toolbar :
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
break;
case R.id.mnufragmentOk:
RETRIEVE EDITTEXT!!
break;
}
this is my activity :
public class ViatgeDetallTransportActivity extends AppCompatActivity{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_transportation);
Toolbar myToolbar = (Toolbar) findViewById(R.id.tlbMenuTransportation);
setSupportActionBar(myToolbar);
getSupportActionBar().setTitle("TravelApp ACtFra");
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ViatgeDetallTransportFragment fragment = new ViatgeDetallTransportFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.activity_fragment_transportation,fragment)
.commit();
}
}
And my fragment class :
public class ViatgeDetallTransportFragment extends Fragment {
public static final String ARG_ID = "id";
public ViatgeDetallTransportFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_transportation, container, false);
return rootView;
}
}
With a simple layout :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="#+id/layout_fragment_transportation" xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Transportation"
/>
<EditText
android:layout_width="100dp"
android:layout_height="wrap_content"
android:id="#+id/edtTitleFragmentTransportation"/>
<EditText
android:layout_width="100dp"
android:layout_height="wrap_content"
android:id="#+id/edtDescripcioFragmentTransportation"/>
<EditText
android:layout_width="100dp"
android:layout_height="wrap_content"
android:id="#+id/edtTypeFragmentTransportation"/>
</LinearLayout>
In the activity, when I click the toolbar button "mnufragmentOk" i want to recieve the data in the edit texts, so i can create a custom object.
Keep the fragment instance as a global variable in Activity
public class ViatgeDetallTransportActivity extends AppCompatActivity{
ViatgeDetallTransportFragment fragment;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_transportation);
Toolbar myToolbar = (Toolbar) findViewById(R.id.tlbMenuTransportation);
setSupportActionBar(myToolbar);
getSupportActionBar().setTitle("TravelApp ACtFra");
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
fragment = new ViatgeDetallTransportFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.activity_fragment_transportation,fragment)
.commit();
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
break;
case R.id.mnufragmentOk:
String s=fragment.getFirstEditTextData();
break;
}
}
Impliment the getFirstEditTextData() method inside of your Fragment
You can set a TAG for your fragment:
ViatgeDetallTransportFragment fragment = new ViatgeDetallTransportFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.activity_fragment_transportation,fragment, "MyFragment").commit();
Then you can find that instance when you click the button:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
break;
case R.id.mnufragmentOk:
ViatgeDetallTransportFragment fragment = getSupportFragmentManager.findFragmentByTag("MyFragment");
break;
}
Finally, you can find the TextView and get it's value:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
break;
case R.id.mnufragmentOk:
ViatgeDetallTransportFragment fragment = getSupportFragmentManager.findFragmentByTag("MyFragment");
EditText editText = (EditText)fragment.getView().findViewById(R.id.my_text_view);
String string = editText.getText().toString().trim();
break;
}
plus:
don't forget to set an ID to your EditTexts:
<EditText
android:id="#+id/my_edit_text"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:id="#+id/edtTypeFragmentTransportation"/>
and you need to reference them in your fragment's view creation:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_transportation, container, false);
EditText editText = (EditText)rootView.findViewById(R.id.my_edit_text);
return rootView;
}
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
Hi here you can see my code.
My probleme is : with this code my EditText and my Button field are null so i can't do anithing with them.
Plz can you help me to access to this button.
For the activity it's autogenerated by eclipse.
public class MainActivity extends ActionBarActivity {
private EditText commentaire;
private Button addReleve;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
this.commentaire = (EditText) findViewById(R.id.commentaire);
this.addReleve = (Button) findViewById(R.id.addReleve);
addReleve.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Toast toast = Toast.makeText(getApplicationContext(), "LOL", Toast.LENGTH_LONG);
toast.show();
return false;
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
return rootView;
}
}
public void resetInterface(){
this.commentaire.setText("");
this.addReleve.setEnabled(true);
}
}
XML Layout (fragment_main.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"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.relevegps.MainActivity$PlaceholderFragment" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="32dp"
android:text="Relevé GPS"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="#+id/addReleve"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="92dp"
android:text="Ajouter le relevé" />
<EditText
android:id="#+id/commentaire"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:ems="10" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/commentaire"
android:layout_centerHorizontal="true"
android:layout_marginBottom="26dp"
android:text="Commentaire" />
</RelativeLayout>
try this also.
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
EditText commentaire = (EditText) rootView.findViewById(R.id.commentaire);
Button addReleve = (Button) rootView.findViewById(R.id.addReleve);
commentaire.setText("");
addReleve.setEnabled(true);
return rootView;
}
// Also this goes in this class
public void resetInterface(){
this.commentaire.setText("");
this.addReleve.setEnabled(true);
}
}
Your problem is that those two views are in your Framgent's xml and you can only find those in that fragment. So just move the commentaire and addReleve specific stuff to your fragment class.
public static class PlaceholderFragment extends Fragment {
// Variables moved from MainActivity to here
private EditText commentaire;
private Button addReleve;
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
// To get views in fragment you need the base view (=rootView)
// Example
this.commentaire = (EditText) rootView.findViewById(R.id.commentaire);
// Put the code in here !
// ...
return rootView;
}
// Also this goes in this class
public void resetInterface(){
this.commentaire.setText("");
this.addReleve.setEnabled(true);
}
}
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;
}
}