Navigation drawer for multiple activities not working - java

I'm trying to get the same navigation drawer for multiple activities. At the moment I have a BaseActivity that holds the navigation drawer and a MainActivity that extends the BaseActivity class. It works fine when i run the BaseActivity first but instead if i run MainActivity first (Which is what I want to do) the navigation drawer doesn't work when i swipe the screen from left to right. I've been stuck on this for while now and can't seem to figure out what I am missing. Any help would be appreciated.
HomeActivity Class
public class HomeActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
}
}
BaseActivity Class
public class BaseActivity extends ActionBarActivity {
private String[] menuList;
private DrawerLayout drawerLayout;
private ListView listView;
private ActionBarDrawerToggle drawerToggle;
private CharSequence drawerTitle;
private CharSequence title;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
// Initialize drawer's list of items. Get the array for the list
menuList = getResources().getStringArray(R.array.menuItems);
// Get the drawers layout
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
// Get the list view
listView = (ListView) findViewById(R.id.list_view);
// Creating an ArrayAdapter to add items to the listview listView
listView.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1,
menuList));
// Set listener for the list item clicks
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView adapterView, View view, int i, long l) {
}
});
}
activity_base.xml
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->
<FrameLayout
android:id="#+id/frame_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- The navigation drawer -->
<ListView
android:id="#+id/list_view"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="10dp" />
</android.support.v4.widget.DrawerLayout>

Related

TabLayout swiping does not change Tab focus

I have a tabLayout and a viewPager underneath it. When I click on the tab, it switches tabs perfectly fine. However, when I swipe, the viewPage swipes over, but the tab does not change focus. I have to manually click on the corresponding tab in order to change the focus (viewPager does not change).
For example, if I'm on the 4th slide, and I swipe left, the viewPage goes to the 3rd slide, but the tab isn't focused over. I have to manually tap on the 3rd tab in order to change the focus.
I'm wondering how I can let the tabs follow the swiping when I swipe from view to view in the viewPager.
fragment XML:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.tabs.TabLayout
android:layout_height="wrap_content"
android:id="#+id/tab_layout"
android:layout_width="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="#id/pager"/>
<androidx.viewpager.widget.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</androidx.constraintlayout.widget.ConstraintLayout>
PagerFragment:
public class PagerFragment extends Fragment {
ViewPagerAdapter pagerAdapter;
ViewPager pager;
TabLayout tl;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pagerAdapter = new ViewPagerAdapter(this.getContext(), getChildFragmentManager(), 4, getActivity());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = super.onCreateView(inflater, container, savedInstanceState);
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragment_pager, null);
pager = root.findViewById(R.id.pager);
pager.setAdapter(pagerAdapter);
tl = root.findViewById(R.id.tab_layout);
tl.addTab(tl.newTab().setText("1"));
tl.addTab(tl.newTab().setText("2"));
tl.addTab(tl.newTab().setText("3"));
tl.addTab(tl.newTab().setText("4"));
tl.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
pager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
tl.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(pager));
return root;
}
}
Adapter:
public class ViewPagerAdapter extends FragmentPagerAdapter {
private Context myContext;
int totalTabs;
public ViewPagerAdapter(Context context, FragmentManager fm, int totalTabs, FragmentActivity fa) {
super(fm);
myContext = context;
this.totalTabs = totalTabs;
}
public Fragment getItem(int position) {
graph_test gt = new graph_test(String.valueOf(position), position);
return gt;
}
#Override
public int getCount() {
return totalTabs;
}
}
Note: I know that FragmentPagerAdapter is deprecated. I was asked to do it this way.
Thanks.
Using the androidx.viewpager.widget.ViewPager you have to set also the ViewPager.OnPageChangeListener with TabLayout.TabLayoutOnPageChangeListener like the below:
pager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tl));
By doing the above you should be able to change the Tab focus when swiping the ViewPager left or right.
onViewCreated() use
TabLayoutMediator(tabLayout, viewPager){ tab, position ->
// set tab text by given *position*
tab.text = "Tab_{position}" // for example
}.atach()
to link TabLayout and ViewPager and atach it

How can I nest fragments with a navigation drawer?

I've been trying for the last few hours to search around SO, but I couldn't find a solution outside of trying to create a workaround. I'm trying to create a navigation drawer for my app, but to do so I had to end up trying to change my base activity into a fragment. This is the result:
public class ToolReaderActivity extends Fragment implements ToolListFragment.OnToolSelectedListener, CompatActionBarNavListener, OnClickListener {
boolean mIsDualPane = false;
Context c;
ToolListFragment mToolListFragment;
InfoFragment mInfoFragment;
Fragment mContent;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
c = getActivity();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.onepane_with_bar, container, false);
// find our fragments
mToolListFragment = (ToolListFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.toolList);
mInfoFragment = (InfoFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.toolInfo);
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.toolList, mToolListFragment).commit();
FragmentTransaction transaction2 = getActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.toolInfo, mInfoFragment).commit();
mToolListFragment.setContext(c);
mToolListFragment.setOnToolSelectedListener(this);
View infoView = getView().findViewById(R.id.toolInfo);
mIsDualPane = infoView != null && infoView.getVisibility() == View.VISIBLE;
int catIndex = savedInstanceState == null ? 0 : savedInstanceState.getInt("catIndex", 0);
setUpActionBar(mIsDualPane, catIndex);
mToolListFragment.setSelectable(mIsDualPane);
restoreSelection(savedInstanceState);
if (savedInstanceState != null) {
//Restore the fragment's instance
mContent = getActivity().getSupportFragmentManager().getFragment(savedInstanceState, "mContent");
}
return rootView;
}
...
...
...
}
The intended output is a activity with a navigation drawer and thus a fragment. The fragment contains this main activity ToolReaderActivity (named so because it was formerly an activity) which has 1-2 fragments inside of it. It's a ListFragment with a fragment showing the selected items information (as either another fragment if mDualPane is true or launched as a seperate activity otherwise).
I can't figure out a way to get this to work, I've tired changing the order that things are done using onCreate, onCreateView, onActivityCreated, but the error I keep getting is that mToolsListFragment is null at mToolsListFragment.setContext(c);
You can simply create NavigationDrawer with the code below.
public class MainActivity extends AppCompatActivity
{
private NavigationView mNavigationView;
private DrawerLayout mDrawerLayout;
private Toolbar toolbar;
private ActionBarDrawerToggle mDrawerToggle;
private FragmentActivity fragment;
private FragmentManager fragmentManager;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initDrawerNavigation();
fragmentManager = getFragmentManager();
}
public void initDrawerNavigation()
{
toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle(R.string.app_name);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mNavigationView = (NavigationView) findViewById(R.id.navigation_view);
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener()
{
#Override
public boolean onNavigationItemSelected(MenuItem item)
{
item.setChecked(true);
switch (item.getItemId())
{
case R.id.st_menu:
fragment = new FirstFragment();
break;
case R.id.nd_menu:
fragment = new Second Fragment();
break;
}
fragmentManager.beginTransaction().replace(R.id.container, fragment).commit();
mDrawerLayout.closeDrawers();
return true;
}
});
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.drawer_open,
R.string.drawer_close)
{
// Called when a drawer has settled in a completely closed state.
public void onDrawerClosed(View view)
{
super.onDrawerClosed(view);
}
// Called when a drawer has settled in a completely open state.
public void onDrawerOpened(View drawerView)
{
super.onDrawerOpened(drawerView);
}
};
mDrawerLayout.addDrawerListener(mDrawerToggle);
}
#Override
protected void onPostCreate(Bundle savedInstanceState)
{
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}
#Override
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId())
{
case android.R.id.home:
mDrawerLayout.openDrawer(GravityCompat.START); // OPEN DRAWER
return true;
}
return super.onOptionsItemSelected(item);
}
}
Here you have activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:theme="#style/ThemeOverlay.AppCompat.ActionBar" />
<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:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity">
<include
layout="#layout/your_layout" />
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
app:menu="#menu/navigation_items" />
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
your_layout can be anything you want. Now you define your FirstFragment class like here:
public class FirstFragment extends Fragment
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
ViewGroup view = (ViewGroup) inflater.inflate(R.layout.target_layout, container, false);
return view;
}
}
You can also refer to this question Navigation Drawer to switch between activities if you want to switch between activities and not fragments. Hope this helps.

android toolbar inside a tab

I want to make a toolbar inside one of my tabs but nothing works for me. Can this even be done? I currently have a toolbar above my tabs but i need it to appear inside the first tab.
Here's the code (with the toolbar above tabs):
import ...
public class MainActivity extends ActionBarActivity {
Toolbar toolbar;
ViewPager pager;
ViewPagerAdapter adapter;
SlidingTabLayout tabs;
CharSequence Titles[] = {"Projects", "People", "Files"};
int Numboftabs = 3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
adapter = new ViewPagerAdapter(getSupportFragmentManager(), Titles, Numboftabs);
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true);
tabs.setViewPager(pager);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_primary, menu);
return true;
}
final ArrayList<String> listItems = new ArrayList<String>();
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.addButton) {
final TextView noProject = (TextView) findViewById(R.id.NOPROJECT);
final ListAdapter addAdapter = new ArrayAdapter<String>(this,
R.layout.list_item, R.id.listFrame, listItems);
final ListView lv = (ListView) findViewById(R.id.lv);
lv.setAdapter(addAdapter);
noProject.setVisibility(View.GONE);
lv.setVisibility(View.VISIBLE);
listItems.add("New Project");
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent switchToEdit = new Intent(MainActivity.this,
TeamCreate.class);
startActivity(switchToEdit);
}
});
}
return super.onOptionsItemSelected(item);
}
}
First tab:
import ...
public class Tab1 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.tab_1,container,false);
return v;
}
}
I faced a similar challenge with a non-standard toolbar and tabs and got past it, though frankly the results were odd looking. You can probably get the toolbar to work under the tab using a similar technique, however it may leave your users scratching their heads. Your technique will have 2 toolbars, one holding the TabLayout widget and another one inside the fragment(s) in the ViewPager.
I was using Material Design tabs for the Detail view in my app. It looked fine until I did the 2-pane Master-Detail view for tablets. Then I had an issue with the tabs wanting to be directly under the toolbar, but no obvious way to have the Master & Detail share the toolbar with the tabs only showing up under the Detail portion of the screen.
I got it working by:
Create a "NoActionBar" style in styles.xml, then refer to it in your main layout using "android:theme="#style/AppTheme".
<!-- Turn off normal application bar so we can put our toolbars where we please.
Do this by replacing "Theme.AppCompat.Light.DarkActionBar" with NoActionBar
per http://www.truiton.com/2015/04/android-action-bar-dialog-using-toolbar/ -->
<style name="AppTheme" parent="MaterialTheme.Base"/>
<style name="MaterialTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
<item name="windowNoTitle">true</item>
<!--We will be using the toolbar so no need to show ActionBar-->
<item name="windowActionBar">false</item>
Toss android.support.design.widget.CoordinatorLayout and just use a LinearLayout.
Here is a snippet that has the toolbar containing the tabs only taking up part of the screen real estate rather than the entire width. Note that the toolbar has "app:layout_scrollFlags="scroll|enterAlways":
<FrameLayout android:id="#+id/detail_container"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:layout_weight="2"
tools:name="com.android.bazemom.popularmovies.TabContainerFragment"
>
<!-- second toolbar that will be used for the tabs -->
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
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="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"
/>
<android.support.design.widget.TabLayout
android:id="#+id/tabanim_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<!-- Helps handing the Fragments to load for each Tab -->
<android.support.v4.view.ViewPager
android:id="#+id/tabanim_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
Here is what the Master-Detail view looked like on wide tablet. The tabs are circled in green. The toolbar with an action is above the tabs.

How to Display Navigation Drawer in all activities?

I have a Navigation Drawer which should appear in all my activities.
I saw many questions similar to this & found a solution like Extending the MainActivity with the Other Activities .
So i extended My Main Activity to my Second Activity.But the Drawer is not being showed in the Second Activity
MainActivity
public class MainActivity extends ActionBarActivity
{
private ListView mDrawerList;
private DrawerLayout mDrawer;
private CustomActionBarDrawerToggle mDrawerToggle;
private String[] menuItems;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR);
// getSupportActionBar().hide();
setContentView(R.layout.activity_main_drawer);
// enable ActionBar app icon to behave as action to toggle nav drawer
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
// set a custom shadow that overlays the main content when the drawer
// opens
mDrawer.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
_initMenu();
mDrawerToggle = new CustomActionBarDrawerToggle(this, mDrawer);
mDrawer.setDrawerListener(mDrawerToggle);
}
private void _initMenu()
{
NsMenuAdapter mAdapter = new NsMenuAdapter(this);
// Add Header
mAdapter.addHeader(R.string.ns_menu_main_header);
// Add first block
menuItems = getResources().getStringArray(R.array.ns_menu_items);
String[] menuItemsIcon = getResources().getStringArray(R.array.ns_menu_items_icon);
int res = 0;
for (String item : menuItems)
{
int id_title = getResources().getIdentifier(item, "string", this.getPackageName());
int id_icon = getResources().getIdentifier(menuItemsIcon[res], "drawable", this.getPackageName());
NsMenuItemModel mItem = new NsMenuItemModel(id_title, id_icon);
// if (res==1) mItem.counter=12; //it is just an example...
// if (res==3) mItem.counter=3; //it is just an example...
mAdapter.addItem(mItem);
res++;
}
mAdapter.addHeader(R.string.ns_menu_main_header2);
mDrawerList = (ListView) findViewById(R.id.drawer);
if (mDrawerList != null)
mDrawerList.setAdapter(mAdapter);
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
}
#Override
protected void onPostCreate(Bundle savedInstanceState)
{
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.control_menu, menu);
return super.onCreateOptionsMenu(menu);
}
/* Called whenever we call invalidateOptionsMenu() */
#Override
public boolean onPrepareOptionsMenu(Menu menu)
{
// If the nav drawer is open, hide action items related to the content
// view
boolean drawerOpen = mDrawer.isDrawerOpen(mDrawerList);
menu.findItem(R.id.action_keyboard).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
/*
* The action bar home/up should open or close the drawer.
* ActionBarDrawerToggle will take care of this.
*/
if (mDrawerToggle.onOptionsItemSelected(item))
{
return true;
}
// Handle your other action bar items...
return super.onOptionsItemSelected(item);
}
private class CustomActionBarDrawerToggle extends ActionBarDrawerToggle
{
public CustomActionBarDrawerToggle(Activity mActivity, DrawerLayout mDrawerLayout)
{
super(mActivity, mDrawerLayout, R.drawable.ic_drawer, R.string.ns_menu_open, R.string.ns_menu_close);
}
#Override
public void onDrawerClosed(View view)
{
getSupportActionBar().setTitle(getString(R.string.ns_menu_close));
supportInvalidateOptionsMenu(); // creates call to
// onPrepareOptionsMenu()
}
#Override
public void onDrawerOpened(View drawerView)
{
getSupportActionBar().setTitle(getString(R.string.ns_menu_open));
supportInvalidateOptionsMenu(); // creates call to
// onPrepareOptionsMenu()
}
}
private class DrawerItemClickListener implements ListView.OnItemClickListener
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
Intent intent = new Intent(MainActivity.this, Tutorial.class);
startActivity(intent);
}
}
}
SecondActivity
public class Tutorial extends MainActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.help);
}
}
Here is my implementation.. hope it help
FIRST, this POST is concept.
SECOND, this is also the KEY one.
FINALLY, Here is combination of all answer in one place
BASE ACTIVITY
This is a base activity for all other activity
You can extends Activity or FragmentActivity or etc. base on your requirement.
Navigation Drawer setup here for one time.
public class BaseActivity extends FragmentActivity {
protected DrawerLayout mDrawer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.base_layout);
mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);
//This is about creating custom listview for navigate drawer
//Implementation for NavigateDrawer HERE !
ArrayList<DrawerListItem> drawerListItems = new ArrayList<DrawerListItem>();
drawerListItems.add(new DrawerListItem(0,"AIRĀ° DEVICES"));
drawerListItems.add(new DrawerListItem(1,"A/C Device [1]"));
drawerListItems.add(new DrawerListItem(1,"A/C Device [2]"));
drawerListItems.add(new DrawerListItem(1,"A/C Device [3]"));
drawerListItems.add(new DrawerListItem(0,"AIRĀ° FEATURES"));
drawerListItems.add(new DrawerListItem(2,"SLEEP MODE"));
drawerListItems.add(new DrawerListItem(2,"TRACKING MODE"));
drawerListItems.add(new DrawerListItem(2,"SETTINGS"));
DrawerAdapter mDrawerAdapter = new DrawerAdapter(this, R.layout.drawer_list_header, drawerListItems);
ListView mDrawerList = (ListView) findViewById(R.id.left_drawer);
mDrawerList.setAdapter(mDrawerAdapter);
}
}
BASE ACTIVITY XML
This xml layout is for Navigation Drawer
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<!-- The navigation drawer -->
<ListView
android:id="#+id/left_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="left"
android:scrollingCache="false"
android:background="#drawable/drawer_bg"
android:divider="#null"
android:choiceMode="singleChoice"/>
</android.support.v4.widget.DrawerLayout>
ALL OTHERS ACTIVITY
Other Activity just extends BaseActivity and define code as below.
The Navigation Drawer will appear for particular activity.
mDrawer is form BaseActivity. it's a protected variable.
public class Screen1 extends BaseActivity
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//inflate your activity layout here!
View contentView = inflater.inflate(R.layout.screen1, null, false);
mDrawer.addView(contentView, 0);
//Do the rest as you want for each activity
}
SCREEN 1 XML SAMPLE
Design as you wish it each activity. no more Navigation Drawer Layout !
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
NOTE
In this implementation, The Navigation Drawer doesn't bind with Action Bar. If you wish to do that do it in BaseActivity.Also, This guide is not cover all requirement. It's just a sample.
in onCreate of TutorialActivity don't call setContentView instead do this:
#Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
LayoutInflater inflater = (LayoutInflater) this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View contentView = inflater.inflate(R.layout.help, null, false);
mDrawer.addView(contentView, 0);
}
make mDrawer in MainActivity protected. and in R.layout.activity_main_drawer just keep drawer tag and the element with gravity left(or right).
I made a BaseActivity activity which extends SherlockActivity (or ActionBarActivity if is your case)
public class BaseActivity extends SherlockActivity
Then, make all your activities extends BaseActivity, like:
public class GlossaryActivity extends BaseActivity
Later, you must replace the activity layout with the one that correspond to your activity, I made a method in BaseActivity like that:
protected void replaceContentLayout(int sourceId, int destinationId) {
View contentLayout = findViewById(destinationId);
ViewGroup parent = (ViewGroup) contentLayout.getParent();
int index = parent.indexOfChild(contentLayout);
parent.removeView(contentLayout);
contentLayout = getLayoutInflater().inflate(sourceId, parent, false);
parent.addView(contentLayout, index);
}
I called this method on the onCreate method in each activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.replaceContentLayout(R.layout.activity_glossary, super.CONTENT_LAYOUT_ID);
}
super.CONTENT_LAYOUT_ID is the FrameLayout of the BaseActivity, and other param is the layout you want replace with
You omitted the #Override from your derived class onCreate.
UPDATE: I'm not sure what the effects are of calling setContentView twice but that could be the problem. Separate out the code that sets up the drawer, and call that from both of the onCreate methods.
I had this problem too. This is my implementation:
activity_main.xml - the child at index 1 in the CoordinatorLayout is the content_main.xml, this I can change in code.
<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"
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.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>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
I've created a class that uses inflates the others activities UI:
public class MyLayoutInflater {
public void inflate(Activity activity, int LayoutResource, android.app.ActionBar getSupportActionBar, Intent getIntent){
CoordinatorLayout coordinatorLayout = (CoordinatorLayout) activity.findViewById(R.id.coordinator);
android.view.LayoutInflater inflater = (android.view.LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View contentView = inflater.inflate(LayoutResource, null, false);
//change i so that it suits the child number in you coordinator layout
int i = 1;
coordinatorLayout.removeViewAt(i);
coordinatorLayout.addView(contentView, i);
getSupportActionBar.setTitle(actionBarTitle);
}
public void inflate(Activity activity, int LayoutResource, android.support.v7.app.ActionBar getActionBar, String actionBarTitle){
CoordinatorLayout coordinatorLayout = (CoordinatorLayout) activity.findViewById(R.id.coordinator);
android.view.LayoutInflater inflater = (android.view.LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View contentView = inflater.inflate(LayoutResource, null, false);
//change i so that it suits the child number in you coordinator layout
int i = 1;
coordinatorLayout.removeViewAt(i);
coordinatorLayout.addView(contentView, i);
getActionBar.setTitle(actionBarTitle);
}
}
Now on the other activities all you have to do is extend the MainActivity and call this method and give it the necessary parameters:
public class AnotherActivity extends MainActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new MyLayoutInflater().inflate(this,R.layout.content_activity_another, getSupportActionBar(), getIntent());
}
}
Ok here is hacky way to do this, I use it only for special kind of debug build to set properties of views in realtime (design tool).
It has advantage that you can use your child activities as usual without, special behavior that is required in different answers.
so in BaseActvity you can add:
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// WARNING: Hacky, use carefully!!!
ViewGroup androidBaseView = (ViewGroup) findViewById(android.R.id.content);
//this one in what child activity has just set in setContentView()
ViewGroup childContent = (ViewGroup) androidBaseView.getChildAt(0);
View drawerView = LayoutInflater.from(this)
.inflate(R.layout.base_activity_drawer, androidBaseView, false);
FrameLayout frameLayout = (FrameLayout) drawerView.findViewById(R.id.content);
androidBaseView.removeView(childContent);
frameLayout.addView(childContent);
androidBaseView.addView(drawerView);
}
and xml for drawer is just:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/nav_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<LinearLayout
android:id="#+id/drawer_for_components"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:orientation="vertical"
android:fitsSystemWindows="true"
/>
</android.support.v4.widget.DrawerLayout>
Here is a simple and fast way to do it in android studio:
Create a new activity (Navigation drawer activity) from the gallery, and name it whatever you want, android studio will create everything for you (the class and the xml files that you can customize it later)
In other activities you should extend your Navigation drawer activity, and make sure these other activities has "no action bar" in the manifests file (android:theme="#style/AppTheme.NoActionBar")
You should modify your other activities as follows:
public class Mainactivity extends NavActivity
{
super.onCreate(savedInstanceState);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//inflate your activity layout here!
View contentView = inflater.inflate(R.layout.activity_main, null, false);
drawer.addView(contentView, 0);
}
Note: the mainactivity will extend the action bar of the NavActivity, the NavActivity has a full functional action bar that will call the navigation drawer
I hope it will work with you
Nowadays you should use Single-Activity App Architecture (source).
Then simple add Navigation Drawer to Main Activity
you can simply use <include/>
By creating a nav drawer
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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">
and then include the layout in it
<include
layout="#layout/activity_accounts"
android:layout_width="match_parent"
android:layout_height="match_parent" />
in your main activity make setContentView(R.layout.your_drawer_activity)
take note that if you use this method you have to create a nav drawer layout for every activity you have, unless you found a way to do includes programmatically.

Using a DrawerLayout along with a ListView

I'm trying to write an android app with a listview of a few different items and also a drawerlayout that you can drag from the left side of the screen. Here's what i mean....
This is what the main screen looks like:
And here's what the drawer menu thing looks like:
The problem i'm having is that when I open the side drawer menu thing and tap an option it doesn't work and the menu just closes. However i'm able to interact with the main listview page. Here's what my code looks like:
String[] homeArray = { "Test", "Test", "Test", "Test", "Test", "Test", "Test", "Test", "Test", "Test", "Test", "Test", "Test", "Test", "Test" };
private ListView homeListView;
private ArrayAdapter arrayAdapter;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mDrawerTitles;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTitle = mDrawerTitle = getTitle();
mDrawerTitles = getResources().getStringArray(R.array.Menu);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
// Set the adapter for the list view
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_list_item, mDrawerTitles));
And the activity_main.xml:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_height="match_parent"
android:layout_width="match_parent"
>
<FrameLayout
android:id="#+id/content_frame"
android:layout_height="match_parent"
android:layout_width="match_parent" />
<ListView
android:id="#+id/left_drawer"
android:layout_height="match_parent"
android:layout_width="240dp"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/darker_gray"
android:dividerHeight="1dp"
android:background="#111"
/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ListActivity" >
<ListView
android:id="#+id/homeListView"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
I have a feeling the problem is in the xml but i'm not sure.
Please post the full code of your Activity that holds the NavigationDrawer.
Furthermore, I would strongly recommend (and so would Google) that you use Fragments for the individual NavigationDrawer sections ("Settings", "Submit Bug" and "Help" in your case).
Do not put all the layout components into the layout file of your Activity.
The layout therefore should look like the following:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- The navigation drawer -->
<ListView android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#111"/>
</android.support.v4.widget.DrawerLayout>
The FrameLayout content_frame is where your Fragment that holds the ListView will go into.
Simply create a custom Fragment (or use a ListFragment) that contains the ListView you displayed in your picture and insert it into the "content_frame".
Use this to replace Fragments inside the content frame: (when you switch your section)
/** Swaps fragments in the main content view */
private void selectItem(int position) {
// Create a new fragment and specify the planet to show based on position
Fragment fragment = new YourListFragment(); // this fragment contains the list with all the "test" items
// Insert the fragment by replacing any existing fragment
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.commit();
// Highlight the selected item, update the title, and close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(mPlanetTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
An Example of how your Fragment could look like: YourListFragment.java
The layout file "list_fragment.xml" simply contains whatever layout components you want. For example a ListView. Initialize an populate the ListView inside the Fragments onCreateView() method.
public class YourListFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.list_fragment, container, false);
return rootView;
}
}
All taken from Googles example on how to create a NavigationDrawer:
http://developer.android.com/training/implementing-navigation/nav-drawer.html

Categories