方向更改时,无法在片段中保存recyclelerview的实例状态

时间:2018-01-21 21:32:08

标签: android android-fragments onsaveinstancestate

我无法让我的recyclerview在方向更改时保存状态。在我的片段中使用过onSaveInstanceState但显然不正确,因为它不起作用。有关如何修复的任何建议和指示?

SecondActivity

public class SecondActivity extends AppCompatActivity {


private boolean mTwoPane;
ArrayList<Recipe> myList;
List<Steps> steps;
android.support.v7.app.ActionBar actionBar;
StepsFragment fragment;

//Eventbus
@Override
protected void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}


@Override
protected void onStop() {
    super.onStop();
    EventBus.getDefault().unregister(this);
}


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


    actionBar = getSupportActionBar();
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setHomeButtonEnabled(true);


    myList = getIntent().getParcelableArrayListExtra("list");
    String id = getIntent().getStringExtra("intent");
    int result = Integer.parseInt(id);
    steps = (ArrayList) myList.get(result - 1).getSteps();

    String nameString = myList.get(result - 1).getName();

    getSupportActionBar().setTitle(nameString);


    if (findViewById(R.id.android_me_linear_layout) != null) {

        mTwoPane = true;

        if (savedInstanceState == null) {

            Bundle arguments = new Bundle();


            arguments.putParcelableArrayList("myList", myList);
            arguments.putInt("result", result);
            arguments.putBoolean("twoPane", mTwoPane);

            StepsFragment fragment = new StepsFragment();

            fragment.setArguments(arguments);

            getSupportFragmentManager().beginTransaction()
                    .add(R.id.fragment_container, fragment)
                    .commit();


        }



    } else {
        // We're in single-pane mode and displaying fragments on a phone in separate activities
        mTwoPane = false;

        Bundle arguments = new Bundle();


        arguments.putParcelableArrayList("myList", myList);
        arguments.putInt("result", result);
        arguments.putBoolean("twoPane", mTwoPane);

        StepsFragment fragment = new StepsFragment();

        fragment.setArguments(arguments);

        getSupportFragmentManager().beginTransaction()
                .add(R.id.fragment_container, fragment)
                .commit();



    }


}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            onBackPressed();
            return true;
    }
    return super.onOptionsItemSelected(item);
}

@Override
public void onBackPressed() {
    super.onBackPressed();
    if(mTwoPane) {


        startActivity(new Intent(SecondActivity.this, MainActivity.class));
        finish();
    }

}

@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(Message event) {

    if (event.getMessage() == 2) {


        Fragment newFragment = new DetailFragment();

        newFragment.setArguments(event.getBundle());

        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

        transaction.replace(R.id.detail_container, newFragment);


        transaction.addToBackStack(null);

        transaction.commit();

        Log.d(LOG_TAG, "Eventbus worked");


    }

    else if ( event.getMessage() == 3){

        Fragment newFragment = new DetailFragment();

        newFragment.setArguments(event.getBundle());

        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

        transaction.replace(R.id.fragment_container, newFragment);

        transaction.addToBackStack(null);

        transaction.commit();



    }


}

}

StepsFragment

public class StepsFragment extends android.support.v4.app.Fragment {



ArrayList<Recipe> myList;
List<Steps> myStepsList;
List <Ingredients> ingredients;

private RecyclerView recyclerView;
StepItemRecyclerViewAdapter stepItemRecyclerViewAdapter;
private RecyclerView.LayoutManager mLayoutManager;

int result;
List<String> ingredientsString;
String string;
Boolean mTwoPane;
Parcelable listState;

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putParcelableArrayList("myArrayListTwo",(ArrayList) myStepsList);
}


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    if(savedInstanceState == null || !savedInstanceState.containsKey("myArrayListTwo")){
        myStepsList = new ArrayList<>();
    }

    else{
        myStepsList = savedInstanceState.getParcelableArrayList("myArrayListTwo");
    }


    mTwoPane = getArguments().getBoolean("twoPane");
    myList = getArguments().getParcelableArrayList("myList");
    result = getArguments().getInt("result") - 1;
    myStepsList = myList.get(result).getSteps();
    ingredients = myList.get(result).getIngredients();


    //Create a String array for all ingredients strings
    ingredientsString = new ArrayList<>();
    ingredientsString.add("Ingredients" + "\n");

    for(int x = 0; x < ingredients.size(); x++){

        ingredientsString.add(ingredients.get(x).getIngredient() + " " + ingredients.get(x).getQuantity() + " " + ingredients.get(x).getMeasure());
        Log.d(LOG_TAG, ingredientsString.get(x).toString());
    }



    StringBuilder stringBuilder = new StringBuilder();
    for(String s : ingredientsString){
        stringBuilder.append(s + "\n");
    }

    string = stringBuilder.toString();



}



@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragment_steps, container, false);

        recyclerView = (RecyclerView) rootView
                .findViewById(R.id.my_recycler_view);

        mLayoutManager = new LinearLayoutManager(getActivity());

        recyclerView.setLayoutManager(mLayoutManager);
        stepItemRecyclerViewAdapter = new StepItemRecyclerViewAdapter(myStepsList);
        recyclerView.setAdapter(stepItemRecyclerViewAdapter);


        TextView textView = (TextView) rootView.findViewById(R.id.text_view);
        textView.setText(string);


    return rootView;
}


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

        private final List<Steps> mValues;



    public StepItemRecyclerViewAdapter(List<Steps> items) {

        mValues = items;
    }

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

    @Override
    public void onBindViewHolder(final StepItemRecyclerViewAdapter.ViewHolder holder, int position) {


        holder.mItem = mValues.get(position);


        holder.mContentView.setText(mValues.get(position).getShortDescription());




        holder.mView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


                if(mTwoPane){
                    Bundle args = new Bundle();

                    args.putParcelableArrayList("myList", myList);
                    args.putInt("result", result);
                    args.putString("int", holder.mItem.getId());
                    EventBus.getDefault().postSticky(new Message(2, args));
                    Log.d(LOG_TAG, "You clicked a button" + holder.mItem.toString());



                } else if( mTwoPane == false){

                    Bundle args = new Bundle();

                    args.putParcelableArrayList("myList", myList);
                    args.putInt("result", result);
                    args.putString("int", holder.mItem.getId());
                    EventBus.getDefault().postSticky(new Message(3, args));
                    Log.d(LOG_TAG, "You clicked a button" + holder.mItem.toString());

                }


            }
        });
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder {
        public  View mView;
        public TextView mContentView;
        public Steps mItem;


        public ViewHolder(View view) {
            super(view);
            mView = view;
            mContentView = (TextView) view.findViewById(R.id.content);

        }

        @Override
        public String toString() {
            return super.toString() + " '" + mContentView.getText() + "'";
        }
    }
}













}

activity_main_two.xml https://github.com/RJRogers/TwoPaneUITest/blob/master/app/src/main/res/layout/activity_main_two.xml

fragment_steps.xml https://github.com/RJRogers/TwoPaneUITest/blob/master/app/src/main/res/layout/fragment_steps.xml

2 个答案:

答案 0 :(得分:1)

从您发布的代码中跳出来的东西就是这个(在您的活动中):

if (findViewById(R.id.android_me_linear_layout) != null) {
    if (savedInstanceState == null) {
        ...
        getSupportFragmentManager().beginTransaction()
                                   .add(R.id.fragment_container, fragment)
                                   .commit();
    }
}
else {
    ...
    getSupportFragmentManager().beginTransaction()
                               .add(R.id.fragment_container, fragment)
                               .commit();
}

通常,只有在savedInstanceState为空时,无论方向如何,都只需要添加一次片段。即使您的活动布局发生变化,片段管理器也会自动保存和恢复您的片段(只要两个布局都有一个具有相同ID的容器)。这可能会导致出现一个新的片段,而不是一个已经保存和恢复其状态的片段。

另一个突出的是(在你的片段中):

if(savedInstanceState == null || !savedInstanceState.containsKey("myArrayListTwo")){
    myStepsList = new ArrayList<>();
}
else{
    myStepsList = savedInstanceState.getParcelableArrayList("myArrayListTwo");
}
...
myStepsList = myList.get(result).getSteps();

这看起来像是你不小心用基于片段参数包的新列表覆盖了保存的列表。我无法准确地遵循这个片段/活动正在尝试做什么,但这似乎是你的问题隐藏的合理位置。

答案 1 :(得分:-2)

您可以在清单文件中的活动中添加此行

android:configChanges="orientation|screenSize"