2016-04-06 3 views
1

Я практикую фрагменты, поэтому я попытался добавить ListFragment в свою MainActivity. Ничего сложного, просто список, где каждая строка имеет имя и номер, который вы можете увеличить/уменьшить с помощью кнопки плюс/минус. Однако, когда я повернуть экран, все номера сбрасываются в 0.Почему мой список не сохранился?

MyListFragment.java

package randomdomain.dialogtest; 

import android.os.Bundle; 
import android.support.v4.app.ListFragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 

import java.util.ArrayList; 
import java.util.List; 

public class MyListFragment extends ListFragment { 
    public static final String MYOBJECT_PARCELABLE_KEY = "myobject_parcelable_key"; 
    private MyAdapter mMyAdapter; 
    private List<MyObject> mMyObjects; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View contentView = inflater.inflate(R.layout.list_fragment, container, false); 

     mMyObjects = fillObjects(); 
     mMyAdapter = new MyAdapter(getActivity(), mMyObjects); 
     setListAdapter(mMyAdapter); 

     return contentView; 
    } 

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

     for (int i = 0; i < mMyObjects.size(); i++) 
      outState.putParcelable(MYOBJECT_PARCELABLE_KEY + i, mMyObjects.get(i)); 
    } 

    @Override 
    public void onViewStateRestored(Bundle savedInstanceState) { 
     super.onViewStateRestored(savedInstanceState); 
     mMyObjects = new ArrayList<MyObject>(); 
     for (int i = 0; i < mMyObjects.size(); i++) { 
      MyObject object = savedInstanceState.getParcelable(MYOBJECT_PARCELABLE_KEY + i); 
      mMyObjects.add(object); 
     } 
    } 

    private List<MyObject> fillObjects() { 
     List<MyObject> myObjects = new ArrayList<MyObject>(); 
     for (int i = 0; i < 30; i++) { 
      MyObject object = new MyObject("Object " + (i + 1) + " ", 0); 
      myObjects.add(object); 
     } 
     return myObjects; 
    } 
} 

MyObject.java при необходимости:

package randomdomain.dialogtest; 

import android.os.Parcel; 
import android.os.Parcelable; 

public class MyObject implements Parcelable { 
    private String mName; 
    private int mValue; 

    public MyObject(String name, int value) { 
     mName = name; 
     mValue = value; 
    } 

    public String getName() { 
     return mName; 
    } 

    public void setName(String name) { 
     mName = name; 
    } 

    public int getValue() { 
     return mValue; 
    } 

    public void setValue(int value) { 
     mValue = value; 
    } 

    @Override 
    public int describeContents() { 
     return 0; // nothing 
    } 

    private MyObject(Parcel in) { 
     mName = in.readString(); 
     mValue = in.readInt(); 
    } 

    @Override 
    public void writeToParcel(Parcel dest, int flags) { 
     dest.writeString(mName); 
     dest.writeInt(mValue); 
    } 

    public static final Creator<MyObject> CREATOR = new Creator<MyObject>() { 
     @Override 
     public MyObject createFromParcel(Parcel source) { 
      return new MyObject(source); 
     } 

     @Override 
     public MyObject[] newArray(int size) { 
      return new MyObject[size]; 
     } 
    }; 
} 

И MyAdapter.java, опять же, если это необходимо:

package randomdomain.dialogtest; 


import android.content.Context; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.Button; 
import android.widget.TextView; 

import java.util.List; 

public class MyAdapter extends BaseAdapter { 
    private Context mContext; 
    private List<MyObject> mMyObjects; 

    public MyAdapter(Context context, List<MyObject> objects) { 
     mContext = context; 
     mMyObjects = objects; 
    } 

    @Override 
    public int getCount() { 
     return mMyObjects.size(); 
    } 

    @Override 
    public Object getItem(int position) { 
     return mMyObjects.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return 0; //unused 
    } 

    @Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 
     final ViewHolder holder; 

     if (convertView == null) { 
      convertView = LayoutInflater.from(mContext).inflate(R.layout.item_row, null); 
      holder = new ViewHolder(); 
      holder.rowName = (TextView) convertView.findViewById(R.id.text_rowname); 
      holder.counter = (TextView) convertView.findViewById(R.id.text_counter); 
      holder.buttonAdd = (Button) convertView.findViewById(R.id.button_add); 
      holder.buttonSubtract = (Button) convertView.findViewById(R.id.button_subtract); 
      convertView.setTag(holder); 
     } 
     else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     holder.rowName.setText(mMyObjects.get(position).getName()); 
     holder.counter.setText(mMyObjects.get(position).getValue() + ""); 
     holder.buttonSubtract.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       mMyObjects.get(position).setValue(Math.max(mMyObjects.get(position).getValue() - 1, 0)); 
       holder.counter.setText(mMyObjects.get(position).getValue() + ""); 
      } 
     }); 
     holder.buttonAdd.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       mMyObjects.get(position).setValue(mMyObjects.get(position).getValue() + 1); 
       holder.counter.setText(mMyObjects.get(position).getValue()+ ""); 
      } 
     }); 
     return convertView; 
    } 

    private static class ViewHolder { 
     public TextView rowName; 
     public TextView counter; 
     public Button buttonSubtract; 
     public Button buttonAdd; 
    } 
} 

И MainActivity просто вызывает фрагмент:

package randomdomain.dialogtest; 

import android.support.v4.app.FragmentTransaction; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 

public class MainActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
     transaction.add(R.id.fragment_container, new MyListFragment()).commit(); 
    } 
} 

Почему значения сбрасываются, даже если я расширил Parcelable и сохранил все значения при сохранении, а затем сбросил список, используя сохраненное состояние экземпляра при восстановлении?

EDIT, обновленный MyListFragment.java

package randomdomain.dialogtest; 

import android.os.Bundle; 
import android.support.annotation.Nullable; 
import android.support.v4.app.ListFragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Toast; 

import java.util.ArrayList; 
import java.util.List; 

public class MyListFragment extends ListFragment { 
    public static final String MYOBJECT_PARCELABLE_KEY = "myobject_parcelable_key"; 
    private MyAdapter mMyAdapter; 
    private List<MyObject> mMyObjects; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View contentView = inflater.inflate(R.layout.list_fragment, container, false); 

     if (savedInstanceState == null) { 
      mMyObjects = fillObjects(); 
     } 
     else { 
      mMyObjects = savedInstanceState.getParcelableArrayList(MYOBJECT_PARCELABLE_KEY); 
     } 

     mMyAdapter = new MyAdapter(getActivity(), mMyObjects); 
     setListAdapter(mMyAdapter); 

     return contentView; 
    } 

    @Override 
    public void onSaveInstanceState(Bundle outState) { 
     outState.putParcelableArrayList(MYOBJECT_PARCELABLE_KEY, (ArrayList<MyObject>) mMyObjects); 
     super.onSaveInstanceState(outState); 
    } 

    private List<MyObject> fillObjects() { 
     List<MyObject> myObjects = new ArrayList<MyObject>(); 
     for (int i = 0; i < 30; i++) { 
      MyObject object = new MyObject("Object " + (i + 1) + " ", 0); 
      myObjects.add(object); 
     } 
     return myObjects; 
    } 
} 

ответ

1

Измените ваши onCreate() только добавить новый экземпляр вашей FragmentFragmentManager если не может найти существующий экземпляр:

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

    if (getSupportFragmentManager().findFragmentById(R.id.fragment_container) == null) 
    { 
     FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
     transaction.add(R.id.fragment_container, new MyListFragment()).commit(); 
    } 
} 
+0

Теперь, когда я вращаюсь, весь фрагмент просто исчезает –

+0

Выяснил, почему, изменила мою функцию onsave на 'outState.putParcelableArrayList (MYOBJECT_PARCELABLE_KEY, (ArrayList ) mMyObjects);' и затем удалила мою функцию восстановления и в onCreateView повторно назначила mMyObjects, если savedInstanceState не был нулевым. –

+0

@ArukaJ - Извините, и это странно, потому что я просто перечитал соответствующую часть в какой-то учебной книге, чтобы убедиться :(Есть еще одна вещь, которую я только что видел в вашем коде: вы вызываете super.onSaveInstanceState() * раньше * поместив ваши значения в пакет состояния экземпляра, вы должны позвонить ему позже. – 0X0nosugar

0

Попробуйте поставить следующий код фрагмента:

@Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setRetainInstance(true); 
    } 
+0

Не похоже на w ork –

+0

Извините, мой друг, у меня нет возможности проверить ваш код прямо сейчас. Может быть, я попробую это позже))). – SanchelliosProg

Смежные вопросы