当前位置: 首页 > 知识库问答 >
问题:

当方向改变时,无法在片段中保存RecycerView的实例状态

乐正烨熠
2023-03-14
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();



    }


}

}
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/activit_main_two.xml

fragment_steps.xml https://github.com/rjrogers/twopaneuitest/blob/master/app/src/main/res/layout/fragment_steps.xml

共有1个答案

蒙化
2023-03-14

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

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为null时添加一次片段,无论方向如何。即使活动的布局发生变化(只要两个布局都有一个具有相同id的容器),片段管理器也会自动保存和还原片段。这可能导致出现一个新的片段,而不是已保存和恢复其状态的片段。

另一件突出的事情是这样的(在你的片段中):

if(savedInstanceState == null || !savedInstanceState.containsKey("myArrayListTwo")){
    myStepsList = new ArrayList<>();
}
else{
    myStepsList = savedInstanceState.getParcelableArrayList("myArrayListTwo");
}
...
myStepsList = myList.get(result).getSteps();
 类似资料:
  • 我试过configChanges,但显然它没有改变我的布局。我试着在onConfigurationChanged的FrameLayout容器中填充肖像和景观布局并替换它们,但似乎也不起作用。 如何处理需要加载不同布局同时保持片段状态不变的情况?这有可能吗?对于这种事情,正确的做法是什么?

  • 所以我在我的开发项目中遇到了另一个路障。 另一个问题是,当我在Frag1中,然后在EditText中键入一些文本,然后更改方向时,尽管实现了onSaveInstanceState(Bundle Bundle),文本还是会消失。 以下是我的相关代码片段: 在activity.java中创建Frag1的代码段 AddPointsFragment.java的代码段 我尝试在代码中运行调试器,以了解在更改

  • null 我想保留的最后一个查看页面索引,当活动因任何原因重新创建时,例如方向改变。 位于附加到活动的(名为)中。我使用的是compat库,因此该片段是的子类。 我认为可以通过重写方法并在中添加适当的逻辑来完成,如文档中所述: 为了正确地处理重启,重要的是您的活动通过正常的活动生命周期恢复其以前的状态,在正常的活动生命周期中,Android在破坏您的活动之前调用onSaveInstanceStat

  • 我有4个按钮来替换活动中的片段[片段A,片段B,片段C,片段D],然后我将片段A替换为活动,然后我将片段A中的值更改为片段A,之后我将片段B替换为片段A,并将片段C替换为片段B.但是我想把片段A替换成片段C。如何在片段A中保存状态。 当我提交片段时编写代码 要替换的图表 片段A ------- 片段B ------- 片段C ------- PS.我不想使用返回按钮返回片段A,我想替换片段A并在第

  • 我有一个包含多个片段的活动。我还使用actionbarSherlock作为我的标签,它也连接到片段。 我的问题是,当我要旋转屏幕(即从纵向到横向/反之亦然)时,我的活动将再次调用,因此它将重新启动我的活动。 我不想重新启动我的活动,只想恢复旋转前显示的当前片段。请不要回答android:configChanges=“orientation | keyboardHidden”,因为它并没有解决问题,