I am working on having a single navigation drawer for all the activities, so I thought to add it in BaseActivity and then inherit it in other activities wherever I need the navigation drawer and I did indeed succeed in getting the navigation drawer working but for some reason the toolbar is not being displayed in the child activities that inherit the BaseActivity, The I tried a lot things and checkout lot of questions on stack overflow but I could not really figure out what is the issue.
Here is the code: layout file
activity_base.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/DrawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:elevation="7dp">
<LinearLayout
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:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/RecyclerView"
android:layout_width="320dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:background="#ffffff"
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.DrawerLayout>
I am using this layout file here in onCreate of BaseActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mRecyclerView = (RecyclerView) findViewById(R.id.RecyclerView); mRecyclerView.setHasFixedSize(true); // Letting the system know that the list objects are of fixed size
mAdapter = new NavigationFragmentAdapter(TITLES,ICONS,NAME,EMAIL,PROFILE); // Creating the Adapter of MyAdapter class(which we are going to see in a bit)
// And passing the titles,icons,header view name, header view email,
// and header view profile picture
mRecyclerView.setAdapter(mAdapter); // Setting the adapter to RecyclerView
mLayoutManager = new LinearLayoutManager(this); // Creating a layout Manager
mRecyclerView.setLayoutManager(mLayoutManager); // Setting the layout Manager
Drawer = (DrawerLayout) findViewById(R.id.DrawerLayout); // Drawer object Assigned to the view
mDrawerToggle = new ActionBarDrawerToggle(this,Drawer,toolbar,R.string.drawer_open,R.string.drawer_close){
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
// code here will execute once the drawer is opened( As I dont want anything happened whe drawer is
// open I am not going to put anything here)
}
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
// Code here will execute once drawer is closed
}
}; // Drawer Toggle Object Made
Drawer.setDrawerListener(mDrawerToggle); // Drawer Listener set to the Drawer toggle
mDrawerToggle.syncState(); // Finally we set the drawer toggle sync State
}
Then I am inheriting this activity in other child activity (HomeActivity):
public class HomeActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_home);
ViewGroup content = (ViewGroup) findViewById(R.id.content_frame);
getLayoutInflater().inflate(R.layout.activity_home, content, true);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
The xml file for HomeActivity:
<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:id="#+id/home_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="app.packman.activity.HomeActivity">
<android.support.design.widget.CoordinatorLayout
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:theme="#style/AppTheme.AppBarOverlay">
<android.support.design.widget.TabLayout
android:id="#+id/home_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_home" />
<!-- other content of activity-->
</android.support.design.widget.CoordinatorLayout>
the output screenshot of HomeActivity which has no toolbar (which is the problem I am facing):
Any suggestions will of great help
You can try add
app:layout_behavior="#string/appbar_scrolling_view_behavior"
in your FrameLayout
Related
Problem 2:
The Tab bar cannot restore back to original position when another tab is clicked (tab 1 with non-recyclerview). It sticked at the top until it can scrolls back using tab 2 that send it to the top
I'm using re-usable code that no need to re-write App Bar and Navigation Drawer everytime.
Problem 1 detail:
The app bar can scroll when scrolling recycler view but the tab bar is hiding behind app bar until app bar scroll out of the screen at top (tab bar cannot move and stay at 0 y-coordinate)
Problem 1 (fixed):
Solution: move the line "app:layout_behavior="#string/appbar_scrolling_view_behavior" from viewpager to framelayout
Motion 1 motion 2
âScreen capture
My code are:
activity_base.xml (acitivity to put every page in FrameLayout)
<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:id="#+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<!--Toolbar-->
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark">
<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/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<!--Activity container to put page content-->
<FrameLayout
android:id="#+id/flContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</android.support.design.widget.CoordinatorLayout>
<!--
NavigationView - place inside drawer
-->
<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"
/>
pg02_push.xml (page with few tabs)
<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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".Pg02Push">
<!--
AppBarLayout > Toolbar, TabLayout
-->
<android.support.design.widget.AppBarLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark"
android:layout_below="#+id/toolbar"
>
<!--TabLayout-->
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"
app:tabGravity="fill"/>
</android.support.design.widget.AppBarLayout>
<!--VIewPager for Tab-->
<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"
/>
pg02tab02_allpush.xml (tab with recycler view)
<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.fcm.firsthandpptynoti.Pg02Tab02AllPush">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview_tab02_allpush"
android:divider="#FFB900"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
BaseActivity.java
#Override
public void setContentView(#LayoutRes int layoutResID){
/**
* This is going to be our actual root layout.
* Instantiates a layout XML file into its corresponding View objects.
* It is never used directly. Instead, use getLayoutInflater() or
* getSystemService(Class) to retrieve a standard LayoutInflater instance
* that is already hooked up to the current context and correctly configured for the device you are running on
* android.view.LayoutInflater#inflate(int, android.view.ViewGroup)
*/
mDrawerLayoutFull = (DrawerLayout) getLayoutInflater().inflate(R.layout.activity_base, null);
/**
* {#link FrameLayout} to inflate the child's view. We could also use a {#link android.view.ViewStub}
*
*/
FrameLayout activityContainer = (FrameLayout) mDrawerLayoutFull.findViewById(R.id.flContent);
getLayoutInflater().inflate(layoutResID, activityContainer, true);
/**
* Note that we don't pass the child's layoutId to the parent,
* instead we pass it our inflated layout.
*/
super.setContentView(mDrawerLayoutFull);
/*
Toolbar
Set a Toolbar to replace the ActionBar.
Initializing Toolbar and setting it as the actionbar
*/
mToolbar = (Toolbar) findViewById(R.id.toolbar);
if (useToolbar()) {
mToolbar.setTitle(setTitleOnToolbar());
setSupportActionBar(mToolbar);
}
else {
mToolbar.setVisibility(View.GONE);
}
/*
Navigation View
*/
//
mNavigationView = (NavigationView) findViewById(R.id.nav_view);
//Navigation View
setUpNavigationView();
//....
//...
//..
//.
}
//End of setContentView
Pg02Push.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pg02_push);
/*
Tab
*/
//ViewPager - Layout manager that allows the user to flip left and right through pages of data.
mViewPager = (ViewPager) findViewById(R.id.viewpager);
//MyViewPagerAdapter
setupViewPager(mViewPager);
//...
//..
//.
mTabLayout = (TabLayout) findViewById(R.id.tabs);
//Assigns the ViewPager to TabLayout
//The one-stop shop for setting up this TabLayout with a ViewPager.
mTabLayout.setupWithViewPager(mViewPager);
} // End of onCreate
I am using android default navigation drawer and i want that same layout for all the activities i tried searching on internet i got some ideas for customized drawer but not on android studio default drawer. Kindly help me.
navigation drawer.class :
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
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();
}
});
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open,
R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView)
findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
app_main.xml:
<?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">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<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>
app_bar_main.xml :
<?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.spykid.navig.navig_sample.Main2Activity">
<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/content_main" />
<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="#android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
Here in app_bar_main layout i would like to change that
include layout="#layout/content_main" with my activity or fragment so that i can have the same layout.
Thanks in advance.
Create an Activity containing only NavigationDrawer and after that OnItemSelected from NavigationDrawer call every activity you want. Then NavigationDrawer will be available in all the activities.
The other solution is create MainActivity with NavigationDrawer and create other Fragments instead of Activities. Call those Fragmnets OnItemSelected from NavigationDrawer. There are alot of example available there.
Edit
In your activity where you have defined navigationDrawer, do the following. And instead of creating new activities for next layouts, create fragments and call them on OnItemSelected on navigationDrawer like below:
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
// This method will trigger on item Click of navigation menu
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
//Checking if the item is in checked state or not, if not make it in checked state
if (menuItem.isChecked()) menuItem.setChecked(false);
else menuItem.setChecked(true);
//Closing drawer on item click
drawerLayout.closeDrawers();
//Check to see which item was being clicked and perform appropriate action
switch (menuItem.getItemId()) {
//Replacing the main content with ContentFragment Which is our Inbox View;
case R.id.drawer_home:
Intent intent=new Intent(HomeActivity.this, HomeActivity.class);
startActivity(intent);
overridePendingTransition(0, 0);
finish();
return true;
// For rest of the options we just show a toast on click
case R.id.drawer_artist:
android.support.v4.app.FragmentManager fragmentManager=getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new ArtistsFragment());
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
return true;
default:
Toast.makeText(getApplicationContext(), "Somethings Wrong", Toast.LENGTH_SHORT).show();
return true;
}
}
});
Fragment code will be like:
public class ArtistsFragment extends Fragment {
public ArtistsFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootview= inflater.inflate(R.layout.fragment_artists, container, false);
return rootview;
}}
activity_main.xml:
<android.support.v4.widget.DrawerLayout
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:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:elevation="4dp"
android:layout_height="fill_parent"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<include
android:id="#+id/tool_bar"
layout="#layout/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
/>
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/home">
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
</LinearLayout>
</FrameLayout>
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
android:background="#drawable/bg_all"
app:itemIconTint="#android:color/white"
app:itemTextColor="#android:color/white"
app:theme="#style/list_item_appearance"
app:menu="#menu/drawer_menu" >
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
I want to change the app I have created so far, in order to implement a ListView. I followed this example and this example. The examples alone work, but not together with the changes I had to make to my so-far existing app.
I have a avticity_main.xml defined as follows:
<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=".MainActivity" >
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
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"/>
</android.support.design.widget.AppBarLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/main_grid"
android:useDefaultMargins="true"
android:alignmentMode="alignBounds"
android:columnOrderPreserved="false"
android:columnCount="4"
>
<TextView
android:text="MainTitle"
android:textSize="32dip"
android:layout_columnSpan="4"
android:layout_gravity="center_horizontal"
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ListView
android:id="#+id/list"
android:layout_height="wrap_content"
android:layout_width="match_parent">
</ListView>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
and I have the following code for my main activity:
public class MainActivity extends AppCompatActivity {
static final String[] MOBILE_OS =
new String[] { "Android", "iOS", "WindowsMobile", "Blackberry"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ListView list = (ListView) findViewById(R.id.list);
list.setAdapter(new ListAdapter(this, MOBILE_OS));
The code compiles fine, but no list is shown.
ListActivity is a "convenience" class to implement a simple ListView. And that's pretty much all you can do. So, there's no setSupportActionBar(Toolbar) there.
To achieve what you want, use AppCompatActivity or default Activity.
This link provides a nice tutorial on how to use the new ToolBar instead of the old ActionBar.
You want something like this:
This layout example could be used:
P.S.: "#color/primary" could be any color like #FF009688.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="#+id/toolbar"
android:background="#color/primary"
android:elevation="4dp">
</android.support.v7.widget.Toolbar>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/toolbar"
android:id="#+id/lv"></ListView>
</RelativeLayout>
And on the Java side:
YourActivity.java
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private ListView lv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
lv = (ListView) findViewById(R.id.lv);
setSupportActionBar(toolbar);
final ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu_white_24dp);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true);
}
// Populate the ListView here...
}
}
EDIT: This other answer of mine can show you how to create a Custom Adapter to display the data you want on the ListView.
Second edit: Use this layout
<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=".MainActivity" >
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
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"/>
</android.support.design.widget.AppBarLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/main_grid"
android:useDefaultMargins="true"
android:alignmentMode="alignBounds"
android:columnOrderPreserved="false"
android:columnCount="4"
android:orientation="vertical">
<TextView
android:text="MainTitle"
android:textSize="32dip"
android:layout_columnSpan="4"
android:layout_gravity="center_horizontal"
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ListView
android:id="#+id/list"
android:layout_height="wrap_content"
android:layout_width="match_parent">
</ListView>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
What did I do?
Your LinearLayout was lacking the orientation parameter on the XML, and your TextView had a android:layout_height set to match_parent, so it was filling the entire layout. I've changed it to wrap_content and you're good to go.
setSupportActionBar(toolbar) is not available in ListActivity. You can use AppCompatActivity instead and just get a reference to the listview:
ListView list = findViewById(R.id.list); and use list.setAdapter(adapter) instead of setListAdapter(adapter);
You can't do that in ListActivity.
If you want to access getSupportActionBar(), you need to extent your class by AppCompatActivity.
My Suggestion : Don`t use ListActivty is you want to use ToolBar. Create an Activity and then only have ListView within that Activity. It'll work just fine.
OR
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
// Set an OnMenuItemClickListener to handle menu item clicks
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
// Handle the menu item
return true;
}
});
// Inflate a menu to be displayed in the toolbar
toolbar.inflateMenu(R.menu.your_toolbar_menu);
}`
You can use the new AppCompatDelegate component provided by the Support Library to easily add a Toolbar to your ListActivity.
Follow this link,
How to add Toolbar to an Activity which doesn't extend AppCompatActivity
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">
I'm working on a material design version of my app using the appcompat v7 libraries, and I've hit an issue with the navigation drawer. When it opens, buttons in the material design toolbar cease to function - any touch outside the navigation drawer just closes the drawer. A following is a gif of what I mean
Here is the xml layout I'm using for the activity:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/action_toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:elevation="4dp"
/>
<FrameLayout
android:id="#+id/note_list_container"
android:layout_marginTop="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<net.rymate.notes.ui.FloatingActionButton
android:id="#+id/fabbutton"
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_gravity="bottom|right"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp" />
</FrameLayout>
<!-- The navigation drawer -->
<LinearLayout
android:id="#+id/left_drawer"
android:layout_width="300dp"
android:layout_marginTop="?attr/actionBarSize"
android:layout_height="match_parent"
android:layout_gravity="start"
android:orientation="vertical">
<ListView
android:id="#+id/cat_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="?catBackColour" />
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
And here is the onCreate code that initialises the drawer and the toolbar.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ROBOTO_LIGHT = Typeface.createFromAsset(this.getAssets(), "Roboto-Light.ttf");
ROBOTO_LIGHT_ITALICS = Typeface.createFromAsset(this.getAssets(), "Roboto-LightItalic.ttf");
setContentView(R.layout.activity_notes);
if (findViewById(R.id.note_container) != null) {
// The detail container view will be present only in the
// large-screen layouts (res/values-large and
// res/values-sw600dp). If this view is present, then the
// activity should be in two-pane mode.
mTwoPane = true;
// In two-pane mode, list items should be given the
// 'activated' state when touched.
FragmentManager fm = getSupportFragmentManager();
//list.setActivateOnItemClick(true);
}
if (!mTwoPane) {
final FloatingActionButton mFab = (FloatingActionButton) findViewById(R.id.fabbutton);
mFab.init(Color.parseColor("#1e90ff"));
mFab.setFabDrawable(getResources().getDrawable(R.drawable.ic_action_new));
mFab.showFab();
mFab.setOnClickListener(this);
list = new NotesListFragment(mFab);
} else {
list = new NotesListFragment();
}
Toolbar toolbar = (Toolbar) findViewById(R.id.action_toolbar);
setSupportActionBar(toolbar);
getSupportFragmentManager().beginTransaction()
.replace(R.id.note_list_container, list)
.commit();
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); // the layout
mDrawerLinear = (LinearLayout) findViewById(R.id.left_drawer);
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
mDrawerLayout.setScrimColor(getResources().getColor(android.R.color.transparent));
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
toolbar, /* toolbar */
R.string.drawer_open, /* "open drawer" description */
R.string.drawer_close /* "close drawer" description */
) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
getSupportActionBar().setTitle("Rymate Notes");
supportInvalidateOptionsMenu();
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
getSupportActionBar().setTitle("Categories");
supportInvalidateOptionsMenu();
}
};
// Set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
pref = getSharedPreferences("rymatenotesprefs", MODE_PRIVATE);
mDrawerList = (ListView) findViewById(R.id.cat_list);
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
mDbHelper = new NotesDbAdapter(this);
mDbHelper.open();
if (mDbHelper.fetchAllNotes().getCount() == 0) {
IntroFragment fragment = new IntroFragment();
getSupportFragmentManager().beginTransaction()
.replace(R.id.note_list_container, fragment)
.commit();
}
getCategories(); // calls a function which populates the listview
}
Is there a way to possibly fix this?
Seems that touch event is stolen by the shadow of the drawer, i.e DrawerLayout keeps intercepting the touch events, because Toolbar is part of the content view, unlike the ActionBar being on top of the decor view.
Possible work around is intercepting the touch event:
If it s between 0 (top) and Toolbar height (bottom), dispatch the event directly to the Toolbar object. Otherwise keep the normal behaviour.
Is same case for drawer toggle clicks?
Turns out Nikola Despotoski had the right idea - the touch event was stolen by the DrawerLayout. However instead of intercepting the touch event I just adjusted the activity layout like so:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<android.support.v7.widget.Toolbar
android:id="#+id/action_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:minHeight="?attr/actionBarSize"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize" >
<!-- The main content view -->
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/note_list_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<net.rymate.notes.ui.FloatingActionButton
android:id="#+id/fabbutton"
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_gravity="bottom|right"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp" />
</FrameLayout>
<!-- The navigation drawer -->
<LinearLayout
android:id="#+id/left_drawer"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:orientation="vertical">
<ListView
android:id="#+id/cat_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?catBackColour"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp" />
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
</FrameLayout>
This has the intended effect of allowing touch events to be registered by the Toolbar rather than the DrawerLayout.