NEUESTE INFO:
Ich habe mein Problem auf ein Problem eingegrenzt, bei dem der fragmentManager Instanzen alter Fragmente beibehält und mein Viewpager nicht mit meinem FragmentManager synchronisiert ist. Siehe dieses Problem ... http://code.google.com/p/android/issues/detail?id=19211#makechanges . Ich habe immer noch keine Ahnung, wie ich das lösen soll. Irgendwelche Vorschläge...
Ich habe lange versucht, dies zu debuggen, und jede Hilfe wäre sehr dankbar. Ich verwende einen FragmentPagerAdapter, der eine Liste von Fragmenten wie folgt akzeptiert:
List<Fragment> fragments = new Vector<Fragment>();
fragments.add(Fragment.instantiate(this, Fragment1.class.getName()));
...
new PagerAdapter(getSupportFragmentManager(), fragments);
Die Implementierung ist Standard. Ich verwende ActionBarSherlock und die v4-Berechenbarkeitsbibliothek für Fragmente.
Mein Problem ist, dass die Fragmente nach dem Verlassen der App und dem Öffnen mehrerer anderer Anwendungen und dem Zurückkehren ihre Referenz auf die FragmentActivity (dh getActivity() == null
) verlieren . Ich kann nicht herausfinden, warum dies geschieht. Ich habe versucht, manuell einzustellen, setRetainInstance(true);
aber das hilft nicht. Ich habe mir gedacht, dass dies passiert, wenn meine FragmentActivity zerstört wird. Dies passiert jedoch immer noch, wenn ich die App öffne, bevor ich die Protokollnachricht erhalte. Gibt es irgendwelche Ideen?
@Override
protected void onDestroy(){
Log.w(TAG, "DESTROYDESTROYDESTROYDESTROYDESTROYDESTROYDESTROY");
super.onDestroy();
}
Der Adapter:
public class PagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragments;
public PagerAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
@Override
public int getCount() {
return this.fragments.size();
}
}
Eines meiner Fragmente wurde entfernt, aber ich habe alles herausgeholt, was entfernt wurde und immer noch nicht funktioniert ...
public class MyFragment extends Fragment implements MyFragmentInterface, OnScrollListener {
...
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
handler = new Handler();
setHasOptionsMenu(true);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.w(TAG,"ATTACHATTACHATTACHATTACHATTACH");
context = activity;
if(context== null){
Log.e("IS NULL", "NULLNULLNULLNULLNULLNULLNULLNULLNULLNULLNULL");
}else{
Log.d("IS NOT NULL", "NOTNOTNOTNOTNOTNOTNOTNOT");
}
}
@Override
public void onActivityCreated(Bundle savedState) {
super.onActivityCreated(savedState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.my_fragment,container, false);
return v;
}
@Override
public void onResume(){
super.onResume();
}
private void callService(){
// do not call another service is already running
if(startLoad || !canSet) return;
// set flag
startLoad = true;
canSet = false;
// show the bottom spinner
addFooter();
Intent intent = new Intent(context, MyService.class);
intent.putExtra(MyService.STATUS_RECEIVER, resultReceiver);
context.startService(intent);
}
private ResultReceiver resultReceiver = new ResultReceiver(null) {
@Override
protected void onReceiveResult(int resultCode, final Bundle resultData) {
boolean isSet = false;
if(resultData!=null)
if(resultData.containsKey(MyService.STATUS_FINISHED_GET)){
if(resultData.getBoolean(MyService.STATUS_FINISHED_GET)){
removeFooter();
startLoad = false;
isSet = true;
}
}
switch(resultCode){
case MyService.STATUS_FINISHED:
stopSpinning();
break;
case SyncService.STATUS_RUNNING:
break;
case SyncService.STATUS_ERROR:
break;
}
}
};
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.activity, menu);
}
@Override
public void onPause(){
super.onPause();
}
public void onScroll(AbsListView arg0, int firstVisible, int visibleCount, int totalCount) {
boolean loadMore = /* maybe add a padding */
firstVisible + visibleCount >= totalCount;
boolean away = firstVisible+ visibleCount <= totalCount - visibleCount;
if(away){
// startLoad can now be set again
canSet = true;
}
if(loadMore)
}
public void onScrollStateChanged(AbsListView arg0, int state) {
switch(state){
case OnScrollListener.SCROLL_STATE_FLING:
adapter.setLoad(false);
lastState = OnScrollListener.SCROLL_STATE_FLING;
break;
case OnScrollListener.SCROLL_STATE_IDLE:
adapter.setLoad(true);
if(lastState == SCROLL_STATE_FLING){
// load the images on screen
}
lastState = OnScrollListener.SCROLL_STATE_IDLE;
break;
case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
adapter.setLoad(true);
if(lastState == SCROLL_STATE_FLING){
// load the images on screen
}
lastState = OnScrollListener.SCROLL_STATE_TOUCH_SCROLL;
break;
}
}
@Override
public void onDetach(){
super.onDetach();
if(this.adapter!=null)
this.adapter.clearContext();
Log.w(TAG, "DETACHEDDETACHEDDETACHEDDETACHEDDETACHEDDETACHED");
}
public void update(final int id, String name) {
if(name!=null){
getActivity().getSupportActionBar().setTitle(name);
}
}
}}
Die Aktualisierungsmethode wird aufgerufen, wenn ein Benutzer mit einem anderen Fragment interagiert und getActivity null zurückgibt. Hier ist die Methode, die das andere Fragment aufruft ...
((MyFragment) pagerAdapter.getItem(1)).update(id, name);
Ich glaube, wenn die App zerstört und dann neu erstellt wird, anstatt sie nur bis zum Standardfragment zu starten, wird die App gestartet und der Viewpager navigiert dann zur letzten bekannten Seite. Das scheint seltsam, sollte die App nicht einfach auf das Standardfragment geladen werden?