0

这种类型的问题在 SO 中被问过很多次,我已经尝试了所有这些,但无法实现我真正想要的。在我的应用程序中Fragment,在那个片段中我有一个recycler视图。recyclerview将由我从 API 获得的数据进行操作。

我想要的是,当旋转发生变化时,应用程序不会再次调用 API。为了实现这一点,我知道我必须将数据放入onSaveInstanceState,如果我想保存一个复杂的对象,那么该类必须是实现的Parcelable。我已经完成了推荐的一切,但无法实现我想要的。

我在这里分享我的代码,我创建了一个简化的例子。

SimpleFragment.java的代码

public class SimpleFragment extends Fragment {

    RecyclerView recyclerView;
    ArrayList<TestModel> testModelList = new ArrayList<TestModel>() ;
    SimpleAdapter simpleAdapter;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.simple_fragment, container, false);
        recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler);

        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(mLayoutManager);

        simpleAdapter = new SimpleAdapter(getActivity());

        recyclerView.setAdapter(simpleAdapter);


        if(savedInstanceState != null){
            //if this fragment starts after a rotation or configuration change, load the existing model from a parcelable
            testModelList = savedInstanceState.getParcelableArrayList("key");
            // I have done necessary debug , after rotation , it comes here ,
            // but suddenly savedInstanceState becomes null and getTestModelList() get called


        }else {
            //if this fragment starts for the first time, load the list of model
           getTestModelList();
        }

        simpleAdapter.setModel(testModelList);

        return rootView;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelableArrayList("key",testModelList);
    }

    public void getTestModelList(){
        for (int i=0;i<10;i++){
            testModelList.add(new TestModel(i,"test"+i));
        }
        Toast.makeText(getActivity(),"Called",Toast.LENGTH_SHORT).show();
    }
}

SimpleFragment 的布局文件:simple_fragment.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">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler"
        android:background="@android:color/black"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

这是我的数据模型TestModel.java的代码

public class TestModel implements Parcelable {

    String text;

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public TestModel(int number, String text) {
        this.text = text;
    }


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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.text);
    }

    protected TestModel(Parcel in) {
        this.text = in.readString();
    }

    public static final Parcelable.Creator<TestModel> CREATOR
            = new Parcelable.Creator<TestModel>() {
        public TestModel createFromParcel(Parcel in) {
            return new TestModel(in);
        }

        public TestModel[] newArray(int size) {
            return new TestModel[size];
        }
    };
}

我的适配器类:SimpleAdapter.java

public class SimpleAdapter extends RecyclerView.Adapter<SimpleAdapter.ViewHolder> {

    Context context;
    ArrayList<TestModel> testModels;

    public SimpleAdapter(Context context) {
        this.context = context;
    }

    public void setModel(ArrayList<TestModel> model){
        this.testModels = model;
        notifyDataSetChanged();
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.single_row, viewGroup, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.list_item.setText(testModels.get(position).getText());
    }

    @Override
    public int getItemCount() {
        return testModels.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder{
        TextView list_item;
        public ViewHolder(View itemView) {
            super(itemView);
            list_item = (TextView) itemView.findViewById(R.id.list_item);
        }
    }
}

适配器single_row.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="match_parent"
        android:layout_height="wrap_content"
        android:padding="20dp"
        android:id="@+id/list_item"
        android:textColor="@android:color/white"/>

</LinearLayout>

这些就是我所做的,如果 getTestModelList()再次调用 SimpleFragment 中的更改方向方法,我想避免这种情况;在实际应用场景中,此方法将执行一些 API 调用。我想保存ArrayList<TestModel> testModelList.

4

3 回答 3

2

您需要保存活动状态并在配置前检查它

遵循此代码

public class MainActivity extends AppCompatActivity{


    private HomeFragment homeFragment;

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

        FragmentManager fm = getSupportFragmentManager();


           if (savedInstanceState == null) {
            homeFragment = new HomeFragment();


            ((fm.beginTransaction()).replace(R.id.mainframe, homeFragment)).commit();
        }
}}}
于 2016-08-11T12:49:05.457 回答
2

onCreate您可以像这样在 Fragment方法中保存 Fragment 实例以更改方向以保存实例:

@Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         // Set Instance true
        this.setRetainInstance(true);
    }
于 2016-08-11T12:49:32.353 回答
1

每当方向改变时,Android 都会重新创建您的活动。这背后的原因是您可能需要更改布局,但您仍然可以使用onConfigurationChanged()ofActivityFragment我建议您添加

android:configChanges="orientation|keyboardHidden|screenSize"

在您的清单文件中(请参阅thisthis)。这将停止重新创建 Confifuration 更改上的 Activity。

于 2016-08-11T12:57:58.627 回答