I'm trying to create a good UI interface for tablet / large screen device.
The perfect solution would be the one running on GMail app (see screenshot below).
As far as I can understand, the layout is composed like this:
<?xml version="1.0" encoding="utf-8"?>
<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:openDrawer="start">
<android.support.design.widget.CoordinatorLayout
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: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>
<include layout="#layout/activity_main_twopane" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:src="#drawable/ic_add" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation_drawer"
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>
But if I adopt my solution, this will give me to 2 problems:
The FloatingActionButton on my code is on the bottom|end of the layout; in GMail app this is positioned only on the list layout (the one which contains e-mails);
The Toolbar on my code is only one (and I have a search action too), but it seems that on GMail app there are 2 of them: one as main with search option and the second one for details actions that are visible when you select an email.
Any advice that will lead me to to achieve the layout on screenshot?
Quick answer for your question 2 and 3:
In order to place the FAB in the desired place you have to add this tag on FloatingActionButton xml code: app:layout_anchor="#id/desired_view_id" and app:layout_anchorGravity="bottom|right|end";
In bottom toolbar you can define separate toolbar and style it.
See code below
// this is top toolbar
Toolbar toolbarTop = (Toolbar) findViewById(R.id.toolbar_top);
setSupportActionBar(toolbarTop);
// this is bottom one
Toolbar toolbarBottom = (Toolbar) findViewById(R.id.toolbar_bottom);
toolbarBottom.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch(item.getItemId()){
case R.id.action_settings:
// TODO
break;
// TODO: Other cases
}
return true;
}
});
// Inflate a menu to be displayed in the toolbar
toolbarBottom.inflateMenu(R.menu.menu_main);
Related
I have adopted the "one activity, multiple fragments" way of defining layouts for my Android (Xamarin) application. All views (fragments) share the same BottomNavigationView managed by MainActivity that adds each fragment to the same FrameLayout. But, as some fragments need to define their own AppBarLayouts, to for example create a CollapsingToolbarLayout, I can not just create a FragmentTransaction and put those fragments in the same FrameLayout container, as the Toolbar is part of the Activity's layout and thus not managed by the fragments. It would also seem counterproductive having to add and manage a Toolbar for each Fragment.
What I have tried so far:
Having a FrameLayout for each variation and then show/hide
accordingly (in layout for MainActivity) when making a
FragmentTransaction.
Use a fullscreen DialogFragment to show contents
above the active fragment.
Convert the "offending" fragment into an
Activity (makes it hard to handle the BottomNavigationView).
MainActivity currently looks like this (with some details omitted):
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android:id="#+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<include
android:id="#+id/appbar_main"
layout="#layout/toolbar_main"/>
<FrameLayout
android:id="#+id/fragment_container"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<include
android:id="#+id/bottombar"
layout="#layout/toolbar_nav" />
</android.support.design.widget.CoordinatorLayout>
appbar_main layout (used by MainActivity)
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<!-- logo layout -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="?attr/actionBarSize"
android:orientation="horizontal"
android:layout_gravity="center"
android:paddingTop="10dp"
android:paddingBottom="10dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
appbar_collapsing layout (for example used to show a profile page)
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="#drawable/toolbar_app_bg"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<ffimageloading.views.ImageViewAsync
android:id="#+id/imageViewCover"
android:layout_width="match_parent"
android:layout_height="200dp"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.9" />
<ffimageloading.views.ImageViewAsync
android:id="#+id/imageViewProfile"
android:layout_width="100dp"
android:layout_height="100dp"/>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
The appbar_main layout provided above is quite simple and also the primary way of showing the Toolbar. appbar_collapsing differs from the main layout in that the Toolbar is nested within a CollapsingToolbarLayout to make it collapsible when scrolling while also collapsing two ImageView.
Any examples and advaree is much appreciated!
In fragments with bottom layout with changing needs for toolbars.
After testing different methods i concluded with this:
private void createMenus(Toolbar actionBarToolBar, #MenuRes int menu){
((MainActivity) Objects.requireNonNull(getActivity())).setSupportActionBar(actionBarToolBar);
actionBarToolBar.setTitle("");
actionBarToolBar.inflateMenu(menu);
}
Call this method here:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
mRootView = inflater.inflate(R.layout.fragment_profile, container, false);
createMenus(mToolbar,R.menu.profile_menu);
setHasOptionsMenu(true);
//add fragments to adapter
//...
return mRootView;
}
Then override this:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.profile_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
I created a new App with Android Studio 2.0 and I want to have my Navigation Drawer below the Toolbar. I know the Material Design specs say it should be above the Toolbar but my Drawer won't have that much entries and I want to see the neat icon animation provided by Google.
I maged to get what I want by placing the DrawerLayout within the top level CoordinatorLayout.
<?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="com.company.app.MainActivity">
<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:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:openDrawer="start">
<include layout="#layout/content_main" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
</android.support.design.widget.CoordinatorLayout>
I am using android:fitsSystemWindow="true" on the top level layout so I can tint the status bar. But when I do that, the Navigation Drawer does have a gray top border.
When I would be using it the way Google specified it (above the Toolbar) then the border would be fine but this way it just looks ugly. Is there any way to remove this?
I experimented with overriding NavigationView.onInsetsChanged(Rect rect) and was able to place the items at the top but the gray border remained.
I had a headache trying to figure this out also and managed to find this which describes how CoordinatorLayout passes fitsSystemWindows to its child. I definitely think this is a bug since NavigationView already has it set to false, but then I read this:
NavigationView takes care of the scrim protection of the status bar for you, ensuring that your NavigationView interacts with the status bar appropriately on API21+ devices.
from the Android Developers Blog. So I'm not sure what to think of it. I think it might be due to the fact that NavigationView was never intended to be used this way.
Nonetheless, here's a solution you can try that fixes the gray bar issue, but I haven't figured out if it might cause anymore problems. If so please post back.
In the activity_main.xml:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_marginTop="100dp"
android:fitsSystemWindows="false"/>
</android.support.design.widget.CoordinatorLayout>
In MainActivity class:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
if (navigationView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
navigationView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
#Override
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
return insets;
}
});
}
}
}
Should get you this:
I have a weird issue concerning the Android Toolbar in Samsung Galaxy Tab 4. Maybe it's the OS (4.4.2) or the device itself.
I am using the AppCompat-v7:23 library to display a Toolbar for pre-Lollipop devices.
Here is the XML code of my Activity where the Toolbar is displayed:
<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:fitsSystemWindows="true">
<include
layout="#layout/appbar_content_top"
android:layout_width="match_parent"
android:layout_height="match_parent" />
And here is appbar_content_top:
<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"
android:fitsSystemWindows="true"
tools:context=".CEMainActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar_layout"
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:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
As you can see, I did not put an android:layout_below attribute for #+id/content. That is one of my requirement. In my Activity, I get the Toolbar and set it as my supportActionToolbar.
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
Log.e("Viewer", "Toolbar is not null");
} else {
Log.e("Viewer", "Toolbar is null");
}
The Toolbar displays for other devices. But in Galaxy Tab 4, the Toolbar is not displayed, even though the snippet above says that the Toolbar is not null.
Weirdly, if I add an android:layout_below attribute to #+id/content, the Toolbar will show in the Galaxy Tab 4.
Any clues on why this could be happening?? Thanks!
Since you are using appbarlayout, use coordinator layout instead of Framelayout as the main viewgroup of appbar_content_top.xml, coordinator act the same way as framelayout, just think of it as a super framelayout ;) and one more thing layout_below work properly with relativelayout only as the parent viewgroup
I built a project based on Scrolling Activity, and faced a strange issue. Consider the following scenario:
I click on fab button to go to another fragment but when the fragment displaces, the fab button will not disappear!
Can anybody know how to fix this problem?
Here is my XML of Scrolling Activity that I added to my frameLayout:
<?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="ir.apio.myapplication.ScrollingActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="#dimen/app_bar_height"
android:fitsSystemWindows="true"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
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"
android:src="#android:drawable/ic_dialog_email"
app:layout_anchor="#id/app_bar"
app:layout_anchorGravity="bottom|end" />
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</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: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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="ir.apio.myapplication.ScrollingActivity"
tools:showIn="#layout/activity_scrolling">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="#dimen/text_margin"
android:text="#string/large_text" />
</android.support.v4.widget.NestedScrollView>
My fab ClickListener :
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.frame,new TestFragment())
.commit();
}
});
And also my TestFragment :
public static class TestFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_test,container,false);
return view;
}
}
Here is the screen-shot in the first place:
Here is screen-shot when going to the new fragment:
The reason you are still seeing the FAB is elevation, which refers to a views depth on the screen. It affects which elements are above or below one another and the shadows they cast(for example a FAB sits on top of the main content and casts a shadow).
The FAB by default will have some elevation, which you can override using the elevation attribute, eg app:elevation="4dp". The other elements will be at the 0dp level.
In your case, you've put the FrameLayout last in your layout file, and I presume that's where you are loading your fragment into. What this does is not actually replace your other content, but just cover it with the content of your FrameLayout.
The reason it doesn't cover the FAB, is because the FAB has some elevation and the FrameLayout doesn't. So although you've put your FrameLayout last and would normally expect that to be "on top", the FAB actually has a higher elevation which overrides that.
A quick fix, would be to give your floating action button app:elevation=0dp which would put it back on the same elevation level as everything else and the normal rules would apply, the FrameLayout is last and would be on top.
In reality, just putting a big frame covering the previous content is not usually the best thing to do and you would want to look at other ways to structure the app.
I had the same problem. I called the .hide() method on the FragmentTransaction and it worked for me.
fab.setOnClickListener {
val fragmentManager = fragmentManager
val fragmentTransaction = fragmentManager?.beginTransaction()
val fragment = YourFragment()
fragmentTransaction?.add(R.id.fragment_container, fragment)
fragmentTransaction?.addToBackStack(null)
fragmentTransaction?.hide(this)
fragmentTransaction?.commit()
}
I want to put an icon right to title in collapsing tool bar, shown as below
but After collapsing i don't want it to show in tool bar.
i want to hide after collapsing.
i have done some thing. using
collapsingToolbarLayout.setTitle(item.getName());
collapsingToolbarLayout.setForeground(getResources().getDrawable(R.drawable.ic_photo_library_white_24dp));
which look like this.
i am still trying to adjust that image.
but i want to hide that image after collapsing. bez it looks like this.
here is my java code.
private void setToolbar(Product item) {
((AppCompatActivity) getActivity()).setSupportActionBar((productToolBar));
ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
actionBar.setTitle("");
productToolBar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().onBackPressed();
}
});
collapsingToolbarLayout.setTitle(item.getName());
collapsingToolbarLayout.setForeground(getResources().getDrawable(R.drawable.ic_photo_library_white_24dp));
collapsingToolbarLayout.set
}
and my xml file.
<android.support.design.widget.CoordinatorLayout
android:id="#+id/product_detail_main_content"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:apptools="http://schemas.android.com/tools"
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="#dimen/product_detail_appBar_height"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/detail_product_collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:foregroundGravity="bottom|right"
android:foregroundTintMode="add"
android:clipToPadding="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="#dimen/space_xxlarge"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/image"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.7"/>
<android.support.v7.widget.Toolbar
android:id="#+id/product_toolBar_title"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:fitsSystemWindows="true"
app:layout_collapseMode="pin"
app:navigationIcon="#drawable/ic_arrow_back_white_24dp"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
........
<android.support.design.widget.CoordinatorLayout
Thanks in advance. ^_^
i got the solution its an issue.
CollapsingToolbarLayout child views not shown in devices< Android L 5.1 including 5.0
here is the link
https://code.google.com/p/android/issues/detail?id=177738&can=1&q=CollapsingToolbarLayout&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars