I'm trying to implement a Navigation Drawer and I managed successfully to integrate it with the Action Bar: it opens and closes when the application button is pressed and it closes when I press on a blank part of the screen, but it does not allow to be dragged back to its original position. Once opened, I can't close it with a swipe (as in every application I have seen so far).
Here is my Java code:
package com.example.notificationswhisperer;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
public class MainActivity
extends Activity {
private DrawerLayout drawerLayout;
private ListView drawerList;
private ActionBarDrawerToggle drawerToggle;
private List<AppDrawerItem> drawerItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notifications_whisperer);
drawerItems = new ArrayList<AppDrawerItem>();
drawerItems.add(
new AppDrawerItem("Settings",
getResources().getDrawable(R.drawable.ic_action_settings)));
drawerItems.add(
new AppDrawerItem("Test",
getResources().getDrawable(R.drawable.ic_action_settings)));
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
drawerLayout = (DrawerLayout) findViewById(R.id.layout_app_drawer);
drawerToggle = new ActionBarDrawerToggle(
this, // Context
drawerLayout, // DrawerLayout object
R.drawable.ic_drawer, // Drawer icon
0, // Open Drawer description
0) { // Closed Drawer description
public void onDrawerOpened(View view) {
super.onDrawerOpened(view);
invalidateOptionsMenu();
}
public void onDrawerSlide(View view, float offset) {
if (offset > .5) {
onDrawerOpened(view);
} else {
onDrawerClosed(view);
}
}
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
invalidateOptionsMenu();
}
};
drawerLayout.setDrawerListener(drawerToggle);
drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, Gravity.START);
drawerList = (ListView) findViewById(R.id.list_app_drawer);
drawerList.setAdapter(new AppDrawerAdapter(this, drawerItems));
drawerList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
drawerList.setItemChecked(position, true);
drawerLayout.closeDrawer(drawerList);
}
});
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
drawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);
drawerToggle.onConfigurationChanged(config);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.notifications_whisperer, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (drawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
This is my layout for the activity:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/layout_app_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.notificationswhisperer.NotificationsWhisperer" >
<ListView
android:id="#+id/list_app_drawer"
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/black"
android:dividerHeight="0.5dp"
android:background="#android:color/white" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
</android.support.v4.widget.DrawerLayout>
And this is for the List entries:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="vertical" >
<ImageView
android:id="#+id/list_item_app_drawer_image"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginLeft="8dp"
android:layout_centerVertical="true" />
<TextView
android:id="#+id/list_item_app_drawer_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/list_item_app_drawer_image"
android:textSize="18sp" />
</RelativeLayout>
Am I missing something? Thank you in advance.
ADDENDUM: Additionally, the back button won't close the Drawer.
I had the very same issue : the drawer could be opened by a swipe, but could only be closed by a click on the actionbar button.
After some research, it appeared that the underlying activity had several critical bugs : some fragments were added which were adding an un-initialized pager (with a null adapter)
Anyway, when I fixed these bugs (which had nothing to do with the drawer implementation), then behavior went correct.
Related
I've created menu using DrawerLayout
MainActivity.java
package com.example.vsoftwares.hamburgermenu;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private ListView mDrawerList,mDrawerList2;
private DrawerLayout mDrawerLayout;
private ArrayAdapter<String> mAdapter;
private ActionBarDrawerToggle mDrawerToggle;
private String mActivityTitle;
Context ctx;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// My code starts here
mDrawerList = (ListView)findViewById(R.id.navList); // changed listview to textview
mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
mActivityTitle = getTitle().toString();
ActionBar actionBar = getSupportActionBar();
addDrawerItems();
setupDrawer();
if (actionBar != null)
{
//actionBar.setTitle("My App Title");
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
//getSupportActionBar().setDisplayShowHomeEnabled(true);
}
// ends here
}
// MY DRAWER CODE STARTS HERE
private void addDrawerItems() {
String[] osArray = { "iOS", "Windows", "OS X", "Linux" };
mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, osArray);
mDrawerList.setAdapter(mAdapter);
mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this, "have to add content", Toast.LENGTH_SHORT).show();
}
});
}
private void setupDrawer() {
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.drawer_open, R.string.drawer_close) {
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
// getSupportActionBar().setTitle("Navigation!");
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
// getSupportActionBar().setTitle(mActivityTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerToggle.setDrawerIndicatorEnabled(true);
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
#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);
}
// ENDS HERE
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
// Activate the navigation drawer toggle
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
activity_main.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The first child in the layout is for the main Activity UI-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivity"
android:background="#FF4081">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="PAGE 1"
android:textSize="24sp"
android:gravity="center"
android:layout_marginTop="100dp"/>
</RelativeLayout>
<!-- Side navigation drawer UI -->
<ListView
android:id="#+id/navList"
android:layout_width="200dp"
android:text="hello"
android:layout_height="match_parent"
android:textColor="#000"
android:background="#FFFFFF"
android:layout_gravity="left|start"
/>
</android.support.v4.widget.DrawerLayout>
This is what I currently have:
I have tried spinner inside layout in my code, but it's not producing what I want. Please give me some help. I need it to look more like the following:
I've been at this for hours and can't seem to get the drawer to show up at all. Here is my code maybe someone can tell me what is wrong here... The app runs with no errors until I get to the activity with the Drawer then it crashes.
Here is my code:
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;
import android.support.v7.app.ActionBarDrawerToggle;
public class FlavorListView extends ActionBarActivity {
//shared preference
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
#Override
public boolean onCreateOptionsMenu(Menu action_setting) {
//MenuInflater inflater = getMenuInflater();
//inflater.inflate(R.menu.menu_welcome,action_setting);
//drawer
mTitle = mDrawerTitle = getTitle();
mDrawerLayout = (DrawerLayout) findViewById(R.id.navigation_drawer);
mDrawerToggle = new ActionBarDrawerToggle(FlavorListView.this, mDrawerLayout,
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);
getSupportActionBar().setTitle(mTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
getSupportActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
// Set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
return true;
}
/* 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 = mDrawerLayout.isDrawerOpen(mDrawerList);
//menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
//return super.onPrepareOptionsMenu(menu);
//drawer end
return true;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.select_flavor);
String[] select_flavor_list = {"Kansas City", "Memphis", "Texas", "North Carolina", "South Carolina","Alabama"};
ListAdapter FlavorListAdapter = new ArrayAdapter<String>(this, R.layout.row_layout_flavor, R.id.flavor_text_view,
select_flavor_list);
ListView listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(FlavorListAdapter);
//For list view selection, begin here...
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
//String flavorPicked = String.valueOf(parent.getItemAtPosition(position));
FoodStyleDialog cdd = new FoodStyleDialog(FlavorListView.this);
cdd.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
cdd.show();
return true;
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View v, int position, long id) {
//GlobalClass flavorPref = ((GlobalClass)getApplicationContext());
String flavorPicked = String.valueOf(adapterView.getItemAtPosition(position));
if (flavorPicked.equals("Kansas City")) {
Intent intent = new Intent(FlavorListView.this, KansasCity.class);
startActivity(intent);
setContentView(R.layout.kansas_city);
Toast.makeText(FlavorListView.this, "Looks like " + flavorPicked +
" style be your flavor! You can change your flavor anytime in the settings menu.",
Toast.LENGTH_LONG).show();
}
else if (flavorPicked.equals("Memphis")) {
Intent intent = new Intent(FlavorListView.this, KansasCity.class);
startActivity(intent);
setContentView(R.layout.kansas_city);
Toast.makeText(FlavorListView.this, "Looks like " + flavorPicked +
" style be your flavor! You can change your flavor anytime in the settings menu.",
Toast.LENGTH_LONG).show();
}
}
});
}
}
I'm getting a java.lang.NullPointerException and the debugger is saying at (FlavorListView.java:57) which is at mDrawerLayout.setDrawerListener(mDrawerToggle);
IF I comment this line out the app runs but no drawer...
please help. thanks :)
Drawer Layout xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/navigation_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- As the main content view, the view below consumes the entire
space available using match_parent in both dimensions. -->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- android:layout_gravity="start" tells DrawerLayout to treat
this as a sliding drawer on the left side for left-to-right
languages and on the right side for right-to-left languages.
The drawer is given a fixed width in dp and extends the full height of
the container. A solid background is used for contrast
with the content view. -->
<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="#ffff"/>
</android.support.v4.widget.DrawerLayout>
FlavorListView Acivity xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingBottom="16dp"
android:paddingTop="16dp"
tools:context=".FlavorListView"
>
<TextView
android:layout_width="match_parent"
android:layout_height="40dp"
android:text="Choose Your Flavor"
android:textAlignment="center"
android:textSize="30sp"
android:textStyle="bold"
android:gravity="center_horizontal"
/>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:listSelector="#drawable/abc_list_pressed_holo_light" />
</LinearLayout>
If you're getting an NPE there, then mDrawerLayout must be null. Make sure drawer_layout is the right ID to find the drawer in your XML. You need to inflate the Drawer Layout XML file too. You almost have it right (you need to replace menu_welcome below with the name of your file):
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_welcome, action_setting);
mDrawerLayout = (DrawerLayout) action_setting.findViewById(R.id.navigation_drawer);
Place below code in your onCreate and NOT in
onCreateOptionMenu
/------------------------------------------------------------/
mTitle = mDrawerTitle = getTitle();
mDrawerLayout = (DrawerLayout) findViewById(R.id.navigation_drawer);
mDrawerToggle = new ActionBarDrawerToggle(FlavorListView.this, mDrawerLayout,R.drawable.ic_menu,
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);
getSupportActionBar().setTitle(mTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
getSupportActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
// Set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
Read the example codes carefully before using it
My requirement is i need the functionality of Navigation Drawer (Navigation Menu should appear both by clicking on the toggle icon and also dragging from margin) + Drawer layout on top of the action bar.
Check this post, i want the similar action.
I had gone through many post regarding this in SO itself, most of them saying to use a third-party library to use to get this done. But i don't want to use, instead in One SO question CommonsWare said like this can be done by tweaking the Drawerlayout.
How to achieve this?
Note: I don't want to use external library as it was creating problems.
In Android Default you cannot move the DrawerLayout along with the Action Bar. However if your are keen on using the Default Navigation Drawer. Hide the Action bar and create a Top layout similar to action bar. It will move with the drawerLayout. If you want further help code wise let me know.
Find my updated answer
MainActivity.java
package com.example.android.navigationdrawerexample;
import android.annotation.SuppressLint;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.widget.DrawerLayout;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.TranslateAnimation;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Toast;
public class MainActivity extends FragmentActivity {
DrawerLayout drawerLayout;
ActionBarDrawerToggle drawerToggle;
ImageView menubtn, addbtn;
LinearLayout menuLayout;
RelativeLayout frame;
TranslateAnimation anim;
float moveFactor, lastTranslate = 0.0f;
ListView accList;
String[] menuValues = { "Add", "View" };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, new PlaceholderFragment())
.commit();
}
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
menuLayout = (LinearLayout) findViewById(R.id.menu);
accList = (ListView) findViewById(R.id.drawer_list);
frame = (RelativeLayout) findViewById(R.id.rl_main);
menubtn = (ImageView) findViewById(R.id.menu_btn);
addbtn = (ImageView) findViewById(R.id.add_btn);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, menuValues);
accList.setAdapter(adapter);
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout,
R.drawable.ic_drawer, R.string.open, R.string.close) {
public void onDrawerClosed(View view) {
}
public void onDrawerOpened(View drawerview) {
// adapter = new AccountAdapter(this, R.layout.row_acc, values);
}
#SuppressLint("NewApi")
public void onDrawerSlide(View drawerView, float slideOffset) {
// use this code only if you need the fragment to slide over, if you want the
// drawerlayout to be above the main screen then ignore this code.
//moveFactor = (menuLayout.getWidth() * slideOffset);
//drawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
// Gravity.LEFT);
//if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// frame.setTranslationX(moveFactor);
//} else {
// anim = new TranslateAnimation(lastTranslate, moveFactor,
// 0.0f, 0.0f);
// anim.setDuration(0);
// anim.setFillAfter(true);
// frame.startAnimation(anim);
// lastTranslate = moveFactor;
//}
}
};
drawerLayout.setDrawerListener(drawerToggle);
menubtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (drawerLayout.isDrawerVisible(Gravity.LEFT)) {
return;
} else {
drawerLayout.openDrawer(Gravity.LEFT);
}
}
});
accList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if (position == 0) {
// Write your code
drawerLayout.closeDrawers();
}
}
});
addbtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Toast.makeText(MainActivity.this, "Action Bar Icon code as per your requirement", Toast.LENGTH_LONG).show();
}
});
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_planet, 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"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
tools:context=".MainActivity" >
<RelativeLayout
android:id="#+id/rl_main"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:id="#+id/top_layout"
android:layout_width="match_parent"
android:layout_height="40dp" >
<ImageView
android:id="#+id/menu_btn"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dp"
android:src="#drawable/ic_drawer" />
<ImageView
android:id="#+id/add_btn"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:src="#android:drawable/ic_dialog_info"/>
</RelativeLayout>
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/top_layout" />
</RelativeLayout>
<!-- The navigation drawer -->
<LinearLayout
android:id="#+id/menu"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:background="#android:color/white"
android:orientation="vertical" >
<TextView
android:id="#+id/welcome_text"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginLeft="20dp"
android:gravity="center_vertical"
android:text="OPEN" />
<ListView
android:id="#+id/drawer_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="20dp"
android:choiceMode="singleChoice"
android:divider="#android:color/white"
android:dividerHeight="2dp"
android:listSelector="#android:color/white" />
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
And another important part Please change your application theme to noActionbar. Let me know if this satisfies your requirements.
Have you checked the Navigation Drawer documentation already? You have to provide a layout for the navigation drawer anyways, so it's always custom and up to you how it looks like.
I am trying to set up a listview for some actions that is displayed on a Navigation Drawer that opens from the right. The project will compile with no errors and I tried out my BaseAdapter on a ListView that is already in view and that works fine. There is no action bar in my app so the user has to open the drawer by sliding from the right edge of the screen. All the info to be displayed in the listview is handled in the adapter.
Here is what is in onCreate that is related to the drawer (On the official tutorial it seemed the only reason they would reference the actual DrawerLayout is to give it a toggle on the action bar, which I don't have):
I am now getting a null pointer exception when I try to assign the adapter.
ListView drawerList = (ListView) findViewById(R.id.drawerList); returns null
UPDATED CODE
ListView drawerList = (ListView) findViewById(R.id.drawerList);
SectionedAdapter DrawerAdapter = new SectionedAdapter(this);
drawerList.setAdapter(DrawerAdapter);
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/left_drawer">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/drawer_frame">
<AllOfMyStuff/>
<FrameLayout/>
<!--Always returns null-->
<ListView android:id="#+id/drawerList"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="right"
android:background="#ff1f1f1f"
android:drawSelectorOnTop="true"/>
</android.support.v4.widget.DrawerLayout>
Your xml seems to be fine but y r u inflating the menu_drawer.xml in fragment and not on an Activity ..Check out this video for better idea :: https://www.youtube.com/watch?v=K8hSIP2ha-g
this is my code..
activity_main.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/drawerlayout">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/maincontent"></FrameLayout>
<ListView
android:background="#FFFFFF"
android:divider="#null"
android:layout_width="240dp"
android:layout_height="match_parent"
android:id="#+id/drawerlist"
android:layout_gravity="left">
</ListView>
</android.support.v4.widget.DrawerLayout>
MainActivity.java
package com.example.nav;
import android.app.ActionBar;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainActivity extends Activity {
DrawerLayout mdrawer;
private ListView list;
private String[] planets;
ActionBar action;
ActionBarDrawerToggle mtoggle;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list=(ListView)findViewById(R.id.drawerlist);
mdrawer=(DrawerLayout)findViewById(R.id.drawerlayout);
action=getActionBar();
mtoggle=new ActionBarDrawerToggle(this, mdrawer, R.drawable.ic_drawer,R.string.OndrawerOpen,R.string.OndrawerClose){
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
}
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
};
mdrawer.setDrawerListener(mtoggle);
getActionBar().setHomeButtonEnabled(true);
getActionBar().setDisplayHomeAsUpEnabled(true);
planets=getResources().getStringArray(R.array.planets);
list.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,planets));
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,long arg3) {
setTitle(planets[position]);
}
});
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(mtoggle.onOptionsItemSelected(item)){
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mtoggle.syncState();
}
void setTitle(String value){
getActionBar().setTitle(value);
}
}
This might help!!
I have a solution for your problem:
1/ It should set a
android:theme="#style/AppThemeNoBar"
style in your manifest.
Add style
<style name="AppThemeNoBar" parent="Theme.AppCompat.Light">
<item name="android:windowNoTitle">true</item>
</style>
2/ menu_drawer :
<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 -->
<RelativeLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</RelativeLayout>
<!-- 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>
3/ MainActivity:
DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(
this, mDrawerLayout, R.drawable.menu_icon, R.string.drawer_open,
R.string.drawer_close
) {
#Override
public void onDrawerClosed(View view) {
invalidateOptionsMenu();
}
#Override
public void onDrawerOpened(View drawerView) {
invalidateOptionsMenu();
}
};
As a result you get a swipe-menu without ActionBar.
Maybe you made a mistake in view id name:
findViewById(R.id.drawList);
it should be R.id.drawerList instead of R.id.drawList.
P.S. I don't have enough rating to comment on answer.
I'm trying to let my HomeActivity extend BaseActivity (as suggested here) so I can have the same Navigation Drawer in every Activity I want. But I get a NullPointerException in the onCreate method of my HomeActivity. This is the code of BaseActivity:
import android.os.Bundle;
import android.app.Activity;
import android.content.res.Configuration;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class BaseActivity extends Activity
{
public DrawerLayout drawerLayout;
public ListView drawerList;
private String[] drawerListEntries;
private ActionBarDrawerToggle drawerToggle;
#Override
protected void onCreate(Bundle savedInstanceState)
{
drawerListEntries = new String[] {"Bla bla", "Profile", "Home"};
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerToggle = new ActionBarDrawerToggle((Activity) this, drawerLayout, R.drawable.ic_navigation_drawer, 0, 0)
{
public void onDrawerClosed(View view)
{
getActionBar().setTitle(R.string.app_name);
}
public void onDrawerOpened(View drawerView)
{
getActionBar().setTitle(R.string.hello_world);
}
};
drawerLayout.setDrawerListener(drawerToggle);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
//layers = getResources().getStringArray(R.array.layers_array);
drawerList = (ListView) findViewById(R.id.drawer_list);
// View header = getLayoutInflater().inflate(R.layout.drawer_list_header, null);
// drawerList.addHeaderView(header, null, false);
drawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, drawerListEntries));
// View footerView = ((LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
// R.layout.drawer_list_footer, null, false);
// drawerList.addFooterView(footerView);
drawerList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
//map.drawerClickEvent(pos);
String selectedValue = (String) drawerList.getAdapter().getItem(pos);
Toast.makeText(getBaseContext(), selectedValue, Toast.LENGTH_SHORT).show();
}
});
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (drawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
drawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
drawerToggle.onConfigurationChanged(newConfig);
}
}
And this is the code of HomeActivity which extends BaseActivity:
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.facebook.Session;
public class HomeActivity extends BaseActivity {
TextView greeting;
Button orderButton, deliverButton, logout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.home, menu);
//return super.onCreateOptionsMenu(menu);
return true;
}
}
I get a NullPointerException in:
super.onCreate(savedInstanceState); // HomeActivity
and when I click on that, it goes to:
drawerLayout.setDrawerListener(drawerToggle); // BaseActivity
Does anyone know how I can fix this?
Update:
drawer_list.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" >
<ListView
android:id="#+id/drawer_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginBottom="10dp"
android:layout_marginTop="5dp"
android:background="#android:color/transparent"
android:cacheColorHint="#android:color/transparent"
android:divider="#CCCCCC"
android:dividerHeight="1dp"
android:paddingLeft="2dp" />
</android.support.v4.widget.DrawerLayout>
and drawer_list_item.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" >
<TextView
android:id="#+id/drawer_list_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginTop="12dp"
android:textSize="24sp"
android:layout_gravity="left"
android:textColor="#color/belize_hole"
android:fontFamily="sans-serif-light">
</TextView>
</LinearLayout>
Same issue in a few posts. I am new to android but solved it this way. Would love to hear if there is a better "right" way to do it. (yes, without fragments but I know I need to learn them eventually).
The problem appears that the base class is not aware of the layout. Not sure how or why it worked for others without having to do something like this.. but I am new to Android.
I was getting the same error and solved by passing my layout to the base via onCreate.
So in the base, I modified onCreate to be like this:
protected void onCreate(Bundle savedInstanceState, int resLayoutID)
{
super.onCreate(savedInstanceState);
setContentView(resLayoutID);
Then, from my new activity, I have this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState, R.layout.my_activity);
This code in my base now works instead of staying null:
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerList = (ListView) findViewById(R.id.left_drawer);
btw, this result was suggested to me by a friend and it worked for me.