lundi 9 mai 2016

Android Recycler VIew: How to save the state of image button throughout application?

I am able to toggle image button. Selecting the image button, turns it into red heart indicating the current item has been added to favorite category. However,

  1. Scrolling up or down, changes the selected item.
  2. Re-launch of activity or even the scrolling among tabs, cause the image button to loose (forget) its state i.e. all image button becomes unselected!

I have some idea that the second problem can be solved by using sharedpreferences but i can't really get how to use it?!

Below is my custom adapter for recycler view:

public class RvAdapter extends RecyclerView.Adapter<RvAdapter.RvItemViewHolder> {

    List<ModelData> modelData = new ArrayList<>();
    Context ctx;

    public RvAdapter(List<ModelData> modelData, Context ctx) {

        this.modelData = modelData;
        this.ctx = ctx;
    }

    @Override
    public RvItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        ArrayList<ModelData> modelData = new ArrayList<ModelData>();

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_item_layout, parent, false);

        RvItemViewHolder rvItemViewHolder = new RvItemViewHolder(view, ctx, modelData);

        return rvItemViewHolder;
    }

    // Involves populating data into the item through holder

    @Override
    public void onBindViewHolder(final RvItemViewHolder holder, int position) {

        //Get the data model based on position

        ModelData rvItem = modelData.get(position);

        // Set item views based on the data model
        Picasso.with(ctx).load(rvItem.getPhotoId()).resize(368, 368).centerCrop().into(holder.menu_img);
        holder.menu_title.setText((rvItem.getName()));

        holder.fav.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                    holder.fav.setSelected(!holder.fav.isSelected());
                if (holder.fav.isSelected()){
                    holder.fav.setImageResource(R.drawable.fav_red);
            }
                else {
                    holder.fav.setImageResource(R.drawable.wishlist);
                }

                }
        });

    }


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

    public static class RvItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        ImageView menu_img;
        TextView menu_title;
        ImageButton fav;
        ArrayList<ModelData> modelData = new ArrayList<ModelData>();
        Context ctx;

        // Constructor that will create objects for its class that is RvItemViewHolder

        public RvItemViewHolder(View view, final Context ctx, ArrayList<ModelData> modelData) {

            super(view);

            this.modelData = modelData;
            this.ctx = ctx;

            // We want our views clickable
            view.setOnClickListener(this);

            menu_img = (ImageView) view.findViewById(R.id.ImageRV);
            menu_title = (TextView) view.findViewById(R.id.titleRV);
            fav = (ImageButton) view.findViewById(R.id.fav);

            view.findViewById(R.id.fav).setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {

                    fav.setSelected(!fav.isSelected());
                    if (fav.isSelected()){
                        fav.setImageResource(R.drawable.fav_red);
                    }
                    else {
                        fav.setImageResource(R.drawable.wishlist);
                    }

                }

            });

        }

        @Override
        public void onClick(View v) {

            int position = getAdapterPosition();
            switch (position) {

                case 0:
                    Intent activityChangeIntent = new Intent(ctx, Dos.class);
                    ctx.startActivity(activityChangeIntent);
                    break;
                case 1:
                    Intent TeaIntent = new Intent(ctx, thirteen.class);
                    ctx.startActivity(TeaIntent);
                    break;
            }

        }
    }

}

Below is my model data:

public class ModelData {

public ModelData(String name, String detail, int photoId) {
    this.name = name;
    this.detail = detail;
    this.photoId = photoId;
}

private String name;
private String detail;
private int photoId;
private boolean selected;

public boolean isSelected() {
    return selected;
}

public void setSelected(boolean selected) {
    this.selected = selected;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getDetail() {
    return detail;
}

public void setDetail(String detail) {
    this.detail = detail;
}

public int getPhotoId() {
    return photoId;
}

public void setPhotoId(int photoId) {
    this.photoId = photoId;
}
}

Below is my tab (fragment):

public class OneFragment extends Fragment {

private OnFragmentInteractionListener mListener;
static SharedPreferences favPref;
public static final String favKey = "favKey";

public OneFragment() {
    // Required empty public constructor
}

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

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

    // Lookup the recyclerview in activity layout

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

    RecyclerView rView = (RecyclerView) rootView.findViewById(R.id.recycler_view);

   RecyclerView.LayoutManager layoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);

    // Set layout manager to position the items

    rView.setLayoutManager(layoutManager);

    // some recommended optimization!

    rView.setHasFixedSize(true);

    // Initialize items

    List<ModelData> rowListItem = getAllItemList();

    // Create adapter passing in the sample user data

    RvAdapter adapter = new RvAdapter(rowListItem, this.getActivity());

    // Attach the adapter to the recyclerview to populate items

    rView.setAdapter(adapter);

    // Inflate the layout for this fragment

    return rootView;


}

@Override
public String toString() {
    return "Users";
}

private List<ModelData> getAllItemList() {

    List<ModelData> allItems = new ArrayList<>();
    allItems.add(new ModelData("Dos", "Live and let others to live", R.drawable.dos));
    allItems.add(new ModelData("13", "Eternal Joy", R.drawable.thirteen));
    allItems.add(new ModelData("Deva", "Details", R.drawable.deva));
    allItems.add(new ModelData("Rathod", "Details", R.drawable.bhavesh));
    allItems.add(new ModelData("Das", "Details", R.drawable.dhruvin));
    allItems.add(new ModelData("Het", "Details", R.drawable.het));
    allItems.add(new ModelData("Me", "Details", R.drawable.me));
    allItems.add(new ModelData("76", "Details", R.drawable.sevensix));
    allItems.add(new ModelData("Pruthvi", "Details", R.drawable.pruthvi));


    return allItems;
}

/**
 * This interface must be implemented by activities that contain this
 * fragment to allow an interaction in this fragment to be communicated
 * to the activity and potentially other fragments contained in that
 * activity.
 * <p/>
 * See the Android Training lesson <a href=
 * "http://ift.tt/NoA2Cz"
 * >Communicating with Other Fragments</a> for more information.
 */
public interface OnFragmentInteractionListener {
    // TODO: Update argument type and name
    void onFragmentInteraction(Uri uri);
}
}

Aucun commentaire:

Enregistrer un commentaire