Inflating AppBarLayout with Toolbar + TabLayout - android

I currently have a DrawerLayout in my main.xml. There's a Toolbar wrapped in an AppBarLayout, and then a simple LinearLayout to swap out fragments.
One of the fragments I navigate to, I want it to contain a TabLayout for a ViewPager of fragments. Currently, I have both of these in the fragment's layout file, but this causes a drop shadow to appear between the Toolbar and the TabLayout, which is something I don't want. I also don't want to use setElevation() because it won't work for pre-Lollipop devices.
A possible solution would be to inflate the AppBarLayout from my fragment, so that it holds both the Toolbar+Tabs. However, I'm not really sure how to do this, so any help would be appreciated.
Here is my 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/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.lumivote.lumivote.ui.MainActivity">
<android.support.design.widget.CoordinatorLayout
android:id="#+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbarlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
</android.support.design.widget.AppBarLayout>
<LinearLayout
android:id="#+id/flContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/nav_header"
app:itemIconTint="#333"
app:itemTextColor="#333"
app:menu="#menu/navigation_drawer_items" />
</android.support.v4.widget.DrawerLayout>
And here is my fragment's xml file:
<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="com.alexdao.democracy.ui.candidate_tab.CandidateListFragment">
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/myPrimaryColor"
app:tabMode="fixed"
app:tabGravity="fill"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white" />
</LinearLayout>

You are able to have separate toolbar for each fragment. Its possible to set fragments toolbar as activity actionbar. Example code:
Toolbar toolbar = (Toolbar) v.findViewById(R.id.toolbar);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
It should be possible to have titles, icons and other stuff as well.
With it you can mimic shadow on pre lollipop devices, no matter what you have on them.

I modified the solution given by bleeding182 and got it to work for AppBarLayout as well (to resolve the problem pointed out by bopa).
#Override
public void onAttach(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getActivity().findViewById(R.id.appbar).setElevation(0);
}
super.onAttach(context);
}
#Override
public void onDetach() {
super.onDetach();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getActivity().findViewById(R.id.appbar).setElevation(R.dimen.toolbar_elevation);
}
}
What I did was replace the call to getSupportActionBar() by giving an ID to my AppBarLayout and then calling findViewById() on it and then calling setElevation on its result. Tested on API 23.

I had a similar issue where I wanted a TabLayout just inside of one fragment.
Without changing any other code you can solve this by using onAttach and onDetach inside your fragment with the TabLayout.
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// todo add some further checks, e.g. instanceof, actionbar != null
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
((AppCompatActivity) activity).getSupportActionBar().setElevation(0);
}
}
#Override
public void onDetach() {
super.onDetach();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
((AppCompatActivity) getActivity()).getSupportActionBar()
.setElevation(getResources().getDimension(R.dimen.toolbar_elevation));
}
}
Be sure to set the same elevation on your TabLayout and everything works fine! ;D

You can simply add TabLayout programmatically from Fragment in wich you need TabLayout
tabLayout = (TabLayout) inflater.inflate(R.layout.tablay, null);
appBarLayout = (AppBarLayout) getActivity().findViewById(R.id.appbar);
appBarLayout.addView(tabLayout, new LinearLayoutCompat.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
and remove TabLayout from AppBar in onDetach()
#Override
public void onDetach() {
appBarLayout.removeView(tabLayout);
super.onDetach();
}

To fix my problem I ended up putting the Toolbar, TabLayout, and ViewPager all in my MainActivity.
main_activity.xml:
<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/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.CoordinatorLayout
android:id="#+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white" />
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:id="#+id/flContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/nav_header"
app:itemIconTint="#333"
app:itemTextColor="#333"
app:menu="#menu/navigation_drawer_items" />
</android.support.v4.widget.DrawerLayout>
Then, in all of my fragments, I set the visibility for the TabLayout and the ViewPager programmatically in onCreateView:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TabLayout tabLayout = (TabLayout) getActivity().findViewById(R.id.tabLayout);
tabLayout.setVisibility(View.GONE);
ViewPager mViewPager = (ViewPager) getActivity().findViewById(R.id.viewpager);
mViewPager.setVisibility(View.GONE);
return inflater.inflate(R.layout.fragment_layout, container, false);
}
Of course, in the fragment with tabs, you would want to set the visibility to View.VISIBLE instead of View.GONE.

The Artem_lens approach worked for me with some modifications.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
mTabLayout = (TabLayout) inflater.inflate(
R.layout.partial_tab_layout,
container,
false);
mAppBarLayout = (AppBarLayout) getActivity().findViewById(R.id.app_bar);
mAppBarLayout.addView(mTabLayout,
new LinearLayoutCompat.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
...
}
And removing the view at onDestroyView()
#Override
public void onDestroyView() {
mAppBarLayout.removeView(mTabLayout);
super.onDestroyView();
}

The solution is simple in the XML. Just add the following code to your AppBarLayout: app:elevation="0dp". So the AppBarLayout should look like this:
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp"
android:theme="#style/AppTheme.AppBarOverlay">

Related

Add Toolbar/Actionbar to PreferenceActivity

I am trying to add a toolbar to my PreferenceActivity.
I have looked around here and a number of places and nothing seems to work.
I am using headers for my top-level.
I tried to then use my own layout in onCreate including the required toolbar and making sure it has a view by the name of "#android:id/list".
<?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">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:title="#string/app_name"
app:navigationIcon="#drawable/back"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<ListView android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
This worked okay for the top level but then the next level failed looking for a view name "android:id/prefs".
java.lang.IllegalArgumentException: No view found for id 0x102040a (android:id/prefs) for fragment PreferencesFragmentButtonInteraction{7a6584a #0 id=0x102040a}
The only code in the onCreate of the fragment is the AddPreferencesFromResource.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences_button_interaction);
}
I have tried to use a theme and set in in the manifest but to no avail.
You can use PreferenceFragmentCompat wrapped in a normal AppCompatActivity. Then you can easily attach an appbar to your activity using
setContentView(R.layout.activity_setting);
and preferences can be set to the fragment using
setPreferencesFromResource(R.xml.preferences_button_interaction, rootKey);
If you wish to add toolbar to your current activity, you can try this method
private void setupActionBar() {
ViewGroup rootView = (ViewGroup)findViewById(R.id.action_bar_root); //id from appcompat
if (rootView != null) {
View view = getLayoutInflater().inflate(R.layout.app_bar_layout, rootView, false);
rootView.addView(view, 0);
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
// Show the Up button in the action bar.
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
app_bar_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>

CollapsingToolbarLayout inside Fragment returning null

I have a viewpager inside in a activity. This activity launch three fragements (not tabbed), as created three different class extends fragment. It is working fine with horizontal scrolling in between fragment.
Now I want to use collapsingToolbar with separate image display in fragment.
Activity - having viewpager, Fragment1 XML having collapsingToolbar, Fragement1 also have 'content_launch.xml' Fragement1 class - toolbar added but while fetching (CollapsingToolbar object it is returning null.
Activity XML as below :
<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=".activity.LaunchActivity">
<android.support.v4.view.ViewPager
android:id="#+id/launchpager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1" app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</LinearLayout>
Activity Class to launch viewpager
ViewPager viewPager = (ViewPager) findViewById(R.id.launchpager);
viewPager.setAdapter(new LaunchAdapter(getSupportFragmentManager
(),getApplicationContext()));
Fragement1 XML
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/quote_coordinator"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:background="#android:color/white"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="#dimen/detail_backdrop_height"
android:id="#+id/quote_appbar"
android:fitsSystemWindows="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/quote_collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim ="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:expandedTitleTextAppearance="#android:color/transparent"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView android:id="#+id/quote_backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode ="parallax"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center_horizontal" android:orientation="vertical">
<TextView android:id="#+id/quote_main_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/main_title"
android:textColor="#android:color/white"
android:textSize="#dimen/main_title"/>
<TextView android:id="#+id/quote_sub_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/main_sub_title"
android:textColor="#android:color/white"
android:textSize="#dimen/main_sub_title"/>
</LinearLayout>
</RelativeLayout>
<android.support.v7.widget.Toolbar
android:id="#+id/quote_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_quote"/>
</android.support.design.widget.CoordinatorLayout>
Fragment1 Class:
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Toolbar quoteToolbar = (Toolbar) getActivity().findViewById(R.id.quote_toolbar);
((AppCompatActivity) getActivity()).setSupportActionBar(quoteToolbar);
final CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) getActivity().findViewById(R.id.quote_collapsing_toolbar);
}
collapsingToolbar object returned as null, not able to find any suggestions, can someone suggest possible way to get object..
First thing: you should not use onCreate to initialize view elements in fragment, you should use onCreateView instead. Second one you don't use getActivity() context.
So instead of this code:
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Toolbar quoteToolbar = (Toolbar) getActivity().findViewById(R.id.quote_toolbar);
((AppCompatActivity) getActivity()).setSupportActionBar(quoteToolbar);
final CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) getActivity().findViewById(R.id.quote_collapsing_toolbar);
}
use this:
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
// inflate your layout.
View view = inflater.inflate(R.layout.yourlayout, container, false);
Toolbar quoteToolbar = (Toolbar) view.findViewById(R.id.quote_toolbar);
((AppCompatActivity) view).setSupportActionBar(quoteToolbar);
final CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) view.findViewById(R.id.quote_collapsing_toolbar);
return view
}
Best regards and happy new year! :)

Material Design elevation issue when add a fragment with TabLayout

I'm currently working on an application for v22 and use the following libraries:
compile 'com.android.support:appcompat-v7:22.2.1'
compile 'com.android.support:support-v4:22.2.1'
compile 'com.android.support:design:22.2.1'
I have only one Activity called HomeActivity that has a Navigation Drawer Inside.
This is the activity_home.xml layout:
<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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<android.support.design.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"
android:fitsSystemWindows="false">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
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.ActionBar" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
/>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="start"
app:menu="#menu/menu_navigation"/>
So, every time I choose an item from navigation Drawer I replace the FrameView #+id/content_frame with a new Fragment like this:
int id = menuItem.getItemId();
switch (id)
{
case R.id.gazzette:
fragmentManager.beginTransaction()
.replace(R.id.content_frame, new ListViewFragment())
.commit();
drawerLayout.closeDrawers();
break;
case R.id.concorsi:
// Insert the fragment by replacing any existing fragment
fragmentManager.beginTransaction()
.replace(R.id.content_frame, new ConcorsiFragment())
.commit();
drawerLayout.closeDrawers();
break;
Everything works fine and I have a toolbar with the right elevation.
But when I try to replace the #+id/content_frame Fragment with a new Fragment with a TabLayout and View Pager I see the elevation of the toolbar of the Home Activity.
The layout of this inner Fragment is:
<android.support.design.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"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"
android:elevation="6dp"
android:background="#color/colorPrimary"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.AppBarLayout>
Naturally, if I start a new Activity (without Fragment) with a TableLayout everything goes ok but I don't want create a new Activity and launch it with a selection of Navigation Drawer but I want use only Fragment items.
If a set app:elevation="0dp" from HomeActivity I have no shadow in all Application Fragment.
Is this the proper way to add a Fragment with TabLayout inside?
Is there a way to remove the shadow of toolbar only in this case?
I have solution, but not elegant. Simply remove elevation from toolbar in onViewCreated() and set it back in onDestroyView().
private Toolbar toolbar;
private float toolbarElevation;
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
toolbar = getActivity().findViewById(R.id.toolbar);
toolbarElevation = toolbar.getElevation();
toolbar.setElevation(0);
}
}
#Override
public void onDestroyView() {
super.onDestroyView();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
toolbar.setElevation(toolbarElevation);
}
}

Android does not show tabs

I am in a process of changing home activity to include tabs. I use https://github.com/saulmm/CoordinatorExamples as a source. For unknown reason I do not see the tabs in my AppBarLayout. I can see the Fragment content but tab headers are not displayed at all. I use appcompat-v7:23.3.0.
Shortened layout:
<android.support.design.widget.CoordinatorLayout
<android.support.design.widget.AppBarLayout
<android.support.design.widget.CollapsingToolbarLayout
<ImageView ..
<android.support.v7.widget.Toolbar ..
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.design.widget.TabLayout
android:id="#+id/main.tabs"
android:layout_width="fill_parent"
android:layout_height="?attr/actionBarSize"
app:tabSelectedTextColor="?android:attr/textColorPrimaryInverse"
app:tabIndicatorColor="?android:attr/textColorPrimaryInverse"
app:tabIndicatorHeight="4dp" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/dashboard.viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
/>
Activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
CollapsingToolbarLayout collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.main_collapsing);
collapsingToolbarLayout.setTitle(getString(R.string.app_name));
ViewPager viewPager = (ViewPager) findViewById(R.id.dashboard_viewpager);
viewPager.setAdapter(new TabsAdapter(getSupportFragmentManager()));
TabLayout tabLayout = (TabLayout) findViewById(R.id.main_tabs);
tabLayout.setupWithViewPager(viewPager);
}
class TabsAdapter extends FragmentPagerAdapter {
public TabsAdapter(FragmentManager fm) {
super(fm);
}
public int getCount() {
return 1;
}
public Fragment getItem(int i) {
switch(i) {
case 0: return DashboardHomeFragment.newInstance();
}
return null;
}
public CharSequence getPageTitle(int position) {
return "Home";
}
}
Fragment:
public class DashboardHomeFragment extends Fragment implements View.OnClickListener {
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_dashboard_home, container, false);
}
public void onActivityCreated(#Nullable Bundle state) {
log.debug("onActivityCreated()");
super.onActivityCreated(state);
}
and its layout:
<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="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hry"
android:textAppearance="#style/TextAppearance.Header"
android:paddingRight="8dp"
android:paddingLeft="8dp"
style="#style/TextComponent.ItemRow"/>
<TextView
android:id="#+id/main.button.puzzle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Najdi výsledek"
android:textAppearance="#style/TextAppearance.Item"
android:drawableRight="#drawable/ic_arrow_forward_24dp"
style="#style/TextComponent.ItemRow.Selectable"/>
There is a second problem but I will post it in separate question linked to this question.
Update:
It was caused by CoordinatorLayout misconfiguration. I changed:
android:layout_height="150dp"
to
android:layout_height="wrap_content"
and the tabs appeared suddenly.
According to the guidelines of Android and the material design, it is correct to use the coordinatorLayout.
The appBarLayout should be max 256dp and inside we find the toolbar and the views that you need.
If you want the views collapsing insert into collapsingToolbarLayout.
If you want the toolbar expandable will be inserted inside the collapsingToolbarLayout.
The tabLayout often is insert into appBarLayout but out collapsingToolbarLayout.
The sum of views height is equals at appBarLayout height (or use wrap_content for appBarLayout).
This is an example of expandable toolbar with tabLayout, in this case appBarLayout has a fixed height but you can use wrap_content.
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="256dp"
android:fitsSystemWindows="true"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="202dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:contentScrim="#color/your_color"
android:fitsSystemWindows="true">
<--Your views-->
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:gravity="top"
app:titleMarginTop="13dp"
android:minHeight="?attr/actionBarSize"
app:popupTheme="#style/AppTheme.PopupOverlay"
app:layout_collapseMode="pin"
/>
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom"
android:background="#color/your_color"
app:tabSelectedTextColor="#color/your_color"
app:tabTextColor="#color/your_color"
app:tabIndicatorColor="#color/your_color"
app:tabMode="fixed"
app:tabGravity="fill"
/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
/>
</android.support.design.widget.CoordinatorLayout>

How to create AppBarLayout which overlaps content of CoordinatorLayout

When using a CoordinatorLayout with AppBarLayout on some activities I need the content to be under the AppBarLayout, i.e. the Toolbar is using some transparent color and overlays the content. By default CoordinatorLayout + AppBarLayout arrange things so that toolbar and scrolling content are next to eachother, without any overlapping.
Android developer guides have the documentation on this here and it looks like this (but those flags do not seem to work with Toolbar and appcompat - I tried):
So I need something that looks like on image above, but with all the scrolling goodies provided by CoordinatorLayout + AppBarLayout. And there's no need to use CollapsingToolbarLayout - just this simple one.
Any hints on how to achieve this?
Here's my activity layout.
<android.support.design.widget.CoordinatorLayout
android:id="#+id/top_content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:background="#android:color/transparent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<include layout="#layout/main_toolbar"/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
>
<!-- to be filled by content fragment -->
</FrameLayout>
<android.support.design.widget.FloatingActionButton
style="#style/FabStyle"
android:id="#+id/fab_button"
android:src="#drawable/bt_filters"
/>
</android.support.design.widget.CoordinatorLayout>
I tried this solution, it works.
transparency :
added background to AppBarLayout, and placed scrolling view in layout before AppBarLayout
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#00000000" >
content positioning : extended AppBarLayout.ScrollingViewBehavior by new AppbBarTransparentScrollingViewBehavior overriding onDependentViewChanged() and modifying updateOffset() to offset = 0
#Override
public boolean onDependentViewChanged(CoordinatorLayout parent, View child,
View dependency) {
updateOffset(parent, child, dependency);
return false;
}
private boolean updateOffset(CoordinatorLayout parent, View child,
View dependency) {
final CoordinatorLayout.Behavior behavior = ((CoordinatorLayout.LayoutParams) dependency
.getLayoutParams()).getBehavior();
if (behavior instanceof Behavior) {
// Offset the child so that it is below the app-bar (with any
// overlap)
final int offset = 0; // CHANGED TO 0
setTopAndBottomOffset(offset);
return true;
}
return false;
}
new content's behavior : set behavior on scrolling view
<android.support.v4.view.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
layout_behavior="AppbBarTransparentScrollingViewBehavior" />
result : with an ImageView inside a NestedScrollView as scrolling view
If you remove the line
app:layout_behavior="#string/appbar_scrolling_view_behavior"
from the FrameLayout, the content will be overlapped by the Toolbar. Hope that helps.
EDIT: Oh you mention that you need the scrolling goodies, so this isn't really a solution.
Here i tried to give Main Background image to windowBackground and ToolBar/ActionBar Background as a Transparent. Below Style i have specified in manifest. Window background changes can be done as per required.
Style in Menifest
<style name="AppThemeSliderToolbar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">#drawable/t_img</item>
<item name="colorPrimary">#ff5b45</item>
<item name="colorPrimaryDark">#FF5722</item>
</style>
Layout with AppBar with semi transparent background
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#50000000"
>
<!--Change Opacity background as per required ..android:background="#50000000"-->
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/frgmentcontainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/appbar"></FrameLayout>
</RelativeLayout>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_marginBottom="20dp"
android:layout_marginRight="20dp"
android:src="#android:drawable/ic_dialog_email"
app:fabSize="normal" />
</android.support.design.widget.CoordinatorLayout>
UPDATE
As per our discussion on comment CollapsingToolbarLayout with fragment.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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=".ScrollingActivity">
<android.support.design.widget.AppBarLayout android:id="#+id/app_bar"
android:fitsSystemWindows="true" android:layout_height="#dimen/app_bar_height" android:background="#00FFFFFF"
android:layout_width="match_parent" android:theme="#style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout android:id="#+id/toolbar_layout"
android:fitsSystemWindows="true" android:layout_width="match_parent"
android:layout_height="match_parent" app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:contentScrim="?attr/colorPrimary">
<android.support.v7.widget.Toolbar android:id="#+id/toolbar"
android:layout_height="?attr/actionBarSize" android:layout_width="match_parent"
app:layout_collapseMode="pin" app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_scrolling" />
<android.support.design.widget.FloatingActionButton android:id="#+id/fab"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_margin="#dimen/fab_margin" app:layout_anchor="#id/app_bar"
app:layout_anchorGravity="bottom|end" android:src="#android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
content_scrolling.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/activity_scrolling" android:layout_width="match_parent"
android:layout_height="match_parent" tools:context=".ScrollingActivity">
<FrameLayout android:id="#+id/framcontainer"
android:layout_width="match_parent"
android:layout_height="match_parent"></FrameLayout>
</android.support.v4.widget.NestedScrollView>
Style Given to Activity in Manifest.
<style name="AppThemeSliderToolbar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">#drawable/t_img</item>
<item name="android:windowContentOverlay">#null</item>
<item name="windowActionBarOverlay">true</item>
<item name="colorPrimary">#android:color/transparent</item>
</style>
ScrollingActivity
public class ScrollingActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scrolling);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
getSupportFragmentManager().beginTransaction().
replace(R.id.framcontainer, new HomeFragment(), "Home").commit();
}
}
Home2
public class Home2 extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.home_2, container, false);
}
}
HomeFragment
public class HomeFragment extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.homefragment, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.txt).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.framcontainer, new Home2(), "Home2").addToBackStack("Home2").commit();
}
});
}
}
Screenshot url. Avoided Ambeding images i've given url
Before updated Ans http://i.stack.imgur.com/5cVOw.jpg
HomeFragment From Updated Ans > http://i.stack.imgur.com/UF8LW.jpg
Home2 From updated Ans http://i.stack.imgur.com/cD480.jpg
For Anybody who is working on a layout that is using a NavigationDrawer one solution to this is to change that ToolBar/AppBar dynamically when you are rendering that fragment for example. Lets say you are starting from Home.java and want to go to Chats.Java which is a fragment from there and you want to change that toolbar you can do this:
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.nav_chat:
toolbar.inflateMenu(R.menu.My_Other_Menu);
toolbar.setTitle("My New Title");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new PaymentFragment()).commit();
break;
}
}
Please not that we have changed the title and also changed the title, menu and also changed the default NavigationIcon to be a back button. However we will also have to change that back button to go back when it is clicked.
This solution is pushes the contents of that Chats.java to be below the ToolBar instead of being covered by it.

Categories

Resources