Different menu toolbar in fragment with BottonNavigationView - android

I have a layout with bottonNavigationView and fragments. How can I have different toolbar menus for each fragment? I've already tried several things.
In a fragment, I hace used.
((AppCompatActivity) getActivity()).getSupportActionBar()
This is the layout of a fragment
<FrameLayout 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"
tools:context="com.cspm.ventas6.cspm.v_fragments.f_clientes"
android:focusable="false">
<LinearLayout
android:id="#+id/con_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:descendantFocusability="blocksDescendants"
android:focusable="false">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.ActionBar">
<!-- Toolbar is the actual app bar with text and the action items -->
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways" />
</android.support.design.widget.AppBarLayout>
<ListView
android:id="#+id/client_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#null" />
</LinearLayout>
</FrameLayout>

In your fragment, add following two methods.
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// tells the fragment that fragment will use toolbar's options menu
setHasOptionsMenu(true);
}
/**
* this method is called when fragment prepares options menu,
* simply, inflate your menu and call super
*/
#Override
public void onPrepareOptionsMenu(Menu menu) {
getActivity().getMenuInflater().inflate(R.menu.menu_res_id, menu);
super.onPrepareOptionsMenu(menu);
}
Change menu_res_id with your menu resource.
And, if you only want to remove an item from current menu, then replace line
getActivity().getMenuInflater().inflate(R.menu.menu_res_id, menu);
with
menu.findItem(R.id.action_search).setVisible(false);

Related

adding menu to toolbar

am trying to add one menu item to toolbar that always shown on the right of the toolbar
menu File
<item android:id="#+id/menu_edit"
android:title="#string/edit"
android:icon="#drawable/ic_baseline_edit_24"
app:showAsAction="ifRoom"
/>
xml file
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:fitsSystemWindows="true"
tools:context=".Profile">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/profileAppBar"
android:layout_width="match_parent"
android:layout_height="400dp"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="#+id/profileCollapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="#color/mediumBlue"
app:layout_scrollFlags="exitUntilCollapsed|scroll"
>
<ImageView
android:id="#+id/profileFullImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/abstract_dark_blue_polygonal_background_1035_9700"
android:fitsSystemWindows="true"
android:transitionName="profileImage"
app:layout_collapseMode="parallax" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/shape_background" />
<androidx.appcompat.widget.Toolbar
app:menu="#menu/profile_toolbr"
android:id="#+id/profileToolBar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
java.class
public class Profile extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
toolbar = findViewById(R.id.profileToolBar);
collapsingToolbarLayout = findViewById(R.id.profileCollapsingToolbarLayout);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
the problem is it not show up and only appears as three dots when i add this
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = new MenuInflater(Profile.this);
menuInflater.inflate(R.menu.profile_toolbr,menu);
return true ;
}
how can i add it to show as an icon on the toolbar
i try to use app:showAsAction="always" but the same no change
You should not use MenuInflater, as it will create new menu. Menu is handled by the activity itself. So you do not need to use new MenuInflater. So you have to remove it and use getMenuInflater.
Replace your onCreateOptionsMenu with this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return super.onCreateOptionsMenu(menu);
}

NestedScrollView with Toolbar

So I set in styles.xml for AppTheme NoActionBar, because I want Toolbar only in a few Activites and also I create post_details_menu with two items. But toolbar not showing at all.
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
Then in Manifest.xml, I have the theme: AppTheme
<application
android:theme="#style/AppTheme"
...>
</application>
Then i created my_toolbar:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorPrimary"/>
</LinearLayout>
And in im PostDetailsActivity i want use my Toolbar:
public class PostDetailActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_post_detail);
Toolbar toolbar = findViewById(R.id.my_toolbar);
setSupportActionBar(toolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.post_details_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case R.id.post_Edit:
showMessage("post_edit clicked");
return true;
case R.id.post_Delete:
showMessage("post_delete clicked");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
And finally this is my layout for ActivityPostDetails:
<androidx.core.widget.NestedScrollView
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"
tools:context=".PostDetailActivity"
android:background="#fff">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView ... />
<TextView ... />
<androidx.recyclerview.widget.RecyclerView .../>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
It's too simple. set your app bar layout in the XML file where you want to show the toolbar.
check below XML code:-
<androidx.core.widget.NestedScrollView
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"
tools:context=".PostDetailActivity"
android:background="#fff">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorPrimary"
android:theme="#style/AppTheme.ActionBar"
app:navigationIcon="#drawable/ic_back"
app:subtitleTextAppearance="#style/CustomSubTitleTextAppearance"
app:titleTextColor="#color/black" />
</com.google.android.material.appbar.AppBarLayout>
<ImageView ... />
<TextView ... />
<androidx.recyclerview.widget.RecyclerView .../>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
In your java code, you have to bind toolbar programmatically in PostDetailsActivity.java.
toolbar = findViewById(R.id.toolbar)
toolbar!!.setNavigationIcon(R.drawable.ic_back)
if (toolbar != null) {
setSupportActionBar(toolbar)
}
Xml structure something like this should solve the problem
<LinearLayout>
<Toolbar/>
<NestedScrollView>
//one parent view inside nestedscrollview
<AnylayoutType>
// other required views
</AnylayoutType>
</NestedScrollView>
<LinearLayout/>
With this approach your Toolbar won't move and menu option will always be available and nested sroll view will work as required.
And if you are sure your view hierarchy is not nested its better to use LinearLayout inside nested scrollview

How to use viewpager and tablayout inside a fragment?

I need my app to have bottom bar navigation and swipable tabs. so I need viewpager to swap between fragments nested inside each fragment that is used by the bottom navigation. how do I do this?
First, you create a Fragment that contains ViewPager and TabLayout like this
<LinearLayout 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:orientation="vertical"
tools:context=".FragmentThatHasViewPagerAndTabLayout">
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
Then create a Activity which includes FrameLayout (that will be used as fragment container) and BottomNavigation
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<android.support.design.widget.BottomNavigationView
android:id="#+id/bottom_navigation_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#color/colorPrimary"
app:itemIconTint="#FFF"
app:itemTextColor="#FFF"
app:menu="#menu/menu_bottom_navigation"/>
</LinearLayout>
Snippet code for Activity
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation_view);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
//Change fragment when select another item in BottomNavigation
}
}
getFragmentManager().beginTransaction().replace(R.id.fragment_container, new FragmentThatHasViewPagerAndTabLayout(), "TAG_TO_REUSE_FRAGMENT_AFTER_CONFIG_CHANGES").commit();
}
And code in Fragment that contains ViewPager and TabLayout, you just write it like normally do (like having a FragmentPagerAdapter, etc.)

Add a spinner to the Toolbar for a specific Fragment only

I am trying to add a spinner to a fragment, but for only one out of three total fragments in my application. My application also has a navigation drawer.
I have removed the default actionbar and added a toolbar as such in the activity_main.xml file:
android.support.v4.widget.DrawerLayout
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:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity"
tools:openDrawer="start" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorPrimary"
android:id="#+id/toolbar"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:elevation="4dp" />
<FrameLayout
android:id="#+id/fragment_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
I add the toolbar in the MainActivity.java class as such:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
etc...
How do I go about adding a Spinner for one particular fragment and not all three?
Do setHasOptionsMenu(true) in your Fragment which need to show the spinner.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
Add menu item.
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/spinner"
android:title="ActionBar Spinner"
app:actionViewClass="android.widget.Spinner"
android:background="#ff00"
app:showAsAction="always" />
</menu>
Then inflate menu in onCreateOptionsMenu method, refer to this:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu,inflater);
inflater.inflate(R.menu.spinner, menu);
MenuItem item = menu.findItem(R.id.spinner);
Spinner spinner = (Spinner) item.getActionView();
//.....
}

How to combine the Toolbar and a TabLayout in landscape orientation?

How can one combine the Toolbar and Tablayout when in landscape mode as shown in the youtube app? I can't seem to find a definitive answer for this.
My current layout:
<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:orientation="vertical"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Dark"/>
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:tabMode="fixed"
app:tabGravity="fill"/>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:background="#color/transparent"/>
</LinearLayout>
As mentioned above, Toolbar is a ViewGroup so a TabLayout can be made a child of this.
<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:orientation="vertical"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Dark"
android:title="Viewer">
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:layout_gravity="center_horizontal"
app:tabMode="fixed"
app:tabGravity="center"/>
</android.support.v7.widget.Toolbar>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:background="#color/transparent"/>
</LinearLayout>
You can add a layout with components to your ActionBar (the classic one, not the
android.support.v7.widget.Toolbar)
First create a menu resource menu\top_menu.xml to be your actionbar 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/topBarTabLayout"
android:title=""
app:actionLayout="#layout/top_bar_tab_layout"
app:showAsAction="always" />
<!-- Other menu items here -->
</menu>
Then, create a layout called layout/top_bar_tab_layout.xml containing just one TabLayout component (you can add other components too!):
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.TabLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/tab_layout_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="0dp"
android:paddingTop="0dp" />
To access this TabLayout component, create a reference inside your activity onCreateOptionsMenu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.top_menu, menu);
topBarTabLayoutMenuItem = menu.findItem(R.id.topBarTabLayout);
topBarTabLayout = (TabLayout) topBarTabLayoutMenuItem.getActionView();
//ADD #1 TAB WITH A ICON RESOURCE
topBarTabLayout.addTab(topBarTabLayout.newTab().setIcon(R.drawable.file));
//ADD #2 TAB WITH A ICON RESOURCE
topBarTabLayout.addTab(topBarTabLayout.newTab().setIcon(R.drawable.folder));
//This may be necessary to force tablayout to fill all space.
topBarTabLayout.setTabGravity(topBarTabLayout.GRAVITY_FILL);
//Add listener to do stuff!
topBarTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
//do whatever you want here, like selecting a viewpager item or open an intent
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
//do whatever you want here
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
//do whatever you want here
}
});
return true;
}
}
This should be enough to add a tabLayout to your actionBar. It will work with other components like spinner or textViews.
Also, if you are planning on setting this tablayout visible only when orientation is landscape, you have to do something like that:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE) {
topBarTabLayoutMenuItem.setVisible(true);
} else {
topBarTabLayoutMenuItem.setVisible(false);
}
}

Categories

Resources