Storing list of position in sharedPreferences, and retrieve in another activity

寵の児 提交于 2021-02-08 03:44:53

问题


I want to do similar like this, I have used cardview with recyclerview. I added favourite button cardview below you can see the full code. In recyclerview adapter I print the Toast as per position and its working fine, now I need to save the int value of position in shared Preferences in arraylist and display those arraylist in next intent.

This is my recyclerview adapter

public void onBindViewHolder(NameViewHolder holder, final int position) {
    holder.textView.setText(names.get(position).textView);
    holder.favourite.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(view.getContext());
            SharedPreferences.Editor editor = sp.edit();
            editor.putInt("key", position);  //may be or may not be.
            //add code here to save position in array
            Toast.makeText(view.getContext(),"Fav "+position,Toast.LENGTH_SHORT).show();
        }
    });

cardview.xml

<?xml version="1.0" encoding="utf-8"?>

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:orientation="vertical"
app:cardBackgroundColor="@android:color/transparent"
app:cardCornerRadius="8dp"
app:cardElevation="3dp"
app:cardPreventCornerOverlap="false"
app:cardUseCompatPadding="true">

<TextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingLeft="20dp"
    android:paddingTop="3dp"
    android:textAlignment="center"
    android:textColor="#ff9901"
    android:textSize="35sp"
    android:textStyle="italic" />

<RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:id="@+id/favourite"
        android:src="@drawable/star"
        android:background="@android:color/transparent"
        />
</RelativeLayout>
</android.support.v7.widget.CardView>

Provide me getting arraylist from prefrences and how to use in ListView too.


回答1:


First of all, consider to pass data in bundle through the intent. If you don't need to store this information after app closing, then use that way.

If you want to also save your data, through re-running the app, then SharedPreferences is fine, here is code, how you can implement this functionality. First let's write snippet that helps you to restore items and update adapter with them:

private static final String CHECKED_ITEMS_REF = "checked_items";
private SharedPreferences sharedPreferences = getContext().getSharedPreferences("MySharedPrefs", MODE_PRIVATE);

private void restoreAdapterState(RecyclerView.Adapter adapter) {
    Set<String> savedCheckedItems = sharedPreferences.getStringSet(CHECKED_ITEMS_REF, new HashSet<>());
    List<Integer> checkedPositions = convertToCheckedItems(savedCheckedItems);
    for (Integer position : checkedPositions) {
        //update somehow info about checked items, for example in 
        //adapter you can store set of checked positions and in
        //onBindViewHolder function check is ViewHolder position
        //contained in you set
        adapter.notifyItemChanged(position);
    }
}

private List<Integer> convertToCheckedItems(Set<String> checkedItems) {
    List<Integer> result = new ArrayList<>();
    for(String itemPositionStr : checkedItems) {
        int position = Integer.parseInt(itemPositionStr);
        result.add(position);
    }

    return result;
}

Note that you can follow my advise in comment and then restoreAdapterState will be modified:

private void restoreAdapterState(MultiCheckedAdapter adapter) {
    Set<String> savedCheckedItems = sharedPreferences.getStringSet(CHECKED_ITEMS_REF, new HashSet<>());
    List<Integer> checkedPositions = convertToCheckedItems(savedCheckedItems);
        adapter.setCheckedPositions(new HashSet<Integer>(checkedPositions));
}

And in MultyCheckedAdapter you will have something like:

private Set<Integer> checkedPositions = new HashSet<>();

public setCheckedPositions(Set<Integer> checkedPositions) {
    this.checkedPositions = checkedPositions;
    for (Integer position : checkedPositions) {
        adapter.notifyItemChanged(position);
    }
}

...

@Override
public void onBindViewHolder(MyHolder holder, final int position) {
    if (checkedPositions.contains(position)) {
        //use one binding
    } else {
        //use another binding
    }
}

...

Then you need to change your snippet:

private Set<Integer> checkedPositions = new HashSet<>();

public void onBindViewHolder(NameViewHolder holder, final int position) {
    holder.textView.setText(names.get(position).textView);
    holder.favourite.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //check somehow is current item checked or not.
            //for example store set of checked items in adapter
            //let's say it declaration is Set<Integer> checkedItems;
            if (checkedPositions.contains(position)) {
                checkedPositions.remove(position);
                removeCheckedItem(position);
            } else {
                checkedPositions.add(position);
                saveCheckedItem(position);
            }
        }
    });
}

private void saveCheckedItem(int position) {
    Set<String> savedCheckedItems = sharedPreferences.getStringSet(CHECKED_ITEMS_REF, new HashSet<>());
    String positionStr = String.valueOf(position);
    if (!savedCheckedItems.contains(positionStr)) {
        savedCheckedItems.add(positionStr);
        sharedPreferences.edit().putStringSet(CHECKED_ITEMS_REF, savedCheckedItems).apply();
    }
}

private void removeCheckedItem(int position) {
    Set<String> savedCheckedItems = sharedPreferences.getStringSet(CHECKED_ITEMS_REF, new HashSet<>());
    String positionStr = String.valueOf(position);
    if (savedCheckedItems.contains(positionStr)) {
        savedCheckedItems.remove(positionStr);
        sharedPreferences.edit().putStringSet(CHECKED_ITEMS_REF, savedCheckedItems).apply();
    }
}



回答2:


You can use a StringBuilder for this purpose. Append/Replace based on the item click and then save it to shared preference as a string.

    public void onBindViewHolder(NameViewHolder holder, final int position) {
   StringBuilder sb = new StringBuilder(sp.getStringPreference("key", ""))
    holder.textView.setText(names.get(position).textView);
    holder.favourite.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(view.getContext());
            SharedPreferences.Editor editor = sp.edit();
            sb.append(position);
            editor.putString("key", sb.toString()); 
            Toast.makeText(view.getContext(),"Fav "+position,Toast.LENGTH_SHORT).show();
        }
    });

Integer items can be retrieved from String using Integer.parseInt(s.charAt(index)); But if you need to just pass the values to next activity and don't need in future then you can use an ArrayList and pass it via Intent.




回答3:


After this line:

editor.putInt("key", position);

put this:

editor.apply();

I think you should add these value to a list instead, then pass the list to another activity, as a param, that will be a better approach.

Edit 2

// take a global string 
String positions = "";

 public void onClick(View view) {
            SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(view.getContext());
            SharedPreferences.Editor editor = sp.edit();
            /*   here first concat the current item position with the string, then put that in the pref  */
            positions = positions + position + " ";
            editor.putString("key", positions); 

        }



//in the next activity, 
String key = sp.getString("key");
String[] positions = key.split(" ");
// Now you have all the positions in the next activity and its in the String datatype
// if you wanna int datatype there, parse it through Integer.parseInt(string).



回答4:


use this to store

SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(view.getContext().MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putInt("key", position);  //may be or may not be.
editor.commit;

and in your other activity use this to retrieve

SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(view.getContext().MODE_PRIVATE);
            int position=sp.getInt("key");

you may also try this Like in your Activity A Create a Intent of Activity B

Intent intent =new Intent(A.this,B.class);
intent.putExtra("key",position);
startActivity(intent);

in your activity B

Intent intent= getIntent();
int position Integer.parseInt(intent.getExtras().get("key"));

EDIT

use the arraylist and transfer it from one activity to another

 ArrayList<Integer> mThumbIds=new ArrayList<Integer>() ;
    mThumbIds.add(R.drawable.sample_0);
            mThumbIds.add(R.drawable.sample_1);
            mThumbIds.add(R.drawable.sample_2);
            mThumbIds.add(R.drawable.sample_3);
            mThumbIds.add(R.drawable.sample_4);
            mThumbIds.add(R.drawable.sample_5);
            mThumbIds.add(R.drawable.sample_6);
            mThumbIds.add(R.drawable.sample_7);
 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                ArrayList list=mThumbIds;
                Intent intent= new Intent(A.this,B.class);
                       intent.putExtra("list",mThumbIds);
                intent.putExtra("position",position);
                intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
               //   overridePendingTransition(R.anim.hold,R.anim.slide_in_left);
                    startActivity(intent);




            }
        });

now use this in your ativity B

    Intent intent =getIntent();


        int position=Integer.parseInt(intent.getExtras().get("position").toString());
        ArrayList<Integer> list= (ArrayList<Integer>) intent.getExtras().get("list");

int current_position=list.get(position)


来源:https://stackoverflow.com/questions/39115550/storing-list-of-position-in-sharedpreferences-and-retrieve-in-another-activity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!