2015-05-25 2 views
1

при перезагрузке фрагмента Мне нужно восстановить переменные. Все остальные переменные работают, кроме моего обратного вызова.Как сохранить и восстановить интерфейс на моем фрагменте, используя onSaveInstanceState

У меня есть фрагмент, как это:

общественного класса ClosetFragment расширяет фрагмент {

private String [] closetSessions = null; 
private DBName dbName = null; 
private String token = null; 
private RefreshCallback callback= null; 

public ClosetFragment(String [] closetSessions, DBName dbName, String token, RefreshCallback callback){ 
    this.closetSessions = closetSessions; 
    this.dbName = dbName; 
    this.token = token; 
    this.callback = callback; 

} 
public ClosetFragment(){ 

} 

    @Override 
    public void onSaveInstanceState(final Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putSerializable("closetSessions", (Serializable) this.closetSessions); 
     outState.putSerializable("dbName", (Serializable) this.dbName); 
     outState.putSerializable("token", (Serializable) this.token); 
     outState.putSerializable("callback", (Serializable) this.callback); 
    } 

И мой обратный вызов:

public interface RefreshCallback extends Serializable{ 
    public void onNeedrefresh(); 
} 

И Exception я получил это:

AppSectionsPagerAdapter - это класс, который реализует мой обратный вызов.

05-25 12:04:06.037: E/AndroidRuntime(10822): FATAL EXCEPTION: main 
05-25 12:04:06.037: E/AndroidRuntime(10822): java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = br.com.closet4share.app.adapters.AppSectionsPagerAdapter$1) 
05-25 12:04:06.037: E/AndroidRuntime(10822): at android.os.Parcel.writeSerializable(Parcel.java:1279) 
05-25 12:04:06.037: E/AndroidRuntime(10822): at android.os.Parcel.writeValue(Parcel.java:1233) 
05-25 12:04:06.037: E/AndroidRuntime(10822): at android.os.Parcel.writeMapInternal(Parcel.java:591) 
05-25 12:04:06.037: E/AndroidRuntime(10822): at android.os.Bundle.writeToParcel(Bundle.java:1627) 
05-25 12:04:06.037: E/AndroidRuntime(10822): at android.os.Parcel.writeBundle(Parcel.java:605) 
05-25 12:04:06.037: E/AndroidRuntime(10822): at android.support.v4.app.FragmentState.writeToParcel(Fragment.java:135) 
05-25 12:04:06.037: E/AndroidRuntime(10822): at android.os.Parcel.writeTypedArray(Parcel.java:1102) 
05-25 12:04:06.037: E/AndroidRuntime(10822): at android.support.v4.app.FragmentManagerState.writeToParcel(FragmentManager.java:378) 
05-25 12:04:06.037: E/AndroidRuntime(10822): at android.os.Parcel.writeParcelable(Parcel.java:1254) 
05-25 12:04:06.037: E/AndroidRuntime(10822): at android.os.Parcel.writeValue(Parcel.java:1173) 
05-25 12:04:06.037: E/AndroidRuntime(10822): at android.os.Parcel.writeMapInternal(Parcel.java:591) 
05-25 12:04:06.037: E/AndroidRuntime(10822): at android.os.Bundle.writeToParcel(Bundle.java:1627) 
05-25 12:04:06.037: E/AndroidRuntime(10822): at android.os.Parcel.writeBundle(Parcel.java:605) 
05-25 12:04:06.037: E/AndroidRuntime(10822): at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:2535) 
05-25 12:04:06.037: E/AndroidRuntime(10822): at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3151) 

Большое спасибо за помощь!

Это, как я осуществить свою функцию обратного вызова:

@Override 
    public Fragment getItem(int i) { 

     Fragment fragment = null; 

     fragment = new ClosetFragment(i,closetSessions,dbName,token, new RefreshCallback(){ 

      /** 
      * 
      */ 
      private static final long serialVersionUID = 1L; 

      @Override 
      public void onNeedrefresh() { 
       AppSectionsPagerAdapter.this.notifyDataSetChanged(); 

      } 

     }); 
     mPageReferences.put(i, new WeakReference<Fragment>(fragment)); 

     return fragment; 

    } 
+1

Можете ли вы изменить в примере, как вы используете экземпляр этого «обратного вызова»? Например. реализация в «AppSectionsPagerAdapter». – vzsg

ответ

0
public class MainActivity extends Activity implements AddToDoFragment.OnToDoAddedListener { 

    private ArrayList<String> todoItems; 
    private ArrayAdapter<String> adapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     if(savedInstanceState == null) { 
      todoItems = new ArrayList<String>(); 
     } else { 
      todoItems = savedInstanceState.getStringArrayList("todoItemTag");//the tag must match what the variable was saved with 
     } 

     FragmentManager fm = getFragmentManager(); 

     ToDoListFragment listToDo = new ToDoListFragment(); 
     listToDo = (ToDoListFragment) fm.findFragmentById(R.id.list_view_fragment); 
     adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, todoItems); 
     listToDo.setListAdapter(adapter); 
    } 

    public void OnToDoAdded(String newToDo) { 
     todoItems.add(newToDo); 
     adapter.notifyDataSetChanged(); 

    } 

    @Override 
    protected void onSavedInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 

     oustate.putStringArrayList("todoItemTag", todoItems);//it would be advised to make the tags a static final String 
    } 
} 

Вы хотите переопределить onSavedInstanceState метод так, что вы знаете, когда состояние должно быть сохранено. Затем вам также потребуется обновить метод onCreate, чтобы проверить, является ли сохраненное значениеInstanceState нулевым. Если он равен нулю, действие не было начато. Это пример вашего класса MainActivity, и вы можете перейти оттуда:

+0

Привет, savedInstanceState не является нулевым, и даже если я не проверял этот код, действие было инициировано. Проблема в том, как сохранить и восстановить мой обратный вызов? Как я могу поместить его и извлечь из saveInstanceState? –

1

Исключение происходит из-за того, что анонимный внутренний класс содержит переменную-член для родительского адаптера - это то, к чему вы обращаетесь через AppSectionsPagerAdapter.this, а адаптер не является Сериализуемый.

Вы не можете продолжать обратный вызов таким образом, и, честно говоря, вы даже не должны пытаться это сделать. Удерживайте только внутренние данные фрагмента и установите обратный вызов отдельно в getItem.

+0

, но когда фрагмент приостанавливается и возобновляется, он не вызывает getItem. И моя ссылка на обратный вызов теряется. Итак, если бы я изменил эту архитектуру, как я могу сказать своему адъютеру, чтобы он уведомлял DataSetChanged изнутри этого флага? @vzsg –

1

В моей деятельности я создал метод:

public void refreshAdapter(){ 
     if (mAppSectionsPagerAdapter != null) 
      mAppSectionsPagerAdapter.notifyDataSetChanged(); 
    } 

и в моем фрагменте вызов:

Closet closet = (Closet)getActivity(); 
      closet.refreshAdapter(); 

И ни nned не спасти ничего. Спасибо @vzsg.

+0

Это тоже работает. Следует опасаться, что 'getActivity()' может вернуть значение null, если фрагмент отсоединен, поэтому вы должны быть осторожны с AsyncTasks, которые могут пережить активность, например. – vzsg