App crashed after adding navigation menu in Android Studio - java

Please take a look at my source code, my app crashed after I added the navigation Menu. Can you please tell what is wrong I have been searching all on Google and could not arrive at a solution to this issue? Thank You.
My MainActivity looks like:
package com.example.rssreader;
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.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.support.v7.app.ActionBar;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private android.support.v4.app.ActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mPlanetTitles;
RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
ReadRss readRss = new ReadRss(this, recyclerView);
readRss.execute();
mTitle = mDrawerTitle = getTitle();
mPlanetTitles = getResources().getStringArray(R.array.contents);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
// set a custom shadow that overlays the main content when the drawer opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// 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());
// enable ActionBar app icon to behave as action to toggle nav drawer
// ActionBarDrawerToggle ties together the the proper interactions
// between the sliding drawer and the action bar app icon
mDrawerToggle = new android.support.v4.app.ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_close /* "close drawer" description for accessibility */
) {
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
if (savedInstanceState == null) {
selectItem(0);
}
getWindow().setNavigationBarColor(getResources().getColor(R.color.colorPrimary));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.layout.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);
// 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_CONTENT_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) {
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);
}
/**
* Fragment that appears in the "content_frame", shows a planet
*/
public static class PlanetFragment extends Fragment {
public static final String ARG_CONTENT_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_content, container, false);
int i = getArguments().getInt(ARG_CONTENT_NUMBER);
String planet = getResources().getStringArray(R.array.contents)[i];
int imageId = getResources().getIdentifier(planet.toLowerCase(Locale.getDefault()),
"drawable", getActivity().getPackageName());
((ImageView) rootView.findViewById(R.id.image)).setImageResource(imageId);
getActivity().setTitle(planet);
return rootView;
}
}
}
My Activity_main.xml looks like:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ListView
android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#ccc"/>
</android.support.v4.widget.DrawerLayout>
Drawer_list_item.xml looks like:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textColor="#113d5e"
android:background="?android:attr/activatedBackgroundIndicator"
android:minHeight="?android:attr/listPreferredItemHeightSmall"/>
Fragment_content.xml looks like:
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:gravity="center"
android:padding="32dp" />
Main.xml looks like:
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:gravity="center"
android:padding="32dp" />
Thank You

I was able to fix that issue by creating a separate class for the navigation drawer. However, I am facing another issue with the RssFeeds.
public class ReadRss extends AsyncTask and recyclerView.setLayoutManager(new LinearLayoutManager(context) is where the error is pointing to when the app crashed when running the debug.
Here is the ReadRss.java:
package tk.mattercast.myapplication;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
public class ReadRss extends AsyncTask<Void, Void, Void> {
Context context;
String address = "http://www.oecd.org/corruption/index.xml";
ProgressDialog progressDialog;
ArrayList<FeedItem>feedItems;
RecyclerView recyclerView;
URL url;
public ReadRss(Context context,RecyclerView recyclerView) {
this.recyclerView=recyclerView;
this.context = context;
progressDialog = new ProgressDialog(context);
progressDialog.setMessage("Fetching Data...");
}
#Override
protected void onPreExecute() {
progressDialog.show();
super.onPreExecute();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
progressDialog.dismiss();
MyAdapter adapter=new MyAdapter(context,feedItems);
recyclerView.setLayoutManager(new LinearLayoutManager(context) {
#Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return null;
}
});
recyclerView.addItemDecoration(new VerticalSpace(50));
recyclerView.setAdapter(adapter);
}
#Override
protected Void doInBackground(Void... params) {
ProcessXml(Getdata());
return null;
}
private void ProcessXml(Document data) {
if (data != null) {
feedItems=new ArrayList<>();
Element root = data.getDocumentElement();
Node channel = root.getChildNodes().item(1);
NodeList items = channel.getChildNodes();
for (int i = 0; i < items.getLength(); i++) {
Node cureentchild = items.item(i);
if (cureentchild.getNodeName().equalsIgnoreCase("item")) {
FeedItem item=new FeedItem();
NodeList itemchilds = cureentchild.getChildNodes();
for (int j = 0; j < itemchilds.getLength(); j++) {
Node cureent = itemchilds.item(j);
if (cureent.getNodeName().equalsIgnoreCase("title")){
item.setTitle(cureent.getTextContent());
}else if (cureent.getNodeName().equalsIgnoreCase("description")){
item.setDescription(cureent.getTextContent());
}else if (cureent.getNodeName().equalsIgnoreCase("pubDate")){
item.setPubDate(cureent.getTextContent());
}else if (cureent.getNodeName().equalsIgnoreCase("link")){
item.setLink(cureent.getTextContent());
}
}
feedItems.add(item);
}
}
}
}
public Document Getdata() {
try {
url = new URL(address);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
InputStream inputStream = connection.getInputStream();
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDoc = builder.parse(inputStream);
return xmlDoc;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

Related

Scrollview is not working in fragment

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context="mcb.myclickbazaar.Fragments.DateTimePlace">
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:isScrollContainer="false"
android:fillViewport="true"
android:padding="10dp">
<LinearLayout>
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout...>
<LinearLayout...>
<LinearLayout...>
<LinearLayout...>
</LinearLayout>
</ScrollView>
</RelativeLayout>
The scrollview is not working. I have tried all the answers from stackoverflow, but still can't find a way to solve this issue.
This xml file is a fragment. It is one of the fragment from tabbedView Activity.
EDIT
JAVA FILE
package mcb.myclickbazaar.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import java.util.ArrayList;
import java.util.List;
import mcb.myclickbazaar.Fragments.DateTimePlace;
import mcb.myclickbazaar.Fragments.FinalBill;
import mcb.myclickbazaar.Fragments.ItemSelect;
import mcb.myclickbazaar.R;
public class ProceedingsActivity extends AppCompatActivity implements ItemSelect.OnFragmentInteractionListener,
DateTimePlace.OnFragmentInteractionListener,FinalBill.OnFragmentInteractionListener{
private static final String TAG = "ProceedingsActivity";
private ViewPager mViewPager;
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_proceedings);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar = (Toolbar) findViewById(R.id.toolbar);
//setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
viewPager = (ViewPager) findViewById(R.id.viewpager_proceedings);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
#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_proceedings, 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);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new ItemSelect(), "Select");
adapter.addFragment(new DateTimePlace(), "DateTime");
adapter.addFragment(new FinalBill(), "Bill");
viewPager.setAdapter(adapter);
}
#Override
public void onFragmentInteraction(Uri uri) {
Log.e(TAG,"Working: on onFragmentInteraction");
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}
Fragment Code
package mcb.myclickbazaar.Fragments;
import android.content.Context;
import android.net.Uri;
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.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import mcb.myclickbazaar.R;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link DateTimePlace.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {#link DateTimePlace#newInstance} factory method to
* create an instance of this fragment.
*/
public class DateTimePlace extends Fragment implements AdapterView.OnItemSelectedListener {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private String upcoming_date_1,upcoming_date_2,upcoming_date_3,upcoming_date_4;
private EditText editText_date;
private EditText editText_time;
private Spinner spinner_calendar;
private Spinner spinner_time;
private OnFragmentInteractionListener mListener;
public DateTimePlace() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment DateTimePlace.
*/
// TODO: Rename and change types and number of parameters
public static DateTimePlace newInstance(String param1, String param2) {
DateTimePlace fragment = new DateTimePlace();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
// Spinner element
final View view = inflater.inflate(R.layout.fragment_date_time_place, container, false);
spinner_calendar = (Spinner) view.findViewById(R.id.spinner_calender);
spinner_time = (Spinner) view.findViewById(R.id.spinner_time);
editText_date = (EditText) view.findViewById(R.id.editText_SelectDate_DTP);
editText_time = (EditText) view.findViewById(R.id.editText_SelectTime_DTP);
editText_date.setFocusable(false);
editText_time.setFocusable(false);
editText_date.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
spinner_calendar.setVisibility(View.VISIBLE);
spinner_calendar.performClick();
editText_date.setHint("");
}
});
editText_time.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
spinner_time.setVisibility(View.VISIBLE);
spinner_time.performClick();
editText_time.setHint("");
}
});
// Spinner click listener
spinner_calendar.setOnItemSelectedListener(this);
// Spinner Drop down elements
List<String> categories_calender = new ArrayList<String>();
categories_calender.add("Today");
categories_calender.add("Tomorrow");
categories_calender.add(getUpcoming_Date(2));
categories_calender.add(getUpcoming_Date(3));
categories_calender.add(getUpcoming_Date(4));
categories_calender.add(getUpcoming_Date(5));
// Creating adapter for spinner
ArrayAdapter<String> dataAdapter_calendar = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_item, categories_calender);
// Drop down layout style - list view with radio button
dataAdapter_calendar.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// attaching data adapter to spinner
spinner_calendar.setAdapter(dataAdapter_calendar);
// Spinner click listener
spinner_time.setOnItemSelectedListener(this);
// Spinner Drop down elements
List<String> categories_time = new ArrayList<String>();
categories_time.add("9AM - 11AM");
categories_time.add("11AM - 1PM");
categories_time.add("1PM - 3PM");
categories_time.add("3PM - 5PM");
categories_time.add("5PM - 7PM");
// Creating adapter for spinner
ArrayAdapter<String> dataAdapter_time = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_item, categories_time);
// Drop down layout style - list view with radio button
dataAdapter_time.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// attaching data adapter to spinner
spinner_time.setAdapter(dataAdapter_time);
return view;
}
private String getUpcoming_Date(int upcoming){
Calendar c = Calendar.getInstance();
Date dt = new Date();
c.add(Calendar.DATE, upcoming);
SimpleDateFormat df = new SimpleDateFormat("EEE,dd MMM", Locale.US);
String formattedDate = df.format(c.getTime());
return formattedDate;
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// On selecting a spinner item
String item = parent.getItemAtPosition(position).toString();
}
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri);
}
}
try this :
make hight match_parent for relativeLayout and ScrollView both like below
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="sdsd"/>
</LinearLayout>
</ScrollView>
</RelativeLayout>
Keep scroll view height as match parent and the height of everything inside it as wrap content.

Navigation drawer icon is not displaying correctly

I followed a tutorial on how to add a navigation drawer to my app. I got it mostly working however after using the navigation drawer the icon is always an arrow pointing to the left. I read that many people forget to add the onPostCreate method. However after adding that method the issue continued.
Note: that the xml layout for the navigation drawer is blank
ProjectsList.java
package com.austinerck.projectteamwork;
import android.content.Context;
import android.os.PersistableBundle;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.SwipeRefreshLayout;
import android.os.Bundle;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.CardView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.ArrayList;
public class ProjectsList extends AppCompatActivity {
ActionBarDrawerToggle drawerToggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_projects_list);
//Toolbar
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
if(getSupportActionBar() != null) {
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
//Navigation Drawer
NavigationDrawerFragment navigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.fragmentNavigationDrawer);
navigationDrawerFragment.setup((DrawerLayout) findViewById(R.id.drawerLayout), (Toolbar) findViewById(R.id.toolbar));
drawerToggle = navigationDrawerFragment.getDrawerToggle();
//SwipeRefreshLayout
final SwipeRefreshLayout swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefresher);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
//TODO: Refresh code goes here
swipeRefreshLayout.setRefreshing(false);
}
});
swipeRefreshLayout.setColorSchemeColors(R.color.colorPrimary);
//RecyclerView
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(new ProjectsListAdapter());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_projects_list, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (drawerToggle.onOptionsItemSelected(item)) {
return true;
}
int id = item.getItemId();
switch (id){
case R.id.action_refresh:
break;
case R.id.action_sort:
break;
case R.id.action_feedback:
break;
case R.id.action_settings:
break;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
drawerToggle.syncState();
}
}
class ProjectsListAdapter extends RecyclerView.Adapter{
private ArrayList<ProjectsListInfo> projectInfo = new ArrayList<>();
ProjectsListAdapter(){
//TODO: Load in information to projectInfo
projectInfo.add(new ProjectsListInfo(NasaProjects.GEMINI));
projectInfo.add(new ProjectsListInfo(NasaProjects.APOLLO));
projectInfo.add(new ProjectsListInfo(NasaProjects.ISS));
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
final View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.fragment_project_card, viewGroup, false);
CardView card = (CardView) view.findViewById(R.id.projectCard);
TextView name1 = (TextView) view.findViewById(R.id.projectName);
TextView creator = (TextView) view.findViewById(R.id.creator);
TextView description = (TextView) view.findViewById(R.id.description);
RelativeLayout background = (RelativeLayout) view.findViewById(R.id.background);
Button buttonViewProject = (Button) view.findViewById(R.id.button_view_project);
Button buttonDescription = (Button) view.findViewById(R.id.button_description);
buttonViewProject.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Shortcut.toast(view.getContext(), "View Project Clicked!");
}
});
buttonDescription.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Shortcut.toast(view.getContext(), "Description Clicked");
}
});
return new ProjectCardView(view, card, name1, creator, description, background, buttonViewProject, buttonDescription);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
ProjectCardView view;
view = (ProjectCardView) viewHolder;
view.name.setText(projectInfo.get(i).getName());
view.creator.setText("Created by " + projectInfo.get(i).getCreator());
view.description.setText(projectInfo.get(i).getDescription());
view.background.setBackgroundResource(projectInfo.get(i).getBackground());
}
#Override
public int getItemCount() {
return projectInfo.size();
}
class ProjectCardView extends RecyclerView.ViewHolder /*implements View.OnClickListener*/{
View itemView;
CardView card;
TextView name, creator, description;
RelativeLayout background;
Button buttonViewProject, buttonDescription;
Context context;
public ProjectCardView(View view, CardView card, TextView name, TextView creator, TextView description, RelativeLayout background, Button buttonViewProject, Button buttonDescription) {
super(view);
context = view.getContext();
this.itemView = view;
this.card = card;
this.name = name;
this.creator = creator;
this.description = description;
this.background = background;
this.buttonViewProject = buttonViewProject;
this.buttonDescription = buttonDescription;
}
}
}
class ProjectsListInfo{
private String name, creator, description;
private int background;
//TODO: Use this to bundle information from the server
/*ProjectsListInfo(String name, String creator, String description, int background){
this.name = name;
this.creator = creator;
this.description = description;
this.background = background;
}*/
ProjectsListInfo(NasaProjects exampleProject){
name = exampleProject.getName();
creator = exampleProject.getCreator();
description = exampleProject.getDesc();
background = exampleProject.getBackground();
}
public String getName() {
return name;
}
public String getCreator() {
return creator;
}
public String getDescription() {
return description;
}
public int getBackground() {
return background;
}
}
NavigationDraweFragment.java
package com.austinerck.projectteamwork;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class NavigationDrawerFragment extends Fragment {
private ActionBarDrawerToggle drawerToggle;
public NavigationDrawerFragment() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
}
public void setup(DrawerLayout drawerLayout, Toolbar toolbar){
drawerToggle = new ActionBarDrawerToggle(getActivity(), drawerLayout, toolbar, R.string.nav_drawer_open, R.string.nav_drawer_close){
#Override
public void onDrawerOpened(View drawerView){
super.onDrawerOpened(drawerView);
getActivity().invalidateOptionsMenu();
}
#Override
public void onDrawerClosed(View drawerView){
super.onDrawerOpened(drawerView);
getActivity().invalidateOptionsMenu();
}
};
drawerLayout.setDrawerListener(drawerToggle);
drawerLayout.post(new Runnable() {
#Override
public void run() {
drawerToggle.syncState();
}
});
}
public ActionBarDrawerToggle getDrawerToggle() {
return drawerToggle;
}
}
activity_projects_list.xml
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawerLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:context=".ProjectsList">
<include
android:id="#+id/toolbar"
layout="#layout/fragment_toolbar"/>
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipeRefresher"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="#dimen/paddingSmall"
android:paddingRight="#dimen/paddingSmall"/>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
<fragment
android:id="#+id/fragmentNavigationDrawer"
android:layout_width="#dimen/drawerWidth"
android:layout_height="match_parent"
android:layout_gravity="start"
app:layout="#layout/fragment_navigation_drawer"
android:name="com.austinerck.projectteamwork.NavigationDrawerFragment"/>
</android.support.v4.widget.DrawerLayout>
Please change
getSupportActionBar().setDisplayShowHomeEnabled(true);
to
getSupportActionBar().setDisplayShowHomeEnabled(false);
this should do the trick.

Starting Activity from Fragment (error inflating class fragment)

I created a navigation drawer fragment and within it I am switching on the position in order to start different activities. The activity that I am trying to start (called p2p_main) extends FragmentActivity.
Here is the code of the fragment from which I am trying to start the p2p_main activity. The second activity is part of an imported project (imported as a library module) that allows the device to find other devices and connect via WiFi direct.
From my navigation drawer fragment when case 1 is selected I want to start the p2p_main activity. I get the following error when I click on the button (the app crashes):
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.jonny.nav/com.mycompany.p2pwifi.p2p_main}: android.view.InflateException: Binary XML file line #19: Error inflating class fragment
package com.jonny.nav;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.app.Fragment;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
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.Toast;
import com.example.fileexplorer.FileChooser;
import com.mycompany.p2pwifi.p2p_main;
/**
* Fragment used for managing interactions for and presentation of a navigation drawer.
* See the <a href="https://developer.android.com/design/patterns/navigation-drawer.html#Interaction">
* design guidelines</a> for a complete explanation of the behaviors implemented here.
*/
public class NavigationDrawerFragment extends Fragment {
/**
* Remember the position of the selected item.
*/
private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
/**
* Per the design guidelines, you should show the drawer on launch until the user manually
* expands it. This shared preference tracks this.
*/
private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
/**
* A pointer to the current callbacks instance (the Activity).
*/
private NavigationDrawerCallbacks mCallbacks;
/**
* Helper component that ties the action bar to the navigation drawer.
*/
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private ListView mDrawerListView;
private View mFragmentContainerView;
private int mCurrentSelectedPosition = 0;
private boolean mFromSavedInstanceState;
private boolean mUserLearnedDrawer;
public NavigationDrawerFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDrawerLayout = null;
// Read in the flag indicating whether or not the user has demonstrated awareness of the
// drawer. See PREF_USER_LEARNED_DRAWER for details.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
if (savedInstanceState != null) {
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
mFromSavedInstanceState = true;
}
// Select either the default item (0) or the last selected item.
//DEFAULT DEFAULT DEFAULT
//DEFAULT!!!!!
//selectItem(mCurrentSelectedPosition);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Indicate that this fragment would like to influence the set of actions in the action bar.
setHasOptionsMenu(true);
}
#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);
}
});
mDrawerListView.setAdapter(new ArrayAdapter<String>(
getActionBar().getThemedContext(),
android.R.layout.simple_list_item_activated_1,
android.R.id.text1,
new String[]{
getString(R.string.title_section1),
getString(R.string.title_section2),
getString(R.string.title_section3),
getString(R.string.title_section4),
}));
mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
return mDrawerListView;
}
public boolean isDrawerOpen() {
return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView);
}
/**
* Users of this fragment must call this method to set up the navigation drawer interactions.
*
* #param fragmentId The android:id of this fragment in its activity's layout.
* #param drawerLayout The DrawerLayout containing this fragment's UI.
*/
public void setUp(int fragmentId, DrawerLayout drawerLayout) {
mFragmentContainerView = getActivity().findViewById(fragmentId);
mDrawerLayout = drawerLayout;
// set a custom shadow that overlays the main content when the drawer opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// set up the drawer's list view with items and click listener
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the navigation drawer and the action bar app icon.
mDrawerToggle = new ActionBarDrawerToggle(
getActivity(), /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.navigation_drawer_open, /* "open drawer" description for accessibility */
R.string.navigation_drawer_close /* "close drawer" description for accessibility */
) {
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
if (!isAdded()) {
return;
}
getActivity().supportInvalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
if (!isAdded()) {
return;
}
if (!mUserLearnedDrawer) {
// The user manually opened the drawer; store this flag to prevent auto-showing
// the navigation drawer automatically in the future.
mUserLearnedDrawer = true;
SharedPreferences sp = PreferenceManager
.getDefaultSharedPreferences(getActivity());
sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
}
getActivity().supportInvalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
};
// If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,
// per the navigation drawer design guidelines.
if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
mDrawerLayout.openDrawer(mFragmentContainerView);
}
// Defer code dependent on restoration of previous instance state.
mDrawerLayout.post(new Runnable() {
#Override
public void run() {
mDrawerToggle.syncState();
}
});
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
/*
Determine which activity to start based on selected item.
*/
private void selectItem(int position) {
/* mCurrentSelectedPosition = position;
if (mDrawerListView != null) {
mDrawerListView.setItemChecked(position, true);
}
if (mDrawerLayout != null) {
mDrawerLayout.closeDrawer(mFragmentContainerView);
}
if (mCallbacks != null) {
mCallbacks.onNavigationDrawerItemSelected(position);
}*/
Intent selectedIntent = null;
switch(position){
case 0: //file explorer activity will need to move to Robert's code
{
//Start p2p_main's code here
selectedIntent = new Intent(getActivity(), FileChooser.class);
getActivity().startActivity(selectedIntent);
break;
}
case 1:
{
//start file explorer
selectedIntent = new Intent(getActivity(), p2p_main.class);
startActivity(selectedIntent);
break;
}
case 2:
{
break;
}
case 3:
{
break;
}
default:
break;
}
mDrawerListView.setItemChecked(position,true);
mDrawerLayout.closeDrawer(mDrawerListView);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallbacks = (NavigationDrawerCallbacks) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
}
}
#Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Forward the new configuration the drawer toggle component.
mDrawerToggle.onConfigurationChanged(newConfig);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// If the drawer is open, show the global app actions in the action bar. See also
// showGlobalContextActionBar, which controls the top-left area of the action bar.
if (mDrawerLayout != null && isDrawerOpen()) {
inflater.inflate(R.menu.global, menu);
showGlobalContextActionBar();
}
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
if (item.getItemId() == R.id.action_example) {
Toast.makeText(getActivity(), "Example action.", Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Per the navigation drawer design guidelines, updates the action bar to show the global app
* 'context', rather than just what's in the current screen.
*/
private void showGlobalContextActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setTitle(R.string.app_name);
}
private ActionBar getActionBar() {
return ((ActionBarActivity) getActivity()).getSupportActionBar();
}
/**
* Callbacks interface that all activities using this fragment must implement.
*/
public interface NavigationDrawerCallbacks {
/**
* Called when an item in the navigation drawer is selected.
*/
void onNavigationDrawerItemSelected(int position);
}
}
Here is the code of the activity that I am trying to start.
package com.mycompany.p2pwifi;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WpsInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.example.fileexplorer.FileChooser;
import java.util.ArrayList;
import java.util.List;
public class p2p_main extends FragmentActivity {
ListView listView;
private final IntentFilter intentFilter = new IntentFilter();
WifiP2pManager.Channel mChannel;
WifiP2pManager mManager;
WiFiDirectBroadcastReceiver mReceiver;
boolean wifiP2pEnabled;
private List peers = new ArrayList();
private ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.list);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(this, getMainLooper(), null);
mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);
peers = mReceiver.get_peers();
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1, peers);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
connect(position);
}
});
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(mReceiver, intentFilter);
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Log.d("wifi", "onsuccess");
}
#Override
public void onFailure(int reason) {
Log.d("wifi", "onfailure");
}
});
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mReceiver);
}
#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);
}
public void setIsWifiP2pEnabled(boolean s){
wifiP2pEnabled = s;
}
public boolean isWifiP2pEnabled(){
return wifiP2pEnabled;
}
/*public void discover_peers(View view) {
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Log.d("wifi", "onsuccess");
}
#Override
public void onFailure(int reason) {
Log.d("wifi", "onfailure");
}
});
}*/
public void update_list() {
this.adapter.notifyDataSetChanged();
}
public void connect(int position) {
WifiP2pDevice device = (WifiP2pDevice) peers.get(position);
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.deviceAddress;
config.wps.setup = WpsInfo.PBC;
mManager.connect(mChannel, config, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
/*Intent intent = new Intent(this.getActivity(), FileChooser.class);
String
startActivity(intent);*/
}
#Override
public void onFailure(int reason) {
Log.d("connect", "Failed to connect to device.");
}
});
}
public void start_explorer(){
Intent file_explorer = new Intent(getApplicationContext(), FileChooser.class);
startActivity(file_explorer);
}
}
This is the activity_main.xml for the main activity (navigation drawer)
<!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. -->
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="#+id/drawer_layout"
android:layout_width="match_parent" android:layout_height="match_parent"
tools:context=".MainActivity">
<!-- As the main content view, the view below consumes the entire
space available using match_parent in both dimensions. -->
<FrameLayout android:id="#+id/container" android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- android:layout_gravity="start" tells DrawerLayout to treat
this as a sliding drawer on the left side for left-to-right
languages and on the right side for right-to-left languages.
If you're not building against API 17 or higher, use
android:layout_gravity="left" instead. -->
<!-- The drawer is given a fixed width in dp and extends the full height of
the container. -->
<fragment android:id="#+id/navigation_drawer"
android:layout_width="#dimen/navigation_drawer_width" android:layout_height="match_parent"
android:layout_gravity="start" android:name="com.jonny.nav.NavigationDrawerFragment"
tools:layout="#layout/fragment_navigation_drawer" />
</android.support.v4.widget.DrawerLayout>
This is the activity_main.xml for the project that contains p2p_main
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:orientation="vertical"
tools:context=".p2p_main">
<!--<Button android:layout_height="wrap_content"
android:layout_width="wrap_co1ntent"
android:text="#string/discover_peers"
android:onClick="discover_peers"
android:layout_gravity="left" />-->
<ListView
android:id="#+id/list"
android:layout_height="wrap_content"
android:layout_width="match_parent">
</ListView>
</LinearLayout>

Failed to inflate android.view.InflateException: Binary XML file line #24: Error inflating class fragment

I want to modify the navigation drawer of my app. It should have separators like the GMail app (an example: http://static.androidnext.de/gmail-google-mail-app-4-5-screenshots.png).
Java code (NavigationDrawerFragment.java) looks like this:
import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
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.ListView;
import android.widget.Toast;
/**
* Fragment used for managing interactions for and presentation of a navigation drawer.
* See the <a href="https://developer.android.com/design/patterns/navigation-drawer.html#Interaction">
* design guidelines</a> for a complete explanation of the behaviors implemented here.
*/
public class NavigationDrawerFragment extends Fragment {
/**
* Remember the position of the selected item.
*/
private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
/**
* Per the design guidelines, you should show the drawer on launch until the user manually
* expands it. This shared preference tracks this.
*/
private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
/**
* A pointer to the current callbacks instance (the Activity).
*/
private NavigationDrawerCallbacks mCallbacks;
/**
* Helper component that ties the action bar to the navigation drawer.
*/
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private ListView myDrawerListView;
private View mFragmentContainerView;
private int mCurrentSelectedPosition = 0;
private boolean mFromSavedInstanceState;
private boolean mUserLearnedDrawer;
public NavigationDrawerFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Read in the flag indicating whether or not the user has demonstrated awareness of the
// drawer. See PREF_USER_LEARNED_DRAWER for details.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
if(savedInstanceState != null) {
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
mFromSavedInstanceState = true;
}
// Select either the default item (0) or the last selected item.
selectItem(mCurrentSelectedPosition);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Indicate that this fragment would like to influence the set of actions in the action bar.
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
myDrawerListView = (ListView) inflater.inflate(
R.layout.fragment_navigation_drawer, container, false);
myDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
});
String[] item_names = {"Item 123", "Item 345"};
Integer[] item_images = {R.drawable.ic_launcher, R.drawable.ic_launcher};
CustomList adapter = new CustomList(getActivity(), item_names, item_images);
LayoutInflater lf = getActivity().getLayoutInflater();
View view = lf.inflate(R.layout.activity_my, container, false);
myDrawerListView = (ListView) view.findViewById(R.id.lv);
myDrawerListView.setAdapter(adapter);
myDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
MyActivity.switchFragment(position, getActivity().getApplicationContext());
}
});
myDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
return myDrawerListView;
}
public boolean isDrawerOpen() {
return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView);
}
/**
* Users of this fragment must call this method to set up the navigation drawer interactions.
*
* #param fragmentId The android:id of this fragment in its activity's layout.
* #param drawerLayout The DrawerLayout containing this fragment's UI.
*/
public void setUp(int fragmentId, DrawerLayout drawerLayout) {
mFragmentContainerView = getActivity().findViewById(fragmentId);
mDrawerLayout = drawerLayout;
// set a custom shadow that overlays the main content when the drawer opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// set up the drawer's list view with items and click listener
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the navigation drawer and the action bar app icon.
mDrawerToggle = new ActionBarDrawerToggle(
getActivity(), /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.navigation_drawer_open, /* "open drawer" description for accessibility */
R.string.navigation_drawer_close /* "close drawer" description for accessibility */
) {
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
if(!isAdded()) {
return;
}
getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
if(!isAdded()) {
return;
}
if(!mUserLearnedDrawer) {
// The user manually opened the drawer; store this flag to prevent auto-showing
// the navigation drawer automatically in the future.
mUserLearnedDrawer = true;
SharedPreferences sp = PreferenceManager
.getDefaultSharedPreferences(getActivity());
sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
}
getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
};
// If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,
// per the navigation drawer design guidelines.
if(!mUserLearnedDrawer && !mFromSavedInstanceState) {
mDrawerLayout.openDrawer(mFragmentContainerView);
}
// Defer code dependent on restoration of previous instance state.
mDrawerLayout.post(new Runnable() {
#Override
public void run() {
mDrawerToggle.syncState();
}
});
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
private void selectItem(int position) {
mCurrentSelectedPosition = position;
if(myDrawerListView != null) {
myDrawerListView.setItemChecked(position, true);
}
if(mDrawerLayout != null) {
mDrawerLayout.closeDrawer(mFragmentContainerView);
}
if(mCallbacks != null) {
mCallbacks.onNavigationDrawerItemSelected(position);
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallbacks = (NavigationDrawerCallbacks) activity;
} catch(ClassCastException e) {
throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
}
}
#Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Forward the new configuration the drawer toggle component.
mDrawerToggle.onConfigurationChanged(newConfig);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// If the drawer is open, show the global app actions in the action bar. See also
// showGlobalContextActionBar, which controls the top-left area of the action bar.
if(mDrawerLayout != null && isDrawerOpen()) {
inflater.inflate(R.menu.global, menu);
showGlobalContextActionBar();
}
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
if(item.getItemId() == R.id.action_example) {
Toast.makeText(getActivity(), "Example action.", Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Per the navigation drawer design guidelines, updates the action bar to show the global app
* 'context', rather than just what's in the current screen.
*/
private void showGlobalContextActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setTitle(R.string.app_name);
}
private ActionBar getActionBar() {
return getActivity().getActionBar();
}
/**
* Callbacks interface that all activities using this fragment must implement.
*/
public static interface NavigationDrawerCallbacks {
/**
* Called when an item in the navigation drawer is selected.
*/
void onNavigationDrawerItemSelected(int position);
}
}
MyActivity.java:
import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.support.v4.widget.DrawerLayout;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MyActivity extends Activity
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in {#link #restoreActionBar()}.
*/
private CharSequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
mNavigationDrawerFragment = (NavigationDrawerFragment) getFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, PlaceholderFragment.newInstance(position + 1))
.commit();
}
public void onSectionAttached(int number) {
switch(number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
}
}
public static void switchFragment(int i, Context context) {
switch(i) {
case 0:
//mTitle = "Case 0";
Toast.makeText(context, "Case 0", Toast.LENGTH_SHORT)
.show();
break;
case 1:
// mTitle = "Case 1";
Toast.makeText(context, "Case 1", Toast.LENGTH_SHORT)
.show();
break;
case 2:
// mTitle = "Case 2";
Toast.makeText(context, "Case 2", Toast.LENGTH_SHORT)
.show();
break;
}
}
public void restoreActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if(!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.my, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
#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(id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_my, container, false);
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MyActivity) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
}
}
activity_my.xml (only layout file with at least 24 lines at it is mentioned in the error):
<!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. -->
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MyActivity">
<!-- As the main content view, the view below consumes the entire
space available using match_parent in both dimensions. -->
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- android:layout_gravity="start" tells DrawerLayout to treat
this as a sliding drawer on the left side for left-to-right
languages and on the right side for right-to-left languages.
If you're not building against API 17 or higher, use
android:layout_gravity="left" instead. -->
<!-- The drawer is given a fixed width in dp and extends the full height of
the container. -->
<fragment
android:id="#+id/navigation_drawer"
android:layout_width="#dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:name="at.myapp.myapp.NavigationDrawerFragment"
tools:layout="#layout/fragment_navigation_drawer" />
<ListView
android:id="#+id/lv"
android:layout_height="wrap_content"
android:layout_width="wrap_content" >
</ListView>
</android.support.v4.widget.DrawerLayout>
And that's the error I receive (line 24 is the beginning of the fragment in the xml file):
> Failed to inflate
android.view.InflateException: Binary XML file line #24: Error inflating class fragment
And a few lines later:
Caused by: java.lang.IllegalArgumentException: Binary XML file line #24: Duplicate id 0x7f090002, tag null, or parent id 0x7f090000 with another fragment
Do you have any ideas?
Try changing
import android.app.Fragment;
to
import android.support.v4.app.Fragment;
Also make sure that your activity extends FragmentActivity instead of the regular Activity.
Use
import android.support.v4.app.FragmentActivity;
to get the FragmentActivity class.
Also see
Error inflating class fragment
Grigori A's answer has some useful pointers.

FragmentTransaction addToBackStack fragments get recreated on orientation changes

i found a weird behavior when using FragmentTransaction addToBackStack. Anytime the phone gets rotated, it recreates all fragments in stack.. Why should those fragments be recreated, aren't they supposed to be onPause? i mean.. they are not visible nor running any background thread..
I provide a simple example (just a basic navigation drawer template in Android Studio) where you can check this behavior. just navigate a few times to other fragments so that some fragments get stored in the stack, then rotate the device, onCreate gets fired as many times you have navigated.
MainActivity.java
package gsrtc_driver.example.com.supportfragmentmanager_orientationchanges;
import android.app.Activity;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.support.v4.widget.DrawerLayout;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class MyActivity extends ActionBarActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
private final static String DEBUG_TAG = "DEBUG_TAG";
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in {#link #restoreActionBar()}.
*/
private CharSequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, PlaceholderFragment.newInstance(position + 1))
.addToBackStack(String.valueOf(position + 1))
.commit();
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
}
}
public void restoreActionBar() {
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.my, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
#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 (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_my, container, false);
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MyActivity) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
Log.d(DEBUG_TAG, getClass().getSimpleName()+"::onAttach raised" );
}
}
}
NavigationDrawerFragment.java
package gsrtc_driver.example.com.supportfragmentmanager_orientationchanges;
import android.support.v7.app.ActionBarActivity;
import android.app.Activity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceManager;
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.Toast;
/**
* Fragment used for managing interactions for and presentation of a navigation drawer.
* See the <a href="https://developer.android.com/design/patterns/navigation-drawer.html#Interaction">
* design guidelines</a> for a complete explanation of the behaviors implemented here.
*/
public class NavigationDrawerFragment extends Fragment {
/**
* Remember the position of the selected item.
*/
private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
/**
* Per the design guidelines, you should show the drawer on launch until the user manually
* expands it. This shared preference tracks this.
*/
private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
/**
* A pointer to the current callbacks instance (the Activity).
*/
private NavigationDrawerCallbacks mCallbacks;
/**
* Helper component that ties the action bar to the navigation drawer.
*/
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private ListView mDrawerListView;
private View mFragmentContainerView;
private int mCurrentSelectedPosition = 0;
private boolean mFromSavedInstanceState;
private boolean mUserLearnedDrawer;
public NavigationDrawerFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Read in the flag indicating whether or not the user has demonstrated awareness of the
// drawer. See PREF_USER_LEARNED_DRAWER for details.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
if (savedInstanceState != null) {
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
mFromSavedInstanceState = true;
}
// Select either the default item (0) or the last selected item.
selectItem(mCurrentSelectedPosition);
}
#Override
public void onActivityCreated (Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Indicate that this fragment would like to influence the set of actions in the action bar.
setHasOptionsMenu(true);
}
#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);
}
});
mDrawerListView.setAdapter(new ArrayAdapter<String>(
getActionBar().getThemedContext(),
android.R.layout.simple_list_item_1,
android.R.id.text1,
new String[]{
getString(R.string.title_section1),
getString(R.string.title_section2),
getString(R.string.title_section3),
}));
mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
return mDrawerListView;
}
public boolean isDrawerOpen() {
return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView);
}
/**
* Users of this fragment must call this method to set up the navigation drawer interactions.
*
* #param fragmentId The android:id of this fragment in its activity's layout.
* #param drawerLayout The DrawerLayout containing this fragment's UI.
*/
public void setUp(int fragmentId, DrawerLayout drawerLayout) {
mFragmentContainerView = getActivity().findViewById(fragmentId);
mDrawerLayout = drawerLayout;
// set a custom shadow that overlays the main content when the drawer opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// set up the drawer's list view with items and click listener
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the navigation drawer and the action bar app icon.
mDrawerToggle = new ActionBarDrawerToggle(
getActivity(), /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.navigation_drawer_open, /* "open drawer" description for accessibility */
R.string.navigation_drawer_close /* "close drawer" description for accessibility */
) {
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
if (!isAdded()) {
return;
}
getActivity().supportInvalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
if (!isAdded()) {
return;
}
if (!mUserLearnedDrawer) {
// The user manually opened the drawer; store this flag to prevent auto-showing
// the navigation drawer automatically in the future.
mUserLearnedDrawer = true;
SharedPreferences sp = PreferenceManager
.getDefaultSharedPreferences(getActivity());
sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).commit();
}
getActivity().supportInvalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
};
// If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,
// per the navigation drawer design guidelines.
if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
mDrawerLayout.openDrawer(mFragmentContainerView);
}
// Defer code dependent on restoration of previous instance state.
mDrawerLayout.post(new Runnable() {
#Override
public void run() {
mDrawerToggle.syncState();
}
});
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
private void selectItem(int position) {
mCurrentSelectedPosition = position;
if (mDrawerListView != null) {
mDrawerListView.setItemChecked(position, true);
}
if (mDrawerLayout != null) {
mDrawerLayout.closeDrawer(mFragmentContainerView);
}
if (mCallbacks != null) {
mCallbacks.onNavigationDrawerItemSelected(position);
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallbacks = (NavigationDrawerCallbacks) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
}
}
#Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Forward the new configuration the drawer toggle component.
mDrawerToggle.onConfigurationChanged(newConfig);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// If the drawer is open, show the global app actions in the action bar. See also
// showGlobalContextActionBar, which controls the top-left area of the action bar.
if (mDrawerLayout != null && isDrawerOpen()) {
inflater.inflate(R.menu.global, menu);
showGlobalContextActionBar();
}
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
if (item.getItemId() == R.id.action_example) {
Toast.makeText(getActivity(), "Example action.", Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Per the navigation drawer design guidelines, updates the action bar to show the global app
* 'context', rather than just what's in the current screen.
*/
private void showGlobalContextActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setTitle(R.string.app_name);
}
private ActionBar getActionBar() {
return ((ActionBarActivity) getActivity()).getSupportActionBar();
}
/**
* Callbacks interface that all activities using this fragment must implement.
*/
public static interface NavigationDrawerCallbacks {
/**
* Called when an item in the navigation drawer is selected.
*/
void onNavigationDrawerItemSelected(int position);
}
}
activity_my.xml
<!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. -->
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MyActivity">
<!-- As the main content view, the view below consumes the entire
space available using match_parent in both dimensions. -->
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- android:layout_gravity="start" tells DrawerLayout to treat
this as a sliding drawer on the left side for left-to-right
languages and on the right side for right-to-left languages.
If you're not building against API 17 or higher, use
android:layout_gravity="left" instead. -->
<!-- The drawer is given a fixed width in dp and extends the full height of
the container. -->
<fragment android:id="#+id/navigation_drawer"
android:layout_width="#dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:name="gsrtc_driver.example.com.supportfragmentmanager_orientationchanges.NavigationDrawerFragment"
tools:layout="#layout/fragment_navigation_drawer" />
</android.support.v4.widget.DrawerLayout>
fragment_my.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MyActivity$PlaceholderFragment">
<TextView
android:id="#+id/section_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
fragment_navigation_drawer.xml
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#cccc"
tools:context=".NavigationDrawerFragment" />
Is this the expected behaviour, how could i avoid the fragment in the stack to be recreated?
sample source here http://www.filedropper.com/supportfragmentmanagerorientationchanges
I allow myself to write my comment as an answer as it solved your problem.
As I mentioned I didn't try your code, however checking one of my codes showed that I don't use the onCreate method but only the onCreateView
I put all the code required in the onCreate only in the onCreateView.
For explaining why it solves your problem you have to refer to the details about the life cycle of a fragment. I don't remember exactly all the details, but what I know is that all the examples given by the Android developer site when talking about fragments use onCreateView and not onCreate.
For me, as far as I know, it is the way to proceed when using fragments and I do it that way in all my codes.
Then to have the view attached on screen rotation use onActivityCreated.
EDIT
To answer or complete the comment of #Xabier I should add that onCreate is replaced by onCreateView, and in my case I usually use it only to inflate the layout.
Then, if your view is static you can use onViewCreated. However if your view is dynamic and for example you have listviews, you have to use onActivityCreated.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_layout, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mListView = (ListView) getView().findViewById(R.id.listview);
mAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_activated_1, a_string_array);
mListView.setAdapter(mAdapter);
mListView.setOnItemClickListener(this);
...
}

Categories

Resources