java - Activity with fragment who can take two differents fragments and rotation of device -


i'm new android, java, ... , new fragment. have activity (a) shows list using fragment (b). selecting item of list, same fragment changed show lis using fragment (c). works except when rotate device while shows second list (c). when shown first list (b), if rotate device, works perfectly.

error logcat:

    04-26 11:30:32.769: e/androidruntime(2882): fatal exception: main     04-26 11:30:32.769: e/androidruntime(2882): java.lang.runtimeexception: unable start activity componentinfo{com.example.traffic/com.example.traffic.listtriplines}: android.support.v4.app.fragment$instantiationexception: unable instantiate fragment com.example.traffic.listpoints: make sure class name exists, public, , has empty constructor public (...)     04-26 11:30:32.769: e/androidruntime(2882): caused by: android.support.v4.app.fragment$instantiationexception: unable instantiate fragment com.example.traffic.listpoints: make sure class name exists, public, , has empty constructor public (...)     04-26 11:30:32.769: e/androidruntime(2882): caused by: java.lang.instantiationexception: com.example.traffic.listpoints 

activity (java + xml):

public class maina extends actionbaractivity {     @override     protected void oncreate(bundle savedinstancestate) {         super.oncreate(savedinstancestate);         setcontentview(r.layout.list_triplines);     }      @override     public void ontripselected(int cod) {         fragment pointsfragment = new listpoints(cod);         fragmenttransaction ftransaction = fmanager.begintransaction();         ftransaction.replace(r.id.trips_points_fragment, pointsfragment);         ftransaction.addtobackstack(null);         ftransaction.settransition(fragmenttransaction.transit_fragment_fade);         ftransaction.commit();     }      @override     public void onpointselected(int pos) {         //do stuff (using pos)         (...)     } }    <relativelayout xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent"     android:layout_height="match_parent"     >      <textview         android:id="@+id/main_title"         style="@style/helptitle"         android:text="@string/listtrips_title"         />      <fragment         android:id="@+id/trips_points_fragment"         android:name="com.example.traffic.fragmentb"         android:layout_width="match_parent"         android:layout_height="0dp"         android:layout_weight="1"         /> </relativelayout> 

fragment b (java + xml) :

(...) import android.support.v4.app.fragment; (...) public class fragmentb extends fragment {      private ontripselectedlistener tselected;     private static listtriplines listtriplines;     private context context;     private layoutinflater inflater;      @override     public void onattach(activity activity) {         super.onattach(activity);         //check che nell'activity sia implement il listener         try {             tselected = (ontripselectedlistener) activity;         } catch (classcastexception e) {             throw new classcastexception(activity.tostring() + " must implement ontripselectedlistener");         }          listtrips = (listtriplines) activity;         context = activity.getapplicationcontext();         inflater = layoutinflater.from(activity);     }      @override     public view oncreateview (layoutinflater inflater, viewgroup vg, bundle savedinstancestate) {         //inflate layout fragment         final view viewresult = inflater.inflate(r.layout.list_trips, vg, false);          listview_trips = (listview) viewresult.findviewbyid(r.id.trips_listview);          return viewresult;     }      @override     public void onactivitycreated(bundle savedinstancestate) {         super.onactivitycreated(savedinstancestate);          listadapter = new cursoradapter(...);          listview_trips.setadapter(listadapter);         listview_trips.setonitemclicklistener(onitemclicklistener);         listview_trips.setonitemlongclicklistener(onitemlongclicklistener);     }   public interface ontripselectedlistener {     public void ontripselected(int cod); }      private onitemclicklistener onitemclicklistener = new onitemclicklistener() {          @override         public void onitemclick(adapterview<?> av, view v, int pos, long id) {             tselected.ontripselected(id);         }      }; }    <linearlayout xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:orientation="vertical"     >     <expandablelistview         android:id="@+id/trips_explistview"         android:layout_width="match_parent"         android:layout_height="0dp"         android:layout_weight="1"         android:background="@color/gray"         /> </linearlayout> 

fragment c (java + xml) :

(...) import android.support.v4.app.fragment; (...) public fragmentc extends fragment {      private onpointselectedlistener plistener;     private static listtriplines listtrips;     private context context;     private int cod;      public listpoints (int _cod) {         this.cod = _cod;     }      @override     public void onattach(activity activity) {         super.onattach(activity);         try {             plistener = (onpointselectedlistener) activity;         } catch (classcastexception e) {             throw new classcastexception(activity.tostring() + " must implement onpointselectedlistener");         }          listtrips = (listtriplines) activity;         context = activity.getapplicationcontext(); inflater = layoutinflater.from(activity);     }      @override     public view oncreateview (layoutinflater inflater, viewgroup vg, bundle savedinstancestate) {         //inflate layout fragment         final view viewresult = inflater.inflate(r.layout.list_points, vg/*null*/, false);          listview_points = (listview) viewresult.findviewbyid(r.id.points_listview);          return viewresult;     }      @override     public void onactivitycreated(bundle savedinstancestate) {         super.onactivitycreated(savedinstancestate);          pointsadapter = new cursoradapter(...);         listview_points.setadapter(pointsadapter);         listview_points.setonitemclicklistener(onitemclicklistener);      }  public interface onpointselectedlistener {     public void onpointselected(int pos); }      private onitemclicklistener onitemclicklistener = new onitemclicklistener() {         @override         public void onitemclick(adapterview<?> av, view v, int pos, long id) {             plistener.onpointselected(pos);         }     };  }  <linearlayout xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:orientation="vertical"     >     <listview         android:id="@+id/points_listview"         android:layout_width="match_parent"         android:layout_height="0dp"         android:layout_weight="1" android:background="@color/gray"         /> </linearlayout> 

maybe problem because use 1 fragment show 2 different fragments ? in case, solve using 2 fragments , alternate 1 must shown (with visibility.gone) ?

thanks

edit: in xml main activity (a), changed fragment name -> fragmentb (i forgot change when posted question).

n.b: need uderline -> when activity (a) starts, loads fragmentb (b); select item , loads fragmentc (c); when rotate in xml there fragmentb (obviusly) while activity (a) must loads fragmentc (c). dont know if android can handle situation.


to solve:

1) logcat after ortsinton modification (creating empty constructor, , passing arguments "bundle") :

04-26 14:24:46.809: e/androidruntime(11558): fatal exception: main 04-26 14:24:46.809: e/androidruntime(11558): java.lang.runtimeexception: unable start activity componentinfo{com.example.traffic/com.example.traffic.listtriplines}: android.view.inflateexception: binary xml file line #23: error inflating class fragment 04-26 14:24:46.809: e/androidruntime(11558):    @ android.app.activitythread.performlaunchactivity(activitythread.java:1659) (...) 04-26 14:24:46.809: e/androidruntime(11558): caused by: android.view.inflateexception: binary xml file line #23: error inflating class fragment (...) 04-26 14:24:46.809: e/androidruntime(11558): caused by: java.lang.illegalstateexception: fragment com.example.traffic.listtrips did not create view. 

2) instantiate fragment programmatically (not xml): - in xml must use "layout" (i used framelayout) not "fragment"; - in java script, must use "fragmenttransaction";

3) android handles activity (that contains fragments) , android recreates @ beginning, must implementate onsaveinstancestate (saves data) , onrestoreinstancestate (to modify activity when rotated device).

i think error lies here, in listpoints fragment:

 public listpoints (int _cod) {     this.cod = _cod; } 

from fragment class reference android

all subclasses of fragment must include public no-argument constructor. framework re-instantiate fragment class when needed, in particular during state restore, , needs able find constructor instantiate it. if no-argument constructor not available, runtime exception occur in cases during state restore.

fragments need empty constructor can instantiated, cannot cannot override it. if need pass arguments try this:

writing in activity:

bundle bundle = new bundle(); bundle.putint(key, _cod); fragment.setarguments(bundle); 

reading in fragment:

bundle arguments = this.getarguments(); this.cod = arguments.getint(key); 

don't forget override onsaveinstancestate function if app in background , killed, able restore state correctly. otherwise variables not have value


Comments

Popular posts from this blog

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -

ubuntu - Selenium Node Not Connecting to Hub, Not Opening Port -