I'm trying to implement Material Navigation Bar. I followed someone's tutorial for it. But I'm facing a little problem. Android Studio resolves everything except for drawer_open and drawer_close parameters for the constructor of ActionBarDrawerToggle e.g.
mDrawerToggle = new ActionBarDrawerToggle(this,Drawer,R.string.drawer_open,R.string.drawer_close)
Here it fails to resolve drawer_open and drawer_close. Google's Navigation Drawer sample works perfectly fine. I have imported all necessary packages. I can't figure out what's going wrong since I've just started learning android.
Full code of MainActivitiy is:
package com.startup.demo;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class MainActivity extends ActionBarActivity {
//First We Declare Titles And Icons For Our Navigation Drawer List View
//This Icons And Titles Are holded in an Array as you can see
String TITLES[] = {"Home","Events","Mail","Shop","Travel"};
//int ICONS[] = {R.drawable.ic_home,R.drawable.ic_events,R.drawable.ic_mail,R.drawable.ic_shop,R.drawable.ic_travel};
//Similarly we Create a String Resource for the name and email in the header view
//And we also create a int resource for profile picture in the header view
String NAME = "Akash Bangad";
String EMAIL = "akash.bangad#android4devs.com";
//int PROFILE = R.drawable.aka;
private Toolbar toolbar; // Declaring the Toolbar Object
RecyclerView mRecyclerView; // Declaring RecyclerView
RecyclerView.Adapter mAdapter; // Declaring Adapter For Recycler View
RecyclerView.LayoutManager mLayoutManager; // Declaring Layout Manager as a linear layout manager
DrawerLayout Drawer; // Declaring DrawerLayout
ActionBarDrawerToggle mDrawerToggle; // Declaring Action Bar Drawer Toggle
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* Assinging the toolbar object ot the view
and setting the the Action bar to our toolbar
*/
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
mRecyclerView = (RecyclerView) findViewById(R.id.RecyclerView); // Assigning the RecyclerView Object to the xml View
mRecyclerView.setHasFixedSize(true); // Letting the system know that the list objects are of fixed size
mAdapter = new MyAdapter(TITLES,NAME,EMAIL); // 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,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
}
#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;
}
return super.onOptionsItemSelected(item);
}
}
Place the following string in strings.xml
drawer_open = "xxx"
drawer_close = "xxx"
Related
I am new to Android Studio and I was working on v3.1.4. When I was dragging any of the widgets and put it in the design, it does not appear. It gives me an error message that the widget is not constrained and it will jump to (0,0) point unless you add a constraint to it. When I use the magic wand the error disappeared but the problem still exist and the widget does not appear.
The code:
package com.example.amr.myapplication;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
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();
}
});
}
#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;
}
return super.onOptionsItemSelected(item);
}
}
Solution:
Step1: Open SDK Manager then install the latest SDK from that.
Step2: Shift to SDK Tools section in SDK Manager then install everything except NDK.
Step3: Restart Android Studio.
Finally, Problem Solved. (See the image below for reference)
Hopefully it will work.
You have the Attributes panel collapsed on the left, inside that can put costraints on the current selected widget.
You'll see a square with four plus signs around to add costraints.
When I debug/ test my app from Android Studio on my phone. I don't see it in my launcher or can't even find the app by searching. It's something to do with Android Manifest right? And I don't think I made it 'launcher activity'. Would you please be able to help me? Thanks!
EDIT:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gursimran.bedi.eta" >
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity.java
package com.gursimran.bedi.eta;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class MainActivity extends AppCompatActivity {
String TITLES[] = {"Home","Events","Mail","Shop","Travel"};
int ICONS[] = {R.drawable.ic_alarm_add_black_48dp, R.drawable.ic_check_circle_black_48dp,
R.drawable.ic_delete_black_48dp, R.drawable.ic_dns_black_48dp,R.drawable.ic_favorite_border_black_48dp};
private Toolbar toolbar;
RecyclerView mRecyclerView; // Declaring RecyclerView
RecyclerView.Adapter mAdapter; // Declaring Adapter For Recycler View
RecyclerView.LayoutManager mLayoutManager; // Declaring Layout Manager as a linear layout manager
DrawerLayout Drawer; // Declaring DrawerLayout
ActionBarDrawerToggle mDrawerToggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
getSupportActionBar().setDefaultDisplayHomeAsUpEnabled(true);
NavigationDrawerFragment drawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
drawerFragment.setUp(R.id.fragment_navigation_drawer, (DrawerLayout)findViewById(R.id.DrawerLayout), toolbar);
mRecyclerView = (RecyclerView) findViewById(R.id.RecyclerView); // Assigning the RecyclerView Object to the xml View
mRecyclerView.setHasFixedSize(true); // Letting the system know that the list objects are of fixed size
// mAdapter = new MyAdapter(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_closed){
#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
}
#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;
}
return super.onOptionsItemSelected(item);
}
}
#Gursimram Bedi :
For your kind information .Try this way
Clean and Rebuild your Project Then Restart your Project Too.
Actually your manifest is perfect.
Let me inform me .I hope it will helps you.
This is the beahviour of my App (only 1 is right, of course):
Of course I want only one item at the moment checked.
I divided the items in two groups (to add the divider, see my previous question: How add horizontal separator in navdrawer? )
This is the nav_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single"
android:id="#+id/group1" >
<item
android:id="#+id/home"
android:checked="false"
android:icon="#drawable/ic_home_black_24dp"
android:title="#string/list_home" />
<item
android:id="#+id/list_event"
android:checked="false"
android:icon="#drawable/ic_list_black_24dp"
android:title="#string/list_event" />
</group>
<group
android:checkableBehavior="single"
android:id="#+id/group2" >
<item
android:id="#+id/settings"
android:checked="false"
android:icon="#drawable/ic_settings_black_24dp"
android:title="#string/settings" />
</group>
</menu>
This is the BaseApp that manage the NavDrawer:
package com.xx.views;
import android.support.design.widget.NavigationView;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.support.v7.app.ActionBarDrawerToggle;
import android.os.Bundle;
import android.view.View;
import com.xx.R;
import com.xx.mappers.DateManager;
public class BaseApp extends AppCompatActivity {
//Defining Variables
protected String LOGTAG = "LOGDEBUG";
protected Toolbar toolbar;
protected NavigationView navigationView;
protected DrawerLayout drawerLayout;
private DateManager db = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.base_layout);
navigationView = (NavigationView) findViewById(R.id.navigation_view);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame, new DashboardFragment());
fragmentTransaction.commit();
setNavDrawer();
// make home as checked
navigationView.getMenu().getItem(0).setChecked(true);
}
private void setNavDrawer(){
// Initializing Toolbar and setting it as the actionbar
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Initializing NavigationView
//Setting Navigation View Item Selected Listener to handle the item click of the navigation menu
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()) {
case R.id.home:
DashboardFragment dashboardFragment = new DashboardFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame, dashboardFragment,"DASHBOARD_FRAGMENT");
fragmentTransaction.commit();
return true;
case R.id.list_event:
ListEventFragment fragmentListEvent = new ListEventFragment();
fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame, fragmentListEvent);
fragmentTransaction.commit();
return true;
case R.id.settings:
SettingsFragment fragmentSettings = new SettingsFragment();
fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame, fragmentSettings);
fragmentTransaction.commit();
return true;
default:
return true;
}
}
});
// Initializing Drawer Layout and ActionBarToggle
drawerLayout = (DrawerLayout) findViewById(R.id.drawer);
ActionBarDrawerToggle actionBarDrawerToggle =
new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.open_drawer, R.string.close_drawer){
#Override
public void onDrawerClosed(View drawerView) {
// Code here will be triggered once the drawer closes as we dont want anything
// to happen so we leave this blank
super.onDrawerClosed(drawerView);
}
#Override
public void onDrawerOpened(View drawerView) {
// Code here will be triggered once the drawer open as we dont want anything
// to happen so we leave this blank
super.onDrawerOpened(drawerView);
}
};
//Setting the actionbarToggle to drawer layout
drawerLayout.setDrawerListener(actionBarDrawerToggle);
//calling sync state is necessay or else your hamburger icon wont show up
actionBarDrawerToggle.syncState();
}
private void eraseTable(){
db=new DateManager(this);
db.resetTable();
}
#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;
}
return super.onOptionsItemSelected(item);
}
}
Thank you very much
This could help you: Try to removing the tag android:checkableBehavior="single" from xml and set android:checkable = “true” for each item individually, then declare a MenuItem object in the activity and in onNavigationItemSelected event if previously declared MenuItem object is not null then set checked value as false for it and then save current selected menuItem received as parameter to earlier declared MenuItem object.
This will set checked selection on even subitems.
if (prevMenuItem != null) {
prevMenuItem.setChecked(false);
}
menuItem.setChecked(true);
mDrawerLayout.closeDrawers();
prevMenuItem = menuItem;
return true;
I found this solutions here
If you are using groups and android:checkableBehavior="single", then all you need to do is set the single item as the checked item in the navigation view (not simply the item as checked with item.setChecked(true)):
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
//item.setChecked(true); //Won't work, will leave previous item checked too.
navigationView.setCheckedItem(id); //this will check single item
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
Now, whether you select or emulate select for an item, it will check only one item at a time.
Put both group inside single group an set
android:checkableBehavior="single"
Create a parent group
You would have to implement a custom adapter, custom/model, custom function to uncheck other items on click.
I suggest you to use this library. Its a material navigation drawer implementation, it already has all this logic implemented. If you dont want to go with a lib, them you should check how its done on this library code and adapt to your needs.
I am trying to implement DrawerLayout. The drawer layout is working fine. But the icon displayed in Top Left corner is android.R.id.home. However I have mentioned my custom icon in ActionBarDrawerToggle as follows:
// Getting reference to the DrawerLayout
drawerLayout = (android.support.v4.widget.DrawerLayout) findViewById(R.id.drawer_layout);
drawerList = (ListView) findViewById(R.id.drawer_list);
// Getting reference to the ActionBarDrawerToggle
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout,
**R.drawable.icon_top_menu**, R.string.drawer_open,
R.string.drawer_close) {
/** Called when drawer is closed */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
}
/** Called when a drawer is opened */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
};
// Setting DrawerToggle on DrawerLayout
drawerLayout.setDrawerListener(drawerToggle);
getActionBar().setIcon(R.drawable.icon_top_menu);
// enabling action bar app icon and behaving it as toggle button
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
What's the problem?
You should check your onoptionsItem selected, should missing there...............
as shown below:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
in place of '.action_settings' try 'icon_top_menu' your icon.......
you should use visibility true/false for the icon menu in each activity where you want to show your icon...and please describe your question properly what you want to do.
To
user1182217
okay i got your problem some what, hope this will help you.
as for icon id you are using "android.R.id.home" which is 'android id' by default,
in place of that use your icon id as R.id.home/ R.id.your_icon_id hope the only error as
per your problem description..........
i have get the sample navigation drawer from this site :
http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer/
and the master detail from here :
http://wptrafficanalyzer.in/blog/itemclick-handler-for-listfragment-in-android/
the error LogCat oncreateview(inflac....) the view
can not be created
me i have try that
//the main activiry as Activity:
package in.wptrafficanalyzer.listfragmentitemclick;
import in.wptrafficanalyzer.listfragmentitemclick.adapter.NavDrawerListAdapter;
import in.wptrafficanalyzer.listfragmentitemclick.model.NavDrawerItem;
import java.util.ArrayList;
import in.wptrafficanalyzer.listfragmentitemclick.R;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.app.ListFragment;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.os.Bundle;
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.AdapterView;
import android.widget.ListView;
public class MainActivity extends Activity implements CountryListFragment.ListFragmentItemClickListener {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
// nav drawer title
private CharSequence mDrawerTitle;
// used to store app title
private CharSequence mTitle;
// slide menu items
private String[] navMenuTitles;
private TypedArray navMenuIcons;
private ArrayList<NavDrawerItem> navDrawerItems;
private NavDrawerListAdapter adapter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTitle = mDrawerTitle = getTitle();
// load slide menu items
navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
// nav drawer icons from resources
navMenuIcons = getResources()
.obtainTypedArray(R.array.nav_drawer_icons);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.list_slidermenu);
navDrawerItems = new ArrayList<NavDrawerItem>();
// adding nav drawer items to array
// Home
navDrawerItems.add(new NavDrawerItem(navMenuTitles[0], navMenuIcons.getResourceId(0, -1)));
// Find People
navDrawerItems.add(new NavDrawerItem(navMenuTitles[1], navMenuIcons.getResourceId(1, -1)));
// Photos
navDrawerItems.add(new NavDrawerItem(navMenuTitles[2], navMenuIcons.getResourceId(2, -1)));
// Communities, Will add a counter here
navDrawerItems.add(new NavDrawerItem(navMenuTitles[3], navMenuIcons.getResourceId(3, -1), true, "22"));
// Pages
navDrawerItems.add(new NavDrawerItem(navMenuTitles[4], navMenuIcons.getResourceId(4, -1)));
// What's hot, We will add a counter here
navDrawerItems.add(new NavDrawerItem(navMenuTitles[5], navMenuIcons.getResourceId(5, -1), true, "50+"));
// Recycle the typed array
navMenuIcons.recycle();
mDrawerList.setOnItemClickListener(new SlideMenuClickListener());
// setting the nav drawer list adapter
adapter = new NavDrawerListAdapter(getApplicationContext(),
navDrawerItems);
mDrawerList.setAdapter(adapter);
// enabling action bar app icon and behaving it as toggle button
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_drawer, //nav menu toggle icon
R.string.app_name, // nav drawer open - description for accessibility
R.string.app_name // nav drawer close - description for accessibility
) {
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
// calling onPrepareOptionsMenu() to show action bar icons
invalidateOptionsMenu();
}
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
// calling onPrepareOptionsMenu() to hide action bar icons
invalidateOptionsMenu();
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
if (savedInstanceState == null) {
// on first time display view for first nav item
displayView(0);
}
}
/**
* Slide menu item click listener
* */
private class SlideMenuClickListener implements
ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// display view for selected nav drawer item
displayView(position);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// toggle nav drawer on selecting action bar app icon/title
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle action bar actions click
switch (item.getItemId()) {
case R.id.action_settings:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/***
* Called when invalidateOptionsMenu() is triggered
*/
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// if nav drawer is opened, hide the action items
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
/**
* Diplaying fragment view for selected nav drawer list item
* */
private void displayView(int position) {
// update the main content by replacing fragments
ListFragment fragment = null;
switch (position) {
case 0:
//fragment = new HomeFragment();
break;
case 1:
fragment = new CountryListFragment();
break;
case 2:
//fragment = new PhotosFragment();
break;
case 3:
// fragment = new CommunityFragment();
break;
case 4:
//fragment = new PagesFragment();
break;
case 5:
//fragment = new WhatsHotFragment();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.country_list_fragment, fragment).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
#Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
/**
* When using the ActionBarDrawerToggle, you must call it during
* onPostCreate() and onConfigurationChanged()...
*/
#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);
// Pass any configuration change to the drawer toggls
mDrawerToggle.onConfigurationChanged(newConfig);
}
/** Called when the activity is first created. */
#Override
public void onListFragmentItemClick(int position) {
/** Getting the orientation ( Landscape or Portrait ) of the screen */
int orientation = getResources().getConfiguration().orientation;
/** Landscape Mode */
if(orientation == Configuration.ORIENTATION_LANDSCAPE ){
/** Getting the fragment manager for fragment related operations */
FragmentManager fragmentManager = getFragmentManager();
/** Getting the fragmenttransaction object, which can be used to add, remove or replace a fragment */
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
/** Getting the existing detailed fragment object, if it already exists.
* The fragment object is retrieved by its tag name
* */
Fragment prevFrag = fragmentManager.findFragmentByTag("in.wptrafficanalyzer.country.details");
/** Remove the existing detailed fragment object if it exists */
if(prevFrag!=null)
fragmentTransaction.remove(prevFrag);
/** Instantiating the fragment CountryDetailsFragment */
CountryDetailsFragment fragment = new CountryDetailsFragment();
/** Creating a bundle object to pass the data(the clicked item's position) from the activity to the fragment */
Bundle b = new Bundle();
/** Setting the data to the bundle object */
b.putInt("position", position);
/** Setting the bundle object to the fragment */
fragment.setArguments(b);
/** Adding the fragment to the fragment transaction */
fragmentTransaction.add(R.id.detail_fragment_container, fragment,"in.wptrafficanalyzer.country.details");
/** Adding this transaction to backstack */
fragmentTransaction.addToBackStack(null);
/** Making this transaction in effect */
fragmentTransaction.commit();
}else{ /** Portrait Mode or Square mode */
/** Creating an intent object to start the CountryDetailsActivity */
Intent intent = new Intent("in.wptrafficanalyzer.CountryDetailsActivity");
/** Setting data ( the clicked item's position ) to this intent */
intent.putExtra("position", position);
/** Starting the activity by passing the implicit intent */
startActivity(intent);
}
}
}
the CountryListFragment as listfragment :
package in.wptrafficanalyzer.listfragmentitemclick;
import android.app.Activity;
import android.app.ListFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class CountryListFragment extends ListFragment{
/** List of countries to be displayed in the ListFragment */
ListFragmentItemClickListener ifaceItemClickListener;
/** An interface for defining the callback method */
public interface ListFragmentItemClickListener {
/** This method will be invoked when an item in the ListFragment is clicked */
void onListFragmentItemClick(int position);
}
/** A callback function, executed when this fragment is attached to an activity */
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try{
/** This statement ensures that the hosting activity implements ListFragmentItemClickListener */
ifaceItemClickListener = (ListFragmentItemClickListener) activity;
}catch(Exception e){
Toast.makeText(activity.getBaseContext(), "Exception",Toast.LENGTH_SHORT).show();
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/** Data source for the ListFragment */
ArrayAdapter<String> adapter = new ArrayAdapter<String>(inflater.getContext(), android.R.layout.simple_list_item_1, Country.name);
/** Setting the data source to the ListFragment */
setListAdapter(adapter);
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
/** Invokes the implementation of the method istFragmentItemClick in the hosting activity */
ifaceItemClickListener.onListFragmentItemClick(position);
}
}
layout main in folder layout
><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/country_list_fragment"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:name="in.wptrafficanalyzer.listfragmentitemclick.CountryListFragment"
/>
<!-- Listview to display slider menu -->
<ListView
android:id="#+id/list_slidermenu"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#color/list_divider"
android:dividerHeight="1dp"
android:listSelector="#drawable/list_selector"
android:background="#color/list_background"/>
> </android.support.v4.widget.DrawerLayout>
layout main in the folder layout-land
><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/country_list_fragment"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:name="in.wptrafficanalyzer.listfragmentitemclick.CountryListFragment"
/>
<FrameLayout
android:id="#+id/detail_fragment_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center"
/>
<!-- Listview to display slider menu -->
<ListView
android:id="#+id/list_slidermenu"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#color/list_divider"
android:dividerHeight="1dp"
android:listSelector="#drawable/list_selector"
android:background="#color/list_background"/>
></android.support.v4.widget.DrawerLayout>
I was confused by this, too. I set up the Navigation Drawer to navigate between major sections of my app. Then I wanted one of those major sections to be set up as Master/Detail. I knew it was possible, since this is basically what Gmail is, but was having a hard time putting what I had already built together with what Eclipse spits out when generating a Master/Detail Activity.
I couldn't just launch the ItemListFragment (Master/Detail) from the MainActivity (Navigation Drawer), because ItemListFragment wants to attach to ItemListActivity, not MainActivity, and a fragment can't have two Activities.
I finally found a tutorial on it that actually used the two design ideas together:
http://blog.evizija.si/android-layout/
I just followed their example and got my UI working as desired in about 5 minutes. It's actually incredibly simple. You make MasterActivity look a bit more like the generated ItemListActivity (ie. implement TaskListFragment.Callbacks, copy over the onItemSelected method, and a chuck of onCreate) and you're done!
I hope this helps solve your problem! Happy coding!
UPDATE: Elaborating on the steps involved (info from link), based on feedback in comments on improving my answer.
(1) Make your drawer activity and fragments, lets call them MainActivity and some fragments we don't care about here. Personally, I would create an empty Fragment, like ItemFragement for example, to be a place holder for the Master/Detail while I get the Drawer up and running. Then once the Drawer is working as desired, tackle the Master/Detail and linking them.
(2) Use the IDE wizard (I'm running Eclipse) to make the activities and fragments of master/detail flow. I'll refer to them by their default names: ItemListActivity, ItemListFragement, ItemDetailActivity, ItemDetailFragment.
(3) If you've used Master/Detail before, you know most of your logic goes into the fragment. This is still true when combining Master/Detail with Drawer. Note, at this point there is no connection between our MainActivity and our Master/Detail flow, and the later may not even be accessible in the UI.
(4) Key Concept: To connect the Drawer with the List, our MainActivity is going to be the hosting Activity for ItemListFragment (rather than the current ItemListActivity). To make this work, we just copy over some of the Master/Detail magic created by the wizard FROM ItemListActivity INTO MainActivity.
(5) Specifically:
(5A) MainActivity implements ItemListFragment.Callbacks (or EmployeeListFragment.Callbacks, AlbumListFragment.Callbacks, whatever you are listing) and implement onItemSelected method
public class MainActivity extends Activity
implements OnItemClickListener, ItemListFragment.Callbacks {
(5B) Copy part of code from onCreate in ItemListActivity and paste it to onCreate in MainActivity. This part:
if (findViewById(R.id.item_detail_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.
((ItemListFragment) getFragmentManager()
.findFragmentById(R.id.item_list))
.setActivateOnItemClick(true);
}
(5C) Also copy onItemSelected method from ItemListActivity and paste it into MainActivity. You will already have an onItemSelected method if you told Eclipse to "add unimplemented methods" in response to the error that would have been raised after Step 5A. If you don't, copy over the whole method. (this step edited in response to a question in comments) Code:
if (mTwoPane) {
// In two-pane mode, show the detail view in this activity by
// adding or replacing the detail fragment using a
// fragment transaction.
Bundle arguments = new Bundle();
arguments.putString(ItemDetailFragment.ARG_ITEM_ID, id);
ItemDetailFragment fragment = new ItemDetailFragment();
fragment.setArguments(arguments);
getFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, fragment)
.commit();
} else {
// In single-pane mode, simply start the detail activity
// for the selected item ID.
Intent detailIntent = new Intent(this, ItemDetailActivity.class);
detailIntent.putExtra(ItemDetailFragment.ARG_ITEM_ID, id);
startActivity(detailIntent);
}
(6) Then the last step is to have MainActivity (the Drawer) open ItemListFragment. If you already have a placeholder Fragment launching (like ItemFragement suggested in Step 1), this is just a matter of replacing ItemFragment with ItemListFragment in the onNavigationDrawerItemSelected method.
Hope that's clear. If not, the original link might do a better job explaining than I did. Just skim to the bottom where the blogger talks about adding the list activity to their drawer activity.
cheers.
UPDATE:
After being ask to do so by a moderator, I'm flagging this and another similar question (as duplicates).
Those questions:
https://stackoverflow.com/questions/25403377/combine-navigation-drawer-and-master-detail-layout
Navigation Drawer and master/detail flow