Trouble with android navigation Drawer - android

I have created a simple navigation drawer using this tutorial , the items in the nav drawer link to their respective fragments, but once i click on an item in the nav drawer i want it to take me to ie a list view. As far i see its that it only links to a java class that extends Fragment, as soon as i mention extend ListFragment it freaks out.

This is the NavigationDrawer I use:
First of all I set a Click listener to the ListView inside the NavigationDrawer
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
DrawerItemClickListener its a custom class
private class DrawerItemClickListener implements
ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
This calls to selectItem(int position)
private void selectItem(int position) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
switch (position) {
case 0:
ft.replace(R.id.content_frame, new FirstFragment());
setTitle("First");
break;
case 1:
ft.replace(R.id.content_frame, new SecondFragment());
setTitle("Second");
break;
case 2:
ft.replace(R.id.content_frame, new ThirdFragment());
setTitle("Third");
break;
}
ft.commit();
mDrawerList.setItemChecked(position, true);
mDrawerLayout.closeDrawer(mRelativeLayout);
}
Here you can set any Fragment of any kind you want. With this you won't have any Fragment type mismatch.
Also you can follow an official NavigationDrawer example provided by Android developers.
http://developer.android.com/training/implementing-navigation/nav-drawer.html
Hope it helps.

Related

Call a fragment from Navigation drawer ClickListener

I have a navigation drawer in my MainActivity and I've set up the ClickListener:
mMenuList.setOnItemClickListener(new DrawerItemClickListener());
In the Main onCreate method, I start the fragment with a default view:
MyMapFragmentActivity fragMap = new MyMapFragmentActivity();
FragmentManager fragMgr = getFragmentManager();
fragMgr.beginTransaction().replace(R.id.content_frame, fragMap).commit();
That is fine, but when I click an item in the nav drawer, I need to be able to open the fragment again, but with some different options.
The question is, the ClickListener is its own class:
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
switch (position) {
case 0:
default:
break;
}
mDrawerLayout.closeDrawer(mMenuList);
}
}
How do I get access to the MyMapFragmentActivity object within this DrawerItemClickListener class so that I can call it with different params ? Or is that not the way it should be done ?

How to attach an onclick listener to Android Studio's navigation drawer activity?

I am attempted to create an application in Android studio that has a navigation drawer.
I am using Android Studio (beta)0.8.14. In this version, there is a navigation drawer activity. I been able to set the labels for my navigation drawer menu using this piece of code and the corresponding values in my strings file
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.login);
break;
case 2:
mTitle = getString(R.string.sign_up);
break;
case 3:
mTitle = getString(R.string.view_map);
break;
case 4:
mTitle = getString(R.string.about);
break;
case 5:
mTitle = getString(R.string.version);
}
}
It looks really nice, but I can't figure out how to add onClickListeners for each of the items.
I've also added this in my NavigationDrawerFragment.java (which was automatically created by Android Studio):
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mDrawerListView = (ListView) inflater.inflate(
R.layout.fragment_navigation_drawer, container, false);
mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
});
mDrawerListView.setAdapter(new ArrayAdapter<String>(
getActionBar().getThemedContext(),
android.R.layout.simple_list_item_activated_1,
android.R.id.text1,
new String[]{
getString(R.string.login),
getString(R.string.sign_up),
getString(R.string.view_map),
getString(R.string.about),
getString(R.string.version),
}));
mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
return mDrawerListView;
}
I would like to launch a different activity for each of the list items but I can't understand how and unfortunately I can't seem to find a tutorial that uses Android Studio's built-in navigation drawer activity.
Also, is it possible to have this navigation drawer available on all of my activities? Do I need to create a new navigation drawer fragment every time I create a new activity?
Thanks in advance!
The idea of having a navigation drawer is to use fragment. It wouldn't be very efficient to launch a new activity whenever you click an item in your navigation drawer.
In your selectItem(position) method you could execute some code for creating a new fragment for list item in your navigation drawer. Each navigation item should be a different fragment then just use a fragment transaction to add it to the container view of the main activity.
As a simple example of what the method may look like:
private void selectItem(int position) {
FragmentManager fragmentManager = getFragmentManager();
switch(position) {
//fragment for position 0
case 0:
fragmentManager.beginTransaction()
.replace(R.id.container, new Fragment0())
.commit();
break;
//fragment for postion 1
case 1:
fragmentManager.beginTransaction()
.replace(R.id.container, new Fragment1())
.commit();
break;
//fragment for position 2
case 2:
fragmentManager.beginTransaction()
.replace(R.id.container, new Fragment2())
.commit();
break;
default:
break;
}
}
This may not be exactly what you want but it is an option for what you're trying to accomplish.
As a note in order for onSectionAttached() to work, all your framents will have to call that to pass their title to the main activity.
See this link for more info.
In order to put onclicklisteners on your navigation drawer, just put an intent below the line of code where you are changing the title bar i.e. in the switch case block
e.g.
case 1:
mTitle = getString(R.string.login);
Intent transfer = new Intent(HomeFragment.this,NextActivity.class);
startActivity(transfer);
This will do it for you.

Navigation Drawer generated by Eclipse, and Fragment instantiation in a smarter way?

In order to create a Navigation Drawer, and because it seemed confusing, I used Eclipse's automatically created template. However, this template creates code so that it displays the content of a String array adapter, and at the selection of an item a Fragment is instantiated in the attached Activity like this:
#Override
public void onNavigationDrawerItemSelected(int position)
{
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragment = null;
switch (position)
{
case 0:
fragment = new FragmentType0();
break;
case 1:
fragment = new FragmentType1();
break;
case 2:
fragment = new FragmentType2();
break;
default:
Log.w(this.getClass().getSimpleName(), "Reached Default in onNavigationDrawerItemSelected!");
break;
}
if (fragment != null)
{
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.container, fragment);
ft.addToBackStack(null);
ft.commit();
mTitle = getString(((GetActionBarTitle) fragment).getActionBarTitleId());
restoreActionBar();
}
}
Because the generated template is the following:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
mDrawerListView = (ListView) inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
selectItem(position);
}
});
String[] drawerTitles = new String[] { getString(R.string.drawer_string_0), getString(R.string.drawer_string_1), getString(R.string.drawer_string_2)};
mDrawerListView.setAdapter(new ArrayAdapter<String> (getActionBar().getThemedContext(), android.R.layout.simple_list_item_1,
android.R.id.text1, drawerTitles));
mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
return mDrawerListView;
}
So as you can see, the titles are given in the navigation drawer, displayed and specified as a String, and when you select an item, the callback is called on the Activity, at which based on position of selected item, the 'proper' Fragment is instantiated based on an if-else structure. This seems like a fairly fragile solution, but I can't seem to figure out how to make it better.
My hunch is something like using a FragmentStatePagerAdapter, but I'm at a loss, as I've never used one before, especially not in this particular context (I'm REALLY new to the navigation drawer, and I don't know how I would integrate it with the navigation drawer, so that it displays strings that correspond to each Fragment). Can anyone please provide advice on what to do here? It works, but it doesn't seem like the "proper" solution.
I'd reccomend that you stay away from the auto-generated code. A lot of the time, it isn't at all what you want.
I recommend you take a look at this tutorial. It explains the basics of the navigation drawer pretty well.

get selected item - ListView Android

I know this has been asked here but the answers were quite confusing. I have 3 items in my ListView. They are "Aluminium", "Gold" and "Zinc". Through each one of them, I want to start different activities and for that I have created the 3 activities which i named "Aluminium.java","Gold.java" and "Zinc.java"
I have used this ListView in a drawer layout for the navigation drawer. I implemented navigation drawers through the code given below which i got from a site.This code changes fragments and its not working properly. Instead of fragments, I want to switch activities.
I want to achieve 3 things:
Switch between activities through the listview in the navigation drawer.
To achieve point 1, I want to get the clicked list item and then use intents.
I want all the 3 activities to have this navigation drawer.
Sorry if its too dumb but I am a beginner. Please help me out with the code.
Java code
public class MainActivity extends FragmentActivity {
final String[] data ={"Aluminium","Gold","Zinc"};
final String[] fragments ={
"com.Chinmay.navigationdrawer.Gold",
"com.Chinmay.navigationdrawer.Aluminium",
"com.Chinmay.navigationdrawer.Zinc"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, data);
final DrawerLayout drawer = (DrawerLayout)findViewById(R.id.drawer_layout);
final ListView navList = (ListView) findViewById(R.id.left_drawer);
navList.setAdapter(adapter);
navList.setOnItemClickListener(new AdapterView.OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, final int pos,long id){
drawer.setDrawerListener( new DrawerLayout.SimpleDrawerListener(){
#Override
public void onDrawerClosed(View drawerView){
super.onDrawerClosed(drawerView);
android.support.v4.app.FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
tx.replace(R.id.content_frame, Fragment.instantiate(MainActivity.this, fragments[pos]));
tx.commit();
}
});
drawer.closeDrawer(navList);
android.support.v4.app.FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
tx.replace(R.id.content_frame,Fragment.instantiate(MainActivity.this, fragments[0]));
tx.commit();
}
});
}
}
Make a base activity class and put all your drawer code there, and extend this base class for your 3 activity, in that way, you'll have drawer for your all activities.
class Gold extends BaseActivity{
}
For the clicking part, you already set an item click listener, just make a switch case such as
switch (pos){
case 0:
Intent i = new Intent(this,Gold.java);
startActivity(i);
break;
}
// fill the rest
}

Switch between tab navigation and list navigation

I am using ActionBarSherlock and applying this pattern for the tab navigation that I found on android developer site. It's working pretty good but I also want to able to switch between NAVIGATION_MODE_TABS and NAVIGATION_MODE_LIST preserving the association between tabs and the fragments.
The pattern I mentioned above is pretty good for preserving a generic code. So I add listeners to my tabs and associate them with specific fragments like this:
bar.addTab(bar.newTab()
.setText("MyFragment")
.setTabListener(new TabListener<SomeFragment>(this, "myfargment", SomeFragment.class)));
and instantiate the fragment when the associated tab is clicked with the help of generics:
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName(), mArgs);
ft.add(android.R.id.content, mFragment, mTag);
} else {
ft.attach(mFragment);
}
}
My question is how can I achieve a similar way while navigating between my fragments with the list navigation mode. I couldn't find a similar way since the OnNavigationListener for the list on the ActionBar works for the whole list instead of per item basis like the tablistener.
or do I have to do something like this:
#Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
switch (itemPosition) {
case 0:
//Replace the current fragment with FragmentA
break;
case 1:
//Replace the current fragment with FragmentB
break;
case 2:
//Replace the current fragment with FragmentC
break;
default:
break;
}
return true;
}
EDIT:
I have noticed an interesting behaviour:
While the navigation mode is set to NAVIGATION_MODE_TABS if I put my phone in landscape mode it converts the tabs to a list and preservers the association between the fragments and the list items(which were tab items before) how can I achieve this result on demand rather than on orientation change?
I dont think its possible if you are in tab mode to manually set to a list navigation. I have the list navigation set for one of my applications when it falls below the "Large" bucket. This is how I am using the navigation listener:
OnNavigationListener mNavigationListener = new OnNavigationListener()
{
int mLastPosition = -1;
#Override
public boolean onNavigationItemSelected(int itemPosition, long itemId)
{
String selectedTag = mFragmentNames.get(itemPosition);
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = fm.findFragmentByTag(selectedTag);
FragmentTransaction ft = fm.beginTransaction();
/** Used to avoid the same fragment being reattached. */
if(mLastPosition != itemPosition)
{
/** Means there was a previous fragment attached. */
if(mLastPosition != -1)
{
Fragment lastFragment = fm.findFragmentByTag(mFragmentNames.get(mLastPosition));
if(lastFragment != null)
ft.remove(lastFragment);
}
if(fragment == null)
{
/** The fragment is being added for the first time. */
fragment = Fragment.instantiate(HomeActivity.this, selectedTag);
ft.add(R.id.rootLayout, fragment, selectedTag);
ft.commit();
} else
{
ft.attach(fragment);
ft.commit();
}
}
/**
* The newly attached fragment will be the last position if changed.
*/
mLastPosition = itemPosition;
return true;
}
};
The variable mFragmentNames is a HashMap that maps a integer position to a fragment name ex. "com.android.myproject.MyFragment"
I hope this helps.

Categories

Resources