在轮换

时间:2016-03-02 18:52:04

标签: android rotation android-recyclerview

我有一个DialogFragment,它包含一个RecyclerView 要填充recyclerview,我想给它一个HashSet,并在RecyclerView中填充项目。

问题是,因为没有onSaveInstanceState - > onRestoreInstanceState,我无法定期保存。

我已经看过关于setRetainInstance(true)的帖子,但它没有保存我的RecyclerView状态。

那是我的代码:

package giorag.dailytimer;

import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckedTextView;
import android.widget.EditText;
import android.widget.ImageButton;

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

/**
 * Created by GioraPC on 01/03/2016.
 */
public class TeamNamesEditDialog extends DialogFragment {

    private EditText personName;
    private RecyclerView namesList;
    private ImageButton addName;
    private TeamNamesAdapter adapter;

    public TeamNamesEditDialog() {
    }

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

        setRetainInstance(true);
    }

    @Override
    public void onDestroyView() {
        if (getDialog() != null && getRetainInstance())
            getDialog().setDismissMessage(null);
        super.onDestroyView();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_team_names, container);
        personName = (EditText) view.findViewById(R.id.team_names_new_name);
        namesList = (RecyclerView) view.findViewById(R.id.team_names_list);
        namesList.setLayoutManager(new LinearLayoutManager(getContext()));
        addName = (ImageButton) view.findViewById(R.id.team_names_add_name);

        getDialog().setTitle("Update team");

        adapter = new TeamNamesAdapter(null);

        namesList.setAdapter(adapter);
        namesList.addItemDecoration(new DividerItemDecoration(getActivity(), null));
        addName.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                adapter.addName(personName.getText().toString());
                personName.setText("");
            }
        });

        ItemTouchHelper.Callback callback =
                new SimpleItemTouchHelperCallback(adapter);
        ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
        touchHelper.attachToRecyclerView(namesList);

        return view;
    }

    class TeamNamesAdapter extends RecyclerView.Adapter<TeamNamesAdapter.ViewHolder> implements ItemTouchHelperAdapter {

        private List<String> names;

        public List<String> getNames() {
            return names;
        }

        public TeamNamesAdapter(List<String> names) {
            this.names = names == null ? new ArrayList<String>() : names;
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.team_names_list_item, null);

            ViewHolder viewHolder = new ViewHolder(view);
            return viewHolder;
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            String name = new ArrayList<>(names).get(position);
            holder.name.setText(name);
        }

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

        public void addName(String name) {
            if(names.contains(name) || name.isEmpty())
                return;

            names.add(name);
            notifyDataSetChanged();
        }

        @Override
        public void onItemDismiss(int position) {
            names.remove(position);
            notifyItemRemoved(position);
        }

        @Override
        public void onItemMove(int fromPosition, int toPosition) {
            if (fromPosition < toPosition) {
                for (int i = fromPosition; i < toPosition; i++) {
                    Collections.swap(names, i, i + 1);
                }
            }
            else {
                for (int i = fromPosition; i > toPosition; i--) {
                    Collections.swap(names, i, i - 1);
                }
            }
            notifyItemMoved(fromPosition, toPosition);
        }

        class ViewHolder extends RecyclerView.ViewHolder {

            CheckedTextView name;

            public ViewHolder(View itemView) {
                super(itemView);

                name = (CheckedTextView)itemView.findViewById(R.id.name_in_list);
                name.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View v) {
                        ((CheckedTextView) v).toggle();
                    }
                });
            }
        }
    }
}

我已尝试在setRetainInstanceonCreateView中的构造函数中调用onCreate,但我仍然在轮换时丢失了RecyclerView项目。

有没有办法保存这些项目并在轮换时恢复它们?

1 个答案:

答案 0 :(得分:2)

我也有CustomDialogFragmentonSaveInstanceState也能正常使用。

您的代码中存在一些问题:例如,在onCreateView期间,您始终使用空List创建适配器。这就是你的物品消失的原因。

因此,您必须在(onSaveInstanceState)期间添加更多代码以保存名称,并在onCreateonCreateView期间恢复它们。

类似的东西:

public class TeamNamesEditDialog extends DialogFragment {
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);            
        savedInstanceState.putStringArrayList("oldNames", (ArrayList<String>) adapter.getNames());
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if(savedInstanceState != null) {
            ArrayList<String> previousNameList = savedInstanceState.getStringArrayList("oldNames");
            adapter = new TeamNamesAdapter(previousNameList);
        } else {
            adapter = new TeamNamesAdapter(null);
        }
        ...
        return view;
    }
}