I have implemented actionbar and navigation drawer on all activity by extending base activity but when i use setcontent view in child activity navigation drawer doesn't works at how to solve this! Here is my code:
MainActivity which contains navigation drawer:
package first.service.precision.servicefirst;
import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
public class Main2Activity extends Activity {
public static ContactView contactView;
NewContacts newContacts;
public static LeadRequirementsView _LeadRequirements;
//public ContactView contactView;
protected DrawerLayout mDrawerLayout;
public static String mysting;
private ListView mDrawerList;
Button butonlead;
// ActionBarDrawerToggle indicates the presence of Navigation Drawer in the action bar
protected ActionBarDrawerToggle mDrawerToggle;
// Title of the action bar
private String mTitle = "";
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
final ActionBar ab = getActionBar();
ab.show();
// Getting reference to the DrawerLayout
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
ab.setTitle(mTitle);
mDrawerList = (ListView) findViewById(R.id.drawer_list);
// Getting reference to the ActionBarDrawerToggle
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.string.open_drawer,
R.string.close_drawer) {
/** Called when drawer is closed */
public void onDrawerClosed(View view) {
invalidateOptionsMenu();
}
/** Called when a drawer is opened */
public void onDrawerOpened(View drawerView) {
invalidateOptionsMenu();
}
};
// Setting DrawerToggle on DrawerLayout
mDrawerLayout.setDrawerListener(mDrawerToggle);
// Creating an ArrayAdapter to add items to the listview mDrawerList
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplication(),
R.layout.drawer_list_item, R.id.title, getResources().getStringArray(R.array.option));
// Setting the adapter on mDrawerList
mDrawerList.setAdapter(adapter);
// Enabling Home button
ab.setHomeButtonEnabled(true);
ab.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#53A93F")));
// Enabling Up navigation
ab.setIcon(R.drawable.sfwhite);
ab.show();
ab.setDisplayHomeAsUpEnabled(true);
// Setting item click listener for the listview mDrawerList
mDrawerList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// Getting an array of options
String[] menuItems = getResources().getStringArray(R.array.option);
// Currently selected option
mTitle = menuItems[position];
// Fragment fragment = null;
// String tag = "";
switch (position) {
case 0:
Intent lead=new Intent(getApplicationContext(),LeadActivity.class);
startActivity(lead);
break;
case 1:
Intent opportunities=new Intent(getApplicationContext(),OpportunitiesActivity .class);
startActivity(opportunities);
break;
case 2:
Intent Accounts=new Intent(getApplicationContext(),AccountsActivity.class);
startActivity(Accounts);
break;
case 3:
Intent Contacts=new Intent(getApplicationContext(),Contacts.class);
startActivity(Contacts);
break;
case 4:
Intent Competitors=new Intent(getApplicationContext(), Competitors.class);
startActivity(Competitors);
break;
case 5:
Intent Acivity=new Intent(getApplicationContext(), Activitites.class);
startActivity(Acivity);
break;
case 6:
Intent Reports=new Intent(getApplicationContext(),ReportActivity.class);
startActivity(Reports);
break;
default:
break;
}
}
});
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
#Override
public void onBackPressed() {
// int back=getFragmentManager().getBackStackEntryCount();
if (mDrawerLayout.isDrawerOpen(Gravity.LEFT)) {
mDrawerLayout.closeDrawer(mDrawerList);
}
else {
super.onBackPressed();
}
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Called whenever we call invalidateOptionsMenu()
*/
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// If the drawer is open, hide action items related to the content view
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
return super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main2, menu);
return super.onCreateOptionsMenu(menu);
}
/* #Override
public void data(String str, String sl) {
Accounts accounts=(Accounts)getFragmentManager().findFragmentByTag("accounts");
accounts.datarecieve(str,sl);
}*/
/*#Override
public void dataTo(ContactView contactView) {
Contactss contactss=(Contactss)getFragmentManager().findFragmentByTag("contact");
contactss.dataTo(contactView);
}*/
/* #Override
public void DataTransfer(String e) {
}*/
//
// #Override
// public void DataTransfer(ArrayList<String> e) {
// Add obj=(Add)getFragmentManager().findFragmentById(R.id.frag_1);
// obj.GetlistContact(e);
// }
}
/* #Override
public void selectedvalue(String s) {
Add add=new Add();
FragmentManager fm=getFragmentManager();
FragmentTransaction ft=fm.beginTransaction();
ft.replace(R.id.content_frame,add);
ft.commit();}
}
*/
Here is chlid activity which extends base activity
package first.service.precision.servicefirst;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import java.util.ArrayList;
public class LeadActivity extends Main2Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super. setContentView(R.layout.activity_lead);
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View contentView = inflater.inflate(R.layout.activity_lead, null, false);
mDrawerLayout.addView(contentView, 0);
ArrayList<NewsItem> listContact = GetlistContact();
ListView lv = (ListView)findViewById(R.id.listView);
lv.setAdapter(new CustomListAdapter(this, listContact));
}
private ArrayList<NewsItem> GetlistContact(){
ArrayList<NewsItem> contactlist = new ArrayList<NewsItem>();
NewsItem contact = new NewsItem();
for(int i=1;i<=30;i++) {
contact = new NewsItem();
contact.setHeadline("Yoge " +i);
contact.setReporterName("Yogeshwaran" + i);
contact.setLeadsource("Yogan" + i);
contact.setLeadStatus("open" + i);
contact.setLeadType("Business"+i);
contactlist.add(contact);
}
return contactlist;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main2, 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);
}
}
am trying to populate listview in child activity i can get the listview but navigation drawer is missing how to solve this!
For this purpose you can use to View Stub in your XML file, which will common for all Java files. Means you should make a separate XML (i.e write common code for all xml file into this one) and access this XML file in different-different java files (activity files).
You can better understand from below line of code.
Add following in your master/common XML file which contain to navigation drawer and action bar with View Stub.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/Home"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/activity_home"
tools:context="com.example.bhuvneshgautam.cityretails.HomeActivity">
<ViewStub
android:id="#+id/layout_stub"
android:inflatedId="#+id/message_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.75" />
</RelativeLayout>
now add below line of code in your each java file(activity java file)
in on Create
ViewStub stub = (ViewStub) findViewById(R.id.layout_stub);
stub.setLayoutResource(R.layout.home_content);
View inflated = stub.inflate();
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();
}
});
Now use to "R.layout.home_content" for passing to XML file name which contain to code which you want to different in different pages.Below is one file code of my project which contain to separate code which i want to different in that file.
In home_content.xml
<ImageView
android:id="#+id/Hpersonalcare"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/personalcare"
android:scaleType="centerCrop"/>
you have to use View Stub
<ViewStub
android:id="#+id/layout_stub"
android:inflatedId="#+id/message_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.75" />
in your MainActivity....
Main2Activity.java
public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener{
.........................
#Override
protected void onCreate(Bundle savedInstanceState) {
.....................
ViewStub stub = (ViewStub) findViewById(R.id.lay_stub);
stub.setLayoutResource(R.layout.home_content);
View inflated = stub.inflate();
Toolbar toolbar = (Toolbar) findViewById(R.id.tlbar);
setSupportActionBar(tlbar);
FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
dont use setContentView(...) again, it overwrites this call in Main2Activity removing drawer. let your "main" Activity be abstract and create protected abstract int getCustomContentView(...) which will be available in all extending Activities, return id which you have currently passing inside setContentView and inflate it in parent and add to container in Drawer. it might be done inside OnCreate so after super you can call directly after findViewByIdin childs
public abstract class Main2Activity extends Activity {
protected abstract int getCustomContentViewResId();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
LinearLayout container = (LinearLayout) findViewById(R.id.drawer_container);
int layoutResourceId = getCustomContentView();
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View innerView = inflater.inflate(layoutResourceId , container, true);
//rest of code
}
}
Lead:
public class LeadActivity extends Main2Activity {
protected int getCustomContentViewResId(){
return R.layout.activity_lead;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_lead);
// this goes to getCustomContentViewResId
ListView lv = (ListView)findViewById(R.id.listView);
// inflating already done in super.onCreate by extended Main2Activity so you may call findViewById directly without setContentView
}
//rest of code
}
Related
I'm trying to create a navigation drawer for Android. I've followed these pages (this and this) but now I'm stuck.
Here's my code, based on the planet navigation drawer:
package com.example.side_navigation_from_scratch;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.SearchManager;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private String mDrawerTitle;
private String mainTitle;
private String[] mPlanetTitles;
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
mainTitle = mDrawerTitle = (String) getTitle();
mPlanetTitles = getResources().getStringArray(R.array.planets_array);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
// set up the drawer's list view with items and click listener
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_list_item, mPlanetTitles));
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
// ActionBarDrawerToggle ties together the the proper interactions
// between the sliding drawer and the action bar app icon
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_close /* "close drawer" description for accessibility */
) {
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
getActionBar().setTitle(mainTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
if (savedInstanceState == null) {
selectItem(0);
}
// enable ActionBar app icon to behave as action to toggle nav drawer
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return super.onCreateOptionsMenu(menu);
}
/* Called whenever we call invalidateOptionsMenu() */
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// If the nav drawer is open, hide action items related to the content view
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// The action bar home/up action should open or close the drawer.
// ActionBarDrawerToggle will take care of this.
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle action buttons
switch(item.getItemId()) {
case R.id.action_websearch:
// create intent to perform web search for this planet
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY, getActionBar().getTitle());
// catch event that there's no activity to handle intent
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
} else {
Toast.makeText(this, R.string.app_not_available, Toast.LENGTH_LONG).show();
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/* The click listner for ListView in the navigation drawer */
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
private void selectItem(int position) {
// update the main content by replacing fragments
Fragment fragment = new PlanetFragment();
Bundle args = new Bundle();
args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
fragment.setArguments(args);
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(mPlanetTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
#Override
public void setTitle(CharSequence title) {
mainTitle = (String) title;
getActionBar().setTitle(mainTitle);
}
/**
* 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);
}
/**
* Fragment that appears in the "content_frame", shows a planet
*/
public static class PlanetFragment extends Fragment {
public static final String ARG_PLANET_NUMBER = "planet_number";
public PlanetFragment() {
// Empty constructor required for fragment subclasses
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_planet, container, false);
int i = getArguments().getInt(ARG_PLANET_NUMBER);
String planet = getResources().getStringArray(R.array.planets_array)[i];
TextView planetName = (TextView) rootView.findViewById(R.id.text);
getActivity().setTitle(planet);
return rootView;
}
}
}
I get different errors depending on the changes I make.
Like it is right now, I get
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setTitle(java.lang.CharSequence)' on a null object reference
ActionBarActivity is deprecated so I'm not going to use it but if I change Activity to AppCompatActivity, I get
java.lang.IllegalArgumentException: AppCompat does not support the current theme features
What am I doing wrong? Which is better to use: Activity, ActionBarActivity or AppCompatActivity? Thanks in advance
Thanks to Raghunandan I managed to fix this: I changed the Activity to AppCompatActivity and replaced getActionBar for getSupportActionBar. I don't have any more NPE
navigation drawer list class
package com.example.navigation;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class NavDrawerListAdapter extends BaseAdapter {
private Context context;
private ArrayList<NavDrawerItem> navDrawerItems;
public NavDrawerListAdapter(Context context, ArrayList<NavDrawerItem> navDrawerItems){
this.context = context;
this.navDrawerItems = navDrawerItems;
}
#Override
public int getCount() {
return navDrawerItems.size();
}
#Override
public Object getItem(int position) {
return navDrawerItems.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.drawer_list_item, null);
}
ImageView imgIcon = (ImageView) convertView.findViewById(R.id.icon);
TextView txtTitle = (TextView) convertView.findViewById(R.id.title);
imgIcon.setImageResource(navDrawerItems.get(position).getIcon());
txtTitle.setText(navDrawerItems.get(position).getTitle());
return convertView;
}
}
this is my main activity
package com.example.navigation;
import java.util.ArrayList;
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.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.RelativeLayout;
public class MainActivity extends ActionBarActivity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
protected RelativeLayout _completeLayout, _activityLayout;
// nav drawer title
private CharSequence mDrawerTitle;
// used to store app title
private CharSequence mTitle;
private ArrayList<NavDrawerItem> navDrawerItems;
private NavDrawerListAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// if (savedInstanceState == null) {
// // on first time display view for first nav item
// // displayView(0);
// }
}
public void set(String[] navMenuTitles, TypedArray navMenuIcons) {
mTitle = mDrawerTitle = getTitle();
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
navDrawerItems = new ArrayList<NavDrawerItem>();
// adding nav drawer items
if (navMenuIcons == null) {
for (int i = 0; i < navMenuTitles.length; i++) {
navDrawerItems.add(new NavDrawerItem(navMenuTitles[i]));
}
} else {
for (int i = 0; i < navMenuTitles.length; i++) {
navDrawerItems.add(new NavDrawerItem(navMenuTitles[i],
navMenuIcons.getResourceId(i, -1)));
}
}
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
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
// getSupportActionBar().setIcon(R.drawable.ic_drawer);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_launcher, // 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) {
getSupportActionBar().setTitle(mTitle);
// calling onPrepareOptionsMenu() to show action bar icons
supportInvalidateOptionsMenu();
}
public void onDrawerOpened(View drawerView) {
getSupportActionBar().setTitle(mDrawerTitle);
// calling onPrepareOptionsMenu() to hide action bar icons
supportInvalidateOptionsMenu();
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
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) {
// getSupportMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
if (mDrawerLayout.isDrawerOpen(mDrawerList)) {
mDrawerLayout.closeDrawer(mDrawerList);
} else {
mDrawerLayout.openDrawer(mDrawerList);
}
}
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) {
switch (position) {
case 0:
Intent intent = new Intent(this, FirstActivity.class);
startActivity(intent);
finish();// finishes the current activity
break;
case 1:
Intent intent1 = new Intent(this, SecondActivity.class);
startActivity(intent1);
finish();// finishes the current activity
break;
// case 2:
// Intent intent2 = new Intent(this, third.class);
// startActivity(intent2);
// finish();
// break;
// case 3:
// Intent intent3 = new Intent(this, fourth.class);
// startActivity(intent3);
// finish();
// break;
// case 4:
// Intent intent4 = new Intent(this, fifth.class);
// startActivity(intent4);
// finish();
// break;
// case 5:
// Intent intent5 = new Intent(this, sixth.class);
// startActivity(intent5);
// finish();
// break;
default:
break;
}
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
mDrawerLayout.closeDrawer(mDrawerList);
}
#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);
}
}
drawer item
package com.example.navigation;
public class NavDrawerItem {
private String title;
private int icon;
public NavDrawerItem() {
}
public NavDrawerItem(String title, int icon) {
this.title = title;
this.icon = icon;
}
public NavDrawerItem(String title) {
this.title = title;
}
public String getTitle() {
return this.title;
}
public int getIcon() {
return this.icon;
}
public void setTitle(String title) {
this.title = title;
}
public void setIcon(int icon) {
this.icon = icon;
}
}
I created a navigation drawer menu item but now i want to create sub menu item in navigation drawer menu item. So how can i create this please suggest me thanks in advance
Here is my navigation Drawer menu item code which we r created in String.xml
<string-array name="nav_drawer_items">
<item>First</item>
<item>Second</item>
<item>Third</item>
<item>Fourth</item>
<item>Fifth</item>
<item>Sixth</item>
</string-array>
Check the following link..
that helps you to create expandable listview in navigation drawer.
android-custom-navigation-drawer
You should check Andtroid Hive Example also.
Some more links that may be helpful to you.
Navigation drawer with Expandable list view - 1
Navigation drawer with Expandable list view - 2
You need customize your navigation drawer menu. Actually looks like use a simple ListView, if you need subsecction, you should use ExpandableListView. Something like this:
http://www.androidhive.info/2013/07/android-expandable-list-view-tutorial/
If show your code or how you create the navigation drawer, we can help you with replace your actual menu with the custom menu.
First - apologies for the newbie question.
I'm trying to implement a Navigation Drawer that will be used across my app. To start, I've followed the Android tutorial and created a basic navigation which changes a with Fragments.
I can pass a framelayout id and fragment to FragmentTransaction. It works great.
I decided to create a new login activity with the default android files (In Android Studio: going to new - activity - login activity ). This is what's confusing me. My questions are:
Can I create a fragment of the login activity where the actions in LoginActivity will work? It looks like the fragment will create a view based on the layout passed, but the methods used in LoginActivity won't work?
If creating a fragment does not work for the login activity, what would be the cleanest way to ensure the navigation works when switching activities? The Navigation Drawer only works when on the main activity; switching to other activities (via Intent) causes the app to lose the navigation drawer actions. The image of the actionbar/navigation drawer remains.
Here's some of my code in MainActivity ... maybe I'm missing something that is causing the navigation drawer to stop functioning when switching activities by Intent?
(Note: LoginActivity extends MainActivity in the LoginActivity class)
Thanks in advance for any direction / advice!
public class MainActivity extends ActionBarActivity {
private NavigationDrawerFragment mNavigationDrawerFragment;
//USER DATA
public String mUserID;
public String mToken;
public String mProgramData;
//NAVIGATION DRAWER
private CharSequence mTitle;
private CharSequence mDrawerTitle;
private String[] mTitles;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mActionBarDrawerToggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTitle = mDrawerTitle = getTitle();
// get list items for nav
mTitles = getResources().getStringArray(R.array.nav_menu);
//drawer widget
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
//listview of left drawer
mDrawerList = (ListView) findViewById(R.id.left_drawer);
// Set up the drawer.
mDrawerList.setAdapter(new ArrayAdapter<>(this,
R.layout.drawer_list_item, mTitles));
//set onclicklistener on the each list item of menu options
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
// some styling...
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
//enables action bar app behavior
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// ties drawerlayout and actionbar for navigation drawers
mActionBarDrawerToggle = new ActionBarDrawerToggle(
this,
mDrawerLayout,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close) {
// different titles for the drawer actions
public void onDrawerClosed(View drawerView) {
getSupportActionBar().setTitle(mTitle);
}
public void onDrawerOpened(View drawerView) {
getSupportActionBar().setTitle(mDrawerTitle);
}
};
// set drawer toggle as the drawer listener
mDrawerLayout.setDrawerListener(mActionBarDrawerToggle);
}
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
selectItem(position);
}
}
#Override
protected void onPostCreate(Bundle savedInstanceState){
super.onPostCreate(savedInstanceState);
mActionBarDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
mActionBarDrawerToggle.onConfigurationChanged(newConfig);
}
#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();
if (mActionBarDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
switch(id) {
case R.id.action_home:
Intent home = new Intent(this, MainActivity.class);
this.startActivity(home);
break;
case R.id.action_login:
Intent login = new Intent(this, LoginActivity.class);
this.startActivity(login);
break;
}
return super.onOptionsItemSelected(item);
}
EDIT
Thanks for your help so far in guiding me with my issue.
Unfortunately I don't think I'm asking the right question, but maybe viewing the LoginActivity code from Android Studio would help.
This is part of LoginActivity:
public class LoginActivity extends MainActivity implements LoaderCallbacks<Cursor> {
private UserLoginTask mAuthTask = null;
// UI references.
private AutoCompleteTextView mUserIDView;
private EditText mPasswordView;
private View mProgressView;
private View mLoginFormView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// Set up the login form.
mUserIDView = (AutoCompleteTextView) findViewById(R.id.email);
populateAutoComplete();
mPasswordView = (EditText) findViewById(R.id.password);
mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
if (id == R.id.login || id == EditorInfo.IME_NULL) {
attemptLogin();
return true;
}
return false;
}
});
Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button);
mEmailSignInButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
attemptLogin();
}
});
mLoginFormView = findViewById(R.id.login_form);
mProgressView = findViewById(R.id.login_progress);
}
private void populateAutoComplete() {
getLoaderManager().initLoader(0, null, this);
}
/**
* Attempts to sign in or register the account specified by the login form.
* If there are form errors (invalid email, missing fields, etc.), the
* errors are presented and no actual login attempt is made.
*/
public void attemptLogin() {
if (mAuthTask != null) {
return;
}
// Reset errors.
mUserIDView.setError(null);
mPasswordView.setError(null);
// Store values at the time of the login attempt.
String email = mUserIDView.getText().toString();
String password = mPasswordView.getText().toString();
boolean cancel = false;
View focusView = null;
// Check for a valid password, if the user entered one.
if (TextUtils.isEmpty(password)) {
mPasswordView.setError(getString(R.string.error_invalid_password));
focusView = mPasswordView;
cancel = true;
}
// Check for a valid email address or ID.
if (TextUtils.isEmpty(email)) {
mUserIDView.setError(getString(R.string.error_field_required));
focusView = mUserIDView;
cancel = true;
} else if (!isEmailValid(email) && !isIDValid(email)) {
mUserIDView.setError(getString(R.string.error_invalid_email));
focusView = mUserIDView;
cancel = true;
}
if (cancel) {
// There was an error; don't attempt login and focus the first
// form field with an error.
focusView.requestFocus();
} else {
// Show a progress spinner, and kick off a background task to
// perform the user login attempt.
showProgress(true);
mAuthTask = new UserLoginTask(email, password);
mAuthTask.execute((Void) null);
}
}
private boolean isEmailValid(String email) {
//TODO: Replace this with your own logic
return email.contains("#");
}
private boolean isIDValid(String email) {
//TODO: Replace this with your own logic
return email.length() == 6;
}
[continued]...........
I'll create a simple fragment of LoginActivity called menu1_Fragment:
public class menu1_Fragment extends android.support.v4.app.Fragment {
View rootview;
public View onCreateView(LayoutInflater inflater, ViewGroup view, Bundle savedInstanceState) {
rootview = (ViewGroup)inflater.inflate(R.layout.activity_login, null);
return rootview;
}
}
If i'm correct (hopefully I'm wrong!) the fragment is replaced with the View (menu1_Fragment). The View cannot have actions (like clicking the login button to send a httppost request).
Also, could you explain why onOptionsItemSelected in MainActivity breaks the navigationdrawer (drawer becomes unclickable. also cannot swipe right to pull it up). Intent launches an activity (LoginActivity), but only the drawer in apperance shows.
to hide also ActionBar icons you can do like:
#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);
}
}
To replace main fragment when you click an item from the drawable menu list i see you have used selectItem(position) method, however that method is never declared on your code. To do that also you can do something like:
private void selectItem(int position){
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 1:
fragment = new TestFragment();
break;
case 2:
fragment = new TestFragment2();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
// update selected item and title, then close the drawer
setTitle(navMenuTitles[position]);
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
I am giving you a example with multiple activities defined as fragment and called using MainActivity, Hope you will get your solution among it..
MainActivity.java
package com.example.fragmentdemo1;
import java.util.ArrayList;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBarActivity;
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 MainActivity extends ActionBarActivity implements
OnItemClickListener {
MainActivity activity;
private ListView lv;
private ArrayList<String> list = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
activity = this;
lv = (ListView) findViewById(R.id.listView);
list.add("First");
list.add("Second");
list.add("Third");
list.add("Forth");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(activity,
android.R.layout.simple_list_item_1, list);
lv.setAdapter(adapter);
lv.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
switch (position) {
case 0:
Fragment1 f1 = new Fragment1();
FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
transaction.addToBackStack(null);
transaction.replace(R.id.container, f1).commit();
break;
case 1:
Fragment2 f2 = new Fragment2();
FragmentTransaction transaction2 = getSupportFragmentManager()
.beginTransaction();
transaction2.addToBackStack(null);
transaction2.replace(R.id.container, f2).commit();
break;
case 2:
Toast.makeText(activity, "" + position, 1000).show();
Fragment3 f3 = new Fragment3();
FragmentTransaction transaction3 = getSupportFragmentManager()
.beginTransaction();
transaction3.addToBackStack(null);
transaction3.replace(R.id.container, f3).commit();
break;
case 3:
Fragment4 f4 = new Fragment4();
FragmentTransaction transaction4 = getSupportFragmentManager()
.beginTransaction();
transaction4.addToBackStack(null);
transaction4.replace(R.id.container, f4).commit();
break;
default:
break;
}
}
#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();
switch (id) {
case android.R.id.home:
finish();
break;
default:
break;
}
return false;
}
}
Fragment1.java
package com.example.fragmentdemo1;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class Fragment1 extends android.support.v4.app.Fragment{
TextView tv;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup view,
Bundle savedInstanceState) {
tv =(TextView)view.findViewById(R.id.textView1);
view = (ViewGroup) inflater.inflate(R.layout.fragment1, null);
return view;
}
}
Fragment2.java
package com.example.fragmentdemo1;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class Fragment2 extends Fragment {
TextView tv;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup view,
Bundle savedInstanceState) {
tv =(TextView)view.findViewById(R.id.textView2);
view = (ViewGroup) inflater.inflate(R.layout.fragment2, null);
return view;
}
}
Fragment3.java
package com.example.fragmentdemo1;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class Fragment3 extends Fragment {
TextView tv;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup view,
Bundle savedInstanceState) {
tv =(TextView)view.findViewById(R.id.textView3);
view =(ViewGroup)inflater.inflate(R.layout.fragment3, null);
return view;
}
}
Fragment4.java
package com.example.fragmentdemo1;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class Fragment4 extends Fragment{
TextView tv;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup view,
Bundle savedInstanceState) {
tv =(TextView)view.findViewById(R.id.textView4);
view = (ViewGroup)inflater.inflate(R.layout.fragment4, null);
return view;
}
}
NOTE : If you want to use method from Fragment class to MainActivity, then you can make it public static, and you can use that method directly by it's class name like Fragment1.countData().
This demo also apply for Navigation drawer.
Hello i have a small problem with my project. I have a sliding menu with webviews . But i can't go back in webviews, when i push the button to go back my app just crash. I tryed with OnBackPressed method and OnKeyDown, but no one of this work. here is my code. just the main activity class and webviewfragment class
Where shoul i put the methods to work fine ? In webview fragment class, not work because webviews extend fragment, no fragmentActivity.
package com.pavan.slidingmenu;
import java.util.ArrayList;
import java.util.List;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
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.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.webkit.WebView;
import android.widget.AdapterView;
import android.widget.ListView;
public class MainActivity extends Activity {
WebView webview ;
String[] menutitles;
TypedArray menuIcons;
String[] pageUrl;
// nav drawer title
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private List<RowItem> rowItems;
private CustomAdapter adapter;
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTitle = mDrawerTitle = getTitle();
menutitles = getResources().getStringArray(R.array.titles);
menuIcons = getResources().obtainTypedArray(R.array.icons);
pageUrl = getResources().getStringArray(R.array.pageurl);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.slider_list);
rowItems = new ArrayList<RowItem>();
for (int i = 0; i < menutitles.length; i++) {
RowItem items = new RowItem(menutitles[i], menuIcons.getResourceId(
i, -1), pageUrl[i]);
rowItems.add(items);
}
menuIcons.recycle();
adapter = new CustomAdapter(getApplicationContext(), rowItems);
mDrawerList.setAdapter(adapter);
mDrawerList.setOnItemClickListener(new SlideitemListener());
// 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, R.string.app_name,
R.string.app_name) {
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
updateDisplay(0);
}
}
class SlideitemListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
updateDisplay(position);
}
}
private void updateDisplay(int position) {
String url = rowItems.get(position).getPageUrl();
Fragment fragment = new MyWebViewFragment();
Bundle bundle = new Bundle();
bundle.putString("url", url);
fragment.setArguments(bundle);
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
setTitle(menutitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
#Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
#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);
}
/**
* 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);
}
// #Override
// public void onBackPressed()
// {
// if(webview.canGoBack())
// webview.goBack();
// else
// super.onBackPressed();
// }
// #Override
// public boolean onKeyDown(int keyCode, KeyEvent event) {
// if(event.getAction() == KeyEvent.ACTION_DOWN){
// switch(keyCode)
// {
// case KeyEvent.KEYCODE_BACK:
// if(webview.canGoBack()){
// webview.goBack();
// }else{
// finish();
// }
// return true;
// }
//
// }
// return super.onKeyDown(keyCode, event);
// }
}
package com.pavan.slidingmenu;
import android.app.Fragment;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebSettings.PluginState;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MyWebViewFragment extends Fragment {
ProgressDialog mProgress;
WebView webview;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.web_fragment, container,
false);
Bundle bundle = getArguments();
String url = bundle.getString("url");
webview = (WebView) rootView.findViewById(R.id.webview1);
WebSettings settings = webview.getSettings();
settings.setJavaScriptEnabled(true);
settings.setLoadWithOverviewMode(true);
settings.setUseWideViewPort(true);
settings.setBuiltInZoomControls(true);
settings.setPluginState(PluginState.ON);
mProgress = ProgressDialog.show(getActivity(), "Loading",
"Please wait for a moment...");
webview.loadUrl(url);
webview.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (mProgress.isShowing()) {
mProgress.dismiss();
}
}
});
return rootView;
}
}
You just need to make your WebViewFragment implement an Interface, like this:
public interface onBackPressedInterface
{
public void onBackPressedWebView();
}
The only method of the Interface will be implemented on your fragment, so you have to add implements clause on your Fragment declaration, like this:
public class MyWebViewFragment extends Fragment implements onBackPressedInterface{
and implement the method like this:
/**
* the user presses the back button
*/
#Override
public void onBackPressedWebView()
{
if (webview.canGoBack()){
webview.goBack();
((MainActivity) getActivity()).canGoBack=true;
}
else{
((MainActivity) getActivity()).canGoBack=false;
getActivity().onBackPressed();
}
}
In your MainActivity, add a boolean variable that defines if you make the normal back behaviour or execute the Interface method on your Fragment. It is public so the Fragment can access it and modify it when there is no more backs to make on the WebView. It is true at the begginig so the interface method could be allways called at the first time the user clicks back button.
public boolean canGoBack = true;
Once the user clicks the back button, the onBackPressed() callback is called on your MainActivity, so overrite it like this:
#Override
public void onBackPressed()
{
if(canGoBack)
((onBackPressedInterface)getSupportFragmentManager().findFragmentById(R.id.webview_fragment)).onBackPressedWebView();
if(!canGoBack)
super.onBackPressed();
}
R.id.webview_fragment is the id of the fragment that I have declared in my Activity layout file.
So, when the user clicks back button, the fragment method is called, it checks if the webview can go back. If it can, goes back and keeps the Activity boolean true so it can be executed again when a new click occurs.
When the WebView has no more backs, the variable is set to false and the normal onBackPressed method is executed, by calling getActivity().onBackPressed().
This is what your Activity layout should be like, with one fixed Fragment component:
<?xml version="1.0" encoding="utf-8"?>
<fragment
android:id="#+id/webview_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.pavan.slidingmenu.MyWebViewFragment" />
If you do not want to have a fixed Fragment in your layout, just create a call in your MyWebViewFragment to create an instance of your fragment, like:
MyWebViewFragment.newInstance() and call the interface callback on that Fragment
So I have my navigation drawer functionality in the MainActivity of my project, and I have my nav drawer links linked to a fragment, but I don't know how to add a UI to that. Things specifically like findViewById(r.id.code), and trying to set TextView's give me errors like unreachable code here is what I have so far.
MainActivity
package yc.android.yourchallenger;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.res.Configuration;
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 {
private String [] mNavigationDrawerItemTitles;
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNavigationDrawerItemTitles = getResources().getStringArray(R.array.navigation_drawer_items_array);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
// Set the adapter for the list view
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.nav_drawer, mNavigationDrawerItemTitles));
// Set the list's click listener
mDrawerList.setOnItemClickListener((OnItemClickListener) new DrawerItemClickListener());
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_launcher, /* nav drawer icon to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description */
R.string.drawer_close /* "close drawer" description */
) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
getActionBar().setTitle(mTitle);
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
getActionBar().setTitle(mDrawerTitle);
}
};
// Set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDrawerToggle.onConfigurationChanged(newConfig);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Pass the event to ActionBarDrawerToggle, if it returns
// true, then it has handled the app icon touch event
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle your other action bar items...
return super.onOptionsItemSelected(item);
}
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
private void selectItem(int position) {
Fragment fragment = null;
switch (position){
case 0: fragment = new CreateFragment();
break;
case 1: fragment = new ReadFragment();
break;
case 2: fragment = new HelpFragment();
break;
default:
break;
}
/* Bundle args = new Bundle();
args.putInt("key", position);
fragment.setArguments(args);*/
if(fragment != null){
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.commit();
// Highlight the selected item, update the title, and close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(mNavigationDrawerItemTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
}
#Override
public void setTitle(CharSequence title){
mTitle = title;
getActionBar().setTitle(mTitle);
}
}
And here is one of my fragments
package yc.android.yourchallenger;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class ReadFragment extends Fragment {
public ReadFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_create, container, false);
TextView view = findViewById(R.id.view);
return rootView;
}
}
There is no reason to make the view created in onCreateView() static (re: Droidy). Simply call getView() anywhere within the Fragment lifecycle after onCreateView().
In your example, all you needed was to change
TextView view = findViewById(R.id.view);
to
TextView view = (TextView) rootView.findViewById(R.id.view);
You can call findViewById(int) on any ViewGroup to find it's children. Calling it in an Activity is a convenience method that uses the view set in setContentView().
So if you wanted to find the view later in the Fragment lifecycle, you'd do something like:
#Override
public void onActivityCreated(Bundle savedInstanceState) {
TextView view = (TextView) getView().findViewById(R.id.view);
}
You can also instantiate views in onViewCreated(View view, Bundle savedInstanceState), where the root view is the first parameter.
Make rootView , private (static) and declare it before the default constructor. Then after inflating your layout to rootView, you can access all the UI elements by using the rootView as follows.
TextView view = (TextView) rootView.findViewById(R.id.view);
Use getActivity() instead of the keyword this inside your Fragment class.
Hope it helps.