Fragment crashes on orientation change - android

Every time orientation changes Fragment crashes with error:
01-26 12:46:43.215 2895-2895/com.cbsystematic.mobile.itvdn
E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.cbsystematic.mobile.itvdn, PID: 2895
java.lang.RuntimeException: Unable to destroy activity {com.cbsystematic.mobile.itvdn/com.cbsystematic.mobile.itvdn.NavigationActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3671)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3689)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3889)
at android.app.ActivityThread.access$900(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1365)
at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:516)
at com.cbsystematic.mobile.itvdn.LessonsFragment.replaceFragment(LessonsFragment.java:126)
at com.cbsystematic.mobile.itvdn.LessonsFragment.onDetach(LessonsFragment.java:119)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1080)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1126)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1108)
at android.support.v4.app.FragmentManagerImpl.dispatchDestroy(FragmentManager.java:1954)
at android.support.v4.app.FragmentActivity.onDestroy(FragmentActivity.java:313)
at android.support.v7.app.ActionBarActivity.onDestroy(ActionBarActivity.java:169)
at android.app.Activity.performDestroy(Activity.java:6112)
at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1140)
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3658)
            at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3689)
            at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3889)
            at android.app.ActivityThread.access$900(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
I need to save state of current Fragment.
Fragment class code:
public class LessonsFragment extends Fragment implements AbsListView.OnItemClickListener {
private OnFragmentInteractionListener mListener;
/**
* The fragment's ListView.
*/
private AbsListView mListView;
/**
* The Adapter which will be used to populate the ListView/GridView with
* Views.
*/
private ListAdapter mAdapter;
private static String courseUrl;
private ParserJson parserJson = new ParserJson();
private TextView descriptionTextView;
private DescriptionData descriptionData;
// TODO: Rename and change types of parameters
public static LessonsFragment newInstance(String url) {
LessonsFragment fragment = new LessonsFragment();
courseUrl = url;
return fragment;
}
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public LessonsFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO: Change Adapter to display your content
mAdapter = new LessonsItemAdapter(getActivity(),
R.layout.lessons_list_item, parserJson.getLessons(courseUrl).getLessonsArray());
descriptionData = parserJson.getLessons(courseUrl).getDescriptionData();
}
// #Override
// public void onSaveInstanceState(Bundle outState) {
// //No call for super(). Bug on API Level > 11.
// }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_lessons_list, container, false);
descriptionTextView = (TextView) view.findViewById(R.id.lessons_description);
descriptionTextView.setText("Описание курса:\n" +
descriptionData.getShortDescription());
// Set the adapter
mListView = (AbsListView) view.findViewById(android.R.id.list);
((AdapterView<ListAdapter>) mListView).setAdapter(mAdapter);
// Set OnItemClickListener so we can be notified on item clicks
mListView.setOnItemClickListener(this);
return view;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
//this occurs when we move out of this Fragment
replaceFragment(CatalogFragment.newInstance(1));
}
private void replaceFragment (Fragment fragment){
String backStateName = fragment.getClass().getName();
String fragmentTag = backStateName;
boolean fragmentPopped = getFragmentManager().popBackStackImmediate (backStateName, 0);
if (!fragmentPopped && getFragmentManager().findFragmentByTag(fragmentTag) == null){ //fragment not in back stack, create it.
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.container, fragment, fragmentTag);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(backStateName);
ft.commit();
}
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (null != mListener) {
mListener.onLessonFragmentInteraction(parserJson.getLessons(courseUrl).getLessonsArray().get(position).getId());
}
}
/**
* 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 {
// TODO: Update argument type and name
public void onLessonFragmentInteraction(String id);
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".AuthorizationActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".NavigationActivity"
android:parentActivityName="com.cbsystematic.mobile.itvdn.AuthorizationActivity" >
<!-- The meta-data element is needed for versions lower than 4.1 -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.cbsystematic.mobile.itvdn.AuthorizationActivity" />
>
</activity>
</application>
Fragment's layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragment_lessons"
android:background="#FAF9F9"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.cbsystematic.mobile.itvdn.LessonsFragment">
<TextView
android:id="#+id/lessons_description"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#acacac" />
<ListView android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/lessons_description"/>
I know that such problems are like pain in the neck. But please give your assumptions.
Will appreciate any help.

It crashes because the fragment gets recreated everytime you change the orientation.
Add this line to your activity in the manifest:
android:configChanges="keyboardHidden|orientation|screenSize"

Related

Null TextView object in a fragment

I'm working on dynamically setting a text of TextView in a fragment called 'ChallengeFragment' by creating a method that sets the text. Then, I call the method in FragmentActivity class to update the TextView. However, I am getting error that TextView object is null when the method is called. I am not sure why TextView is null.
Here's the logcat message:
16:36:02.437 4072-4072/eie.android.crunch E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: eie.android.crunch, PID: 4072
java.lang.RuntimeException: Unable to start activity ComponentInfo{eie.android.crunch/eie.android.crunch.ChallengePage}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at eie.android.crunch.ChallengeFragment.setNameText(ChallengeFragment.java:76)
at eie.android.crunch.ChallengePage.onCreate(ChallengePage.java:50)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
            at android.app.ActivityThread.access$800(ActivityThread.java:151)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Here is the Fragment class (ChallengeFragment.java):
public class ChallengeFragment extends Fragment {
private Activity mActivity;
private TextView nameText;
private Handler handler =new Handler();
public ChallengeFragment() {
}
public void onAttach(Activity activity) {
super.onAttach(activity);
mActivity = activity;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LayoutInflater lf = getActivity().getLayoutInflater();
View v = lf.inflate(R.layout.fragment_challenge, null);
nameText = (TextView) v.findViewById(R.id.user_name_text_view);
....
return v;
}
public void setNameText(String s) {
nameText.setText(s);
}
public TextView getNameText() {
return nameText;
}
}
And this is the code for FragmentActivity that updates the text of TextView (ChallengePage.java):
public class ChallengePage extends FragmentActivity {
private FriendChallengeFragment initialFriendHabit;
private ChallengeFragment friendHabit;
private ChallengeFragment myHabit;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_challenge);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
myHabit = new ChallengeFragment();
initialFriendHabit = new FriendChallengeFragment();
myHabit.onAttach(ChallengePage.this);
initialFriendHabit.onAttach(ChallengePage.this);
fragmentTransaction
.replace(R.id.my_habit, myHabit ,"fragment_top")
.replace(R.id.friend_habit, initialFriendHabit, "fragment_bottom")
.commit();
Intent intent = getIntent();
String challengedUsername = intent.getStringExtra("username");
if(challengedUsername != null) {
friendHabit = new ChallengeFragment();
friendHabit.onAttach(ChallengePage.this);
fragmentTransaction.replace(R.id.friend_habit, friendHabit, "fragment_bottom");
friendHabit.setNameText(challengedUsername);
}
}
}
And this is the layout file that contains the fragment (fragment_challenge.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:id="#+id/user_name_text_view"
android:layout_gravity="center_horizontal"
android:text="User Name"
android:textSize="30dp"
android:layout_marginTop="30dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:id="#+id/habit_name_text"
android:layout_gravity="center_horizontal"
android:text="Habit Name"
android:textSize="40dp"
android:layout_marginTop="20dp"/>
<ProgressBar
android:layout_height="wrap_content"
android:layout_width="312dp"
style="#android:style/Widget.ProgressBar.Horizontal"
android:id="#+id/progressBar"
android:layout_marginTop="50dp"
android:layout_gravity="center_horizontal"/>
</LinearLayout>
I've looked at other stackoverflow questions relating to this but could not find answers.
The problem is your fragment's setNameText() method is called before onCreateView() has run, so your TextView has not been initialized yet. You have to wait until later to set the name text.
If you always have the name text when you are creating and adding the fragment, then it's better to pass that as an argument to the fragment and have it set the text of the TextView at the appropriate time. Something like this:
public class ChallengeFragment extends Fragment {
public static ChallengeFragment newInstance(String name) {
ChallengeFragment fragment = new ChallengeFragment();
Bundle args = new Bundle();
args.putString("username", name);
fragment.setArguments(args);
return fragment;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
Bundle args = getArguments();
if (args != null) {
String name = args.getString("username");
nameText.setText(name);
}
}
// everything else
}
A few things to note:
Do not create a constructor. Fragments need to have a default (no argument) constructor so that Android can instantiate them. This newInstance pattern is typically regarded as the best practice.
Use onActivityCreated because at that time you know the Activity is created and that the fragment's view hierarchy has been created.
Fragment arguments persist across configuration changes, so you shouldn't need to do anything special for that.
Also, you should not be calling onAttach() yourself, that's a lifecycle method that the OS calls on your fragment.

Unable to attach Fragment to activity through XML

I created a new activity by right clicking on my project and selecting new > fragment > blank fragment.
Here is the auto generated fragment. The only thing I added was the lines under the onCreateView() method. I also implemented onFragmentInteractionListener on the activity that I want to attatch this fragment to. I made sure to implement the onFragmentInteraction(...) method on that Activity, but left it blank.
Whats the problem here?
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.support.v4.app.Fragment;
public class FragmentHowToPlay extends Fragment {
// 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 OnFragmentInteractionListener mListener;
/**
* 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 FragmentHowToPlay.
*/
// TODO: Rename and change types and number of parameters
public static FragmentHowToPlay newInstance(String param1, String param2) {
FragmentHowToPlay fragment = new FragmentHowToPlay();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public FragmentHowToPlay() {
// Required empty public constructor
}
#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
View v = inflater.inflate(R.layout.fragment_fragment_how_to_play, container, false);
TextView text1 = (TextView) v.findViewById(R.id.text1);
text1.setText(Html.fromHtml(getString(R.string.my_text)));
return v;
}
// 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(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.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 {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
}
Here is the logcat error:
Process: mjj.fling, PID: 8965
java.lang.RuntimeException: Unable to start activity ComponentInfo{mjj.fling/mjj.fling.HowToPlayActivity}: android.view.InflateException: Binary XML file line #19: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2441)
at android.app.ActivityThread.access$800(ActivityThread.java:162)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1349)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5431)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:913)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:706)
Caused by: android.view.InflateException: Binary XML file line #19: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:763)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:809)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:402)
at android.app.Activity.setContentView(Activity.java:2214)
at mjj.fling.HowToPlayActivity.onCreate(HowToPlayActivity.java:16)
at android.app.Activity.performCreate(Activity.java:6093)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
Caused by: android.app.Fragment$InstantiationException: Trying to instantiate a class mjj.fling.FragmentHowToPlay that is not a Fragment
at android.app.Fragment.instantiate(Fragment.java:606)
at android.app.Fragment.instantiate(Fragment.java:582)
at android.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2108)
at android.app.Activity.onCreateView(Activity.java:5431)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733)
Caused by: java.lang.ClassCastException
XML LAYOUT for Activity that Fragment is being attached to
<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="mjj.fling.HowToPlayActivity"
android:background="#01051D">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scrollView"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="42dp" >
<fragment
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:name="mjj.fling.FragmentHowToPlay"
android:id="#+id/fragment"
tools:layout="#layout/fragment_fragment_how_to_play" />
</ScrollView>
You fragment extends android.support.v4.app.Fragment instead of android.app.Fragment -- see the import declaration. The former is meant to be used by FragmentActivity (or better yet the new AppCompatActivity) from the support library, not with regular android.app.Activity. You need to change one or the other and in general be consistent about what you are using throughout the app.

Android studio, XML Inflation error on main activity creation android.view.InflateException

Hours have gone by and i still can't get round this really frustrating error.
i'm new to android programming so i'm pretty much following tutorials and trying to understand them as i move along. i've also tryed different approaches but keep getting the same error.
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.testapp.scott.mpt/com.testapp.scott.mpt.MyActivity}: android.view.InflateException: Binary XML file line #34: Error inflating class fragment
Here's my Fragment Layout (I'm using a shape as a background button. that's not the problem because i've tryed removing it and nothing changed...)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="match_parent"
tools:context="com.testapp.scott.mpt.MainToolbarFrag"
android:background="#ff434343">
<Button
android:layout_width="96dp"
android:layout_height="fill_parent"
android:text="My desk"
android:id="#+id/BT_Toolbar_MyDesk"
android:background="#drawable/toolbar_buttonbk"
android:textSize="18sp" />
<Button
android:layout_width="96dp"
android:layout_height="fill_parent"
android:text="Exercises"
android:id="#+id/BT_Toolbar_Exercises"
android:background="#drawable/toolbar_buttonbk"
android:layout_gravity="left"
android:textSize="18sp" />
<Button
android:layout_width="96dp"
android:layout_height="fill_parent"
android:text="My\nProfile"
android:id="#+id/BT_Toolbar_MyProfile"
android:background="#drawable/toolbar_buttonbk"
android:layout_gravity="left"
android:textSize="18sp" />
<Button
android:layout_width="96dp"
android:layout_height="fill_parent"
android:text="Extras"
android:id="#+id/BT_Toolbar_Extras"
android:background="#drawable/toolbar_buttonbk"
android:layout_gravity="left"
android:textSize="18sp" />
</LinearLayout>
The activity in which i would want the fragment to be displayed:
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MyActivity"
tools:ignore="MergeRootFrame" >
<Space
android:layout_width="fill_parent"
android:layout_height="20dp"
android:layout_row="0"
android:layout_column="0"
android:id="#+id/Space0" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="#string/main_welcome"
android:id="#+id/TV_Main_Welcome"
android:layout_row="1"
android:layout_column="0"
android:textAlignment="center"
android:singleLine="true"
android:password="false"
android:inputType="none"
android:gravity="center"
android:textStyle="italic"
android:layout_gravity="left|top" />
<fragment
android:layout_width="wrap_content"
android:layout_height="74dp"
class="com.testapp.scott.mpt.MainToolbarFrag"
android:id="#+id/fragment"
android:layout_row="30"
android:layout_column="0"
tools:layout="#layout/fragment_maintoolbar" />
My Fragment Java Class:
package com.testapp.scott.mpt;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link MainToolbarFrag.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {#link MainToolbarFrag#newInstance} factory method to
* create an instance of this fragment.
*
*/
public class MainToolbarFrag extends Fragment {
// 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 OnFragmentInteractionListener mListener;
/**
* 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 MainToolbarFrag.
*/
// TODO: Rename and change types and number of parameters
public static MainToolbarFrag newInstance(String param1, String param2) {
MainToolbarFrag fragment = new MainToolbarFrag();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public MainToolbarFrag() {
// Required empty public constructor
}
#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
return inflater.inflate(R.layout.fragment_maintoolbar, container, false);
}
// 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(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.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 {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
}
And my main Activity class:
package com.testapp.scott.mpt;
import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import com.testapp.scott.mpt.MyClasses.Constants;
import com.testapp.scott.mpt.MyClasses.Exercises;
import com.testapp.scott.mpt.MyClasses.UserData;
import com.testapp.scott.mpt.MyClasses.deskData;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
public class MyActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.my, 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();
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 {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_my, container, false);
return rootView;
}
}
}
And FInally this is my Log:
10-13 20:51:54.974 1678-1678/com.testapp.scott.mpt D/dalvikvm﹕ Late-enabling CheckJNI
10-13 20:51:54.994 1678-1684/com.testapp.scott.mpt D/dalvikvm﹕ Debugger has detached; object registry had 1 entries
10-13 20:51:55.074 1678-1678/com.testapp.scott.mpt D/AndroidRuntime﹕ Shutting down VM
10-13 20:51:55.074 1678-1678/com.testapp.scott.mpt W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x41941d88)
10-13 20:51:55.074 1678-1678/com.testapp.scott.mpt E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.testapp.scott.mpt, PID: 1678
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.testapp.scott.mpt/com.testapp.scott.mpt.MyActivity}: android.view.InflateException: Binary XML file line #34: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2237)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2286)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1246)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:212)
at android.app.ActivityThread.main(ActivityThread.java:5135)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:877)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.view.InflateException: Binary XML file line #34: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:297)
at android.app.Activity.setContentView(Activity.java:1929)
at com.testapp.scott.mpt.MyActivity.onCreate(MyActivity.java:32)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2201)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2286)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1246)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:212)
at android.app.ActivityThread.main(ActivityThread.java:5135)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:877)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassCastException: com.testapp.scott.mpt.MyActivity#44aea5d0 must implement OnFragmentInteractionListener
at com.testapp.scott.mpt.MainToolbarFrag.onAttach(MainToolbarFrag.java:84)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:853)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1044)
at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1146)
at android.app.Activity.onCreateView(Activity.java:4786)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:689)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:297)
at android.app.Activity.setContentView(Activity.java:1929)
at com.testapp.scott.mpt.MyActivity.onCreate(MyActivity.java:32)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2201)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2286)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1246)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:212)
at android.app.ActivityThread.main(ActivityThread.java:5135)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:877)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
at dalvik.system.NativeStart.main(Native Method)
I've already fixed the missing implementation in my activity class.
The real problem here is the inflation error.
Thanks!
your problem is from these lines of code:
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
your activity must implement OnFragmentInteractionListener, but you do not implement that in your MyActivity.
There really is no point in answering questions if the answer doesn't reply to the question asked (Please note the last two lines of my question)...
That being said, i figured out how to solve the problem and for anyone having the same issue the problem resided in the fact that MyActivity was not pointing to the fragment in it's onCreate() Method.
i solved it by changing
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
}
in particular the line:
.add(R.id.container, new PlaceholderFragment())
to:
.add(R.id.container, new MainToolbarFrag())
where MainToolbarFrag() is the class of your fragment.

android.view.InflateException: Binary XML file line #9: Error inflating class fragment

There are a lot of articles pointing to the same error but none appeared to fix my problem. So I am posting it
I have a fragment layout below
<FrameLayout 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"
tools:context=".MyAppointmentFragment" >
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/fragment_text" />
</FrameLayout>
And the activity layout below
<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="horizontal"
android:baselineAligned="false"
tools:context=".IndexActivity"
>
<fragment
android:name="com.example.helloworld.MyAppointmentFragment"
android:id="#+id/myappointment_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
Below is the java source for the activity that is throwing this error
package com.example.helloworld;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
public class IndexActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_index);
}
}
package com.example.helloworld;
import android.app.Activity;
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;
/**
* A simple {#link android.support.v4.app.Fragment} subclass. Activities that
* contain this fragment must implement the
* {#link MyAppointmentFragment.OnFragmentInteractionListener} interface to
* handle interaction events. Use the {#link MyAppointmentFragment#newInstance}
* factory method to create an instance of this fragment.
*
*/
public class MyAppointmentFragment extends Fragment {
// 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 OnFragmentInteractionListener mListener;
/**
* 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 MyAppointmentFragment.
*/
// TODO: Rename and change types and number of parameters
public static MyAppointmentFragment newInstance(String param1, String param2) {
MyAppointmentFragment fragment = new MyAppointmentFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public MyAppointmentFragment() {
// Required empty public constructor
}
#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
return inflater.inflate(R.layout.fragment_my_appointment, container,
false);
}
// 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(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.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 {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
}
When launched in an emulator I get the following error
02-20 13:21:42.530: E/AndroidRuntime(1290): FATAL EXCEPTION: main
02-20 13:21:42.530: E/AndroidRuntime(1290): java.lang.RuntimeException: Unable to start
activity
ComponentInfo{com.example.helloworld/com.example.helloworld.IndexActivity}:
android.view.InflateException: Binary XML file line #9: Error inflating class fragment
02-20 13:21:42.530: E/AndroidRuntime(1290): at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
The Android version I am using is 4.3 and minSdkVersion="13" and targetSdkVersion="18"
I would appreciate any help to resolve this issue
Complete Stack Trace Below
FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.helloworld/com.example.helloworld.IndexActivity}: android.view.InflateException: Binary XML file line #9: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.view.InflateException: Binary XML file line #9: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:267)
at android.app.Activity.setContentView(Activity.java:1895)
at com.example.helloworld.IndexActivity.onCreate(IndexActivity.java:11)
at android.app.Activity.performCreate(Activity.java:5133)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
... 11 more
Caused by: java.lang.ClassCastException: com.example.helloworld.IndexActivity#4174c9f8 must implement OnFragmentInteractionListener
at com.example.helloworld.MyAppointmentFragment.onAttach(MyAppointmentFragment.java:85)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:883)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1082)
at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1184)
at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:285)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:685)
... 21 more
java.lang.ClassCastException: com.example.helloworld.IndexActivity#4174c9f8 must implement OnFragmentInteractionListener
Your IndexActivity class is supposed to implement some OnFragmentInteractionListener interface, and it does not.
My answer is quite late cause I also faced the same problem and no solution was working for me. If none of the other areas like onFragmentInteractionListener() have problem then check for
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
as this method is deprecated replace it with
public void onAttach(Context context) {
super.onAttach(context);
try {
mListener = (OnFragmentInteractionListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
Make sure you have a string named fragment_text
android:text="#string/fragment_text"
in your strings.xml file in the values folder. Even if you have, try doing a project 'clean' as well.

Android - SupportMapFragment with GoogleMaps API 2.0 giving IllegalArgumentException

I am trying to use the latest Map API 2.0 provided for Android. I am using the Support Library as I want to support Android 2.2. Following is my code:
Main Activity class
public class MainActivity extends FragmentActivity {
public FragmentManager fManager ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fManager = getSupportFragmentManager();
Button showMapButton = (Button) findViewById(R.id.showMapButton);
showMapButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
loadMapFragment();
}
});
}
private void loadMapFragment() {
MapPageFragment plotterFragment = new MapPageFragment();
FragmentTransaction ft = fManager.beginTransaction();
ft.replace(R.id.allFragmentsFrameLayout, plotterFragment);
ft.addToBackStack(null);
ft.commit();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
Main Activity layout file
<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"
tools:context=".MainActivity" >
<Button
android:id="#+id/showMapButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Show Map"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="30dp"
android:layout_alignParentTop="true" />
<FrameLayout
android:id="#+id/allFragmentsFrameLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentTop="true">
<!-- Put fragments dynamically -->
</FrameLayout>
</RelativeLayout>
Map Fragment Class
public class MapPageFragment extends SupportMapFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
return inflater.inflate(R.layout.map_fragment_layout, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
Map Fragment Layout
<?xml version="1.0" encoding="utf-8"?>
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
class="com.google.android.gms.maps.SupportMapFragment"
map:uiCompass="true"
map:mapType= "normal"
map:uiRotateGestures="true"
map:uiScrollGestures="true"
map:uiTiltGestures="true"
map:uiZoomControls="true"
map:uiZoomGestures="true" />
Android Manifest File
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mapfragmentexample"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
<permission
android:name="com.plotter.permission.MAPS_RECEIVE"
android:protectionLevel="signature"/>
<uses-permission android:name="com.plotter.permission.MAPS_RECEIVE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="AIzaSyA5FtIeLQ1gGUihZIZPQVi3Yz_0l4NG9PY"/>
</application>
</manifest>
Everything is working fine for the first time. i.e. When I click on the Show Map button the map fragment gets loaded and displays the map. When I press back button, the map fragment is unloaded and I can see the Show Map button again.
I face an issue when I press the Show Map button again. I get the following error:
FATAL EXCEPTION: main
android.view.InflateException: Binary XML file line #2: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:699)
at android.view.LayoutInflater.inflate(LayoutInflater.java:468)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at com.mapfragmentexample.MapPageFragment.onCreateView(MapPageFragment.java:17)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1460)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:911)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:429)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4503)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: Binary XML file line #2:
Duplicate id 0x7f040006, tag null, or parent id 0x0 with another fragment
for com.google.android.gms.maps.SupportMapFragment
at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:285)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:671)
... 18 more
I am not getting where I am getting wrong or missing anything.
You can fix this, if you delete all nested fragments in onDestroyView(). Don't know if it is a proper solution.
public void onDestroyView() {
super.onDestroyView();
Fragment fragment = (getFragmentManager().findFragmentById(R.id.map));
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
}
And inflating them as usual in onCreateView()
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.map, container, false);
}
You need to use getChildFragmentManager() to add SupportMapFragment not not through xml.
For "why", see official documentation: http://developer.android.com/about/versions/android-4.2.html#NestedFragments
Take a look at my answer here: https://stackoverflow.com/a/15512285/2183804
You cannot inflate a layout into a fragment when that layout includes a fragment. Nested fragments are only supported when added to a fragment dynamically. More detail here!
Used this solution (similar to others):
public void onDestroyView() {
FragmentManager fm = getActivity().getSupportFragmentManager();
Fragment fragment = (fm.findFragmentById(R.id.map));
if (fragment.isResumed()) {
FragmentTransaction ft = fm.beginTransaction();
ft.remove(fragment);
ft.commit();
}
super.onDestroyView();
}
I had problems before using the if (fragment.isResumed).
I was facing the same issue in JakeWhartonViewPagerIndicatore along with SherlockFragments. Here is sample TestFragment with solved issue, thanks to Natalia for providing above solution. Your fragment may be a little different from mine.
Reference: Making ActionBarSherlock and ViewPagerIndicator play nice
Good Luck..!!
package com.example.vpiabstest;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.actionbarsherlock.app.SherlockFragment;
public class TestFragment extends SherlockFragment {
private String mContent = "???";
private String text;
private static final String KEY_TAB_NUM = "key.tab.num";
public static TestFragment newInstance(String text) {
TestFragment fragment = new TestFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putString(KEY_TAB_NUM, text);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
text = getString(R.string.tab_page_num) + mContent;
View view = null;
if(text.contains("2")) {
view = inflater.inflate(R.layout.pinpoints_list, null);
} else if(text.contains("1")) {
view = inflater.inflate(R.layout.main_fragment_activity, null);
} else {
view = inflater.inflate(R.layout.activity_main, null);
((TextView)view.findViewById(R.id.text)).setText(text);
}
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContent = getArguments() != null ? getArguments().getString(KEY_TAB_NUM) : "???";
}
public void onDestroyView() {
super.onDestroyView();
// Your Programing skills goes here
if(text == null || !text.contains("1")) {
return;
}
// Do Not Miss this
try {
Fragment fragment = (getFragmentManager().findFragmentById(R.id.map_fragment));
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Use dialog.SetContentView() method in your activity's onCreate() cause when we tring to load.
Dialog again it loads only dialog not the whole activity life cycle and leads it to exception of Duplicate id.
Try it.
Try this
Maps fragment layout
<?xml version="1.0" encoding="utf-8"?>
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
map:uiCompass="true"
map:mapType= "normal"
map:uiRotateGestures="true"
map:uiScrollGestures="true"
map:uiTiltGestures="true"
map:uiZoomControls="true"
map:uiZoomGestures="true"
tools:context="the.package.name.of.mappagefragment.MapPageFragment" />
Map fragment class
public class MapPageFragment extends SupportMapFragment
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = super.onCreateView(inflater, container, savedInstanceState);
if (rootView == null)
{
rootView = inflater.inflate(R.layout.map_fragment_layout, container, false);
}
return rootView;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
}
}
I used Natalia response but at times broke the application.
Use this one and it worked perfectly without breaking.
#Override
public void onDestroyView() {
try{
FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
transaction.remove(nestedFragment);
transaction.commit();
}catch(Exception e){
}
super.onDestroyView();
}
https://stackoverflow.com/a/7953801/3364157
Fragment fragment = (getChildFragmentManager().findFragmentById(R.id.mapview));
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
Use this saves the day.
Use intent flags:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
when calling main activity.
I had the same problem. Try adding ...
android:name="com.mapfragmentexample.MapPageFragment"
... to fragment in the layout file!

Categories

Resources