【问题标题】:Storing list of position in sharedPreferences, and retrieve in another activity在 sharedPreferences 中存储位置列表,并在另一个活动中检索
【发布时间】:2016-08-24 06:07:04
【问题描述】:

我想做类似this 的事情,我使用了cardview 和recyclerview。我在下面添加了最喜欢的按钮卡片视图,您可以看到完整的代码。在 recyclerview 适配器中,我根据位置打印 Toast 并且它工作正常,现在我需要将位置的 int 值保存在 arraylist 中的共享首选项中,并在下一个意图中显示这些 arraylist。

这是我的 recyclerview 适配器

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>

提供我从首选项中获取数组列表以及如何在 ListView 中使用。

【问题讨论】:

  • 你能添加你的活动java代码吗?
  • 我需要发布哪部分代码?我已经发布了我如何调用收藏按钮。如果在列表中按下收藏按钮,则应将项目添加到 sharedprefrences 中。

标签: android sharedpreferences android-adapter android-recyclerview android-sharedpreferences


【解决方案1】:

首先,考虑通过intent以bundle的形式传递数据。如果您在关闭应用后不需要存储此信息,请使用该方式。

如果您还想通过重新运行应用程序来保存数据,那么 SharedPreferences 就可以了,这里是代码,您如何实现此功能。首先让我们编写帮助您恢复项目并使用它们更新适配器的 sn-p:

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;
}

请注意,您可以在评论中遵循我的建议,然后 restoreAdapterState 将被修改:

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));
}

MultyCheckedAdapter 中,您将拥有类似的内容:

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
    }
}

...

那么你需要改变你的sn-p:

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();
    }
}

【讨论】:

  • 我试过你的代码,但它对我来说太复杂了。因为我是安卓新手。无论如何,谢谢迈克尔
  • 对你来说到底有什么困难?如果您使用列表和共享状态编写您的第一个应用程序,那么您必须了解列表、适配器、共享首选项是如何工作的。你也必须知道,如何用java编写程序。如果我们假设,那么对您来说到底有什么困难?我可以编辑我的答案并解释这些误解
  • 你有四个部分的代码。我真的很困惑把它们放在哪里? HashSet 是做什么的? set 在做什么?所有这些东西都很复杂,第一次听到谢谢??你能告诉我,在 sharedPrefrences Context.Mode_APPEND 中是用于附加值而不是替换值吗?那我们为什么不在这里使用呢?我认为使用 Mode_APPEND 将是干净的代码?
  • 我使用私有模式,不允许其他应用程序访问您的共享首选项。那么关于,不好意思,Java 7 早就引入了,在Java 6 中你必须写Set&lt;String&gt; mySet = new HashSet&lt;String&gt;();,在Java 7 中你可以写Set&lt;String&gt; mySet = new HashSet&lt;&gt;();。至于最后一部分,您需要放置在您的 sn-p 中。您的自定义适配器中的第三部分(我只是使用了我的名字),第二部分是第一部分的增强部分。您需要将第一部分放在第二个 Activity 或其他内容中,在其中构建新的列表视图,或者您在那里拥有什么。
  • @Queendevelopers 抱歉,我不能为您编写整个程序,我只是解释了如何解决您的问题。在我看来,您的问题似乎表明您需要查看整个程序,但它现在就像这样工作,它是 stackoverflow。所以,对不起,我的粗鲁,但我建议你阅读更多关于 java 和 android 的教程。
【解决方案2】:

您可以为此目的使用 StringBuilder。根据项目单击追加/替换,然后将其作为字符串保存到共享首选项。

    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.parseInt(s.charAt(index)); 从 String 中检索整数项。 但是,如果您只需要将值传递给下一个活动并且以后不需要,那么您可以使用 ArrayList 并通过 Intent 传递它。

【讨论】:

  • sp 没有找到你在 secondLine 的 StringBuilder 中定义的?
  • sp 是您的共同偏好,您可以将其设为全局。
  • 好的,太好了,我回家后会试一试,我会回复你的! ;)
【解决方案3】:

这一行之后:

editor.putInt("key", position);

这样写:

editor.apply();

我认为您应该将这些值添加到列表中,然后将列表作为参数传递给另一个活动,这将是一种更好的方法。

编辑 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).

【讨论】:

  • 是的,如果我确实添加了 editor.putInt("key',position); 只会添加一个值,不是吗?在列表中,用户可能会单击多个列表项,因此我需要发送多个位置。我该怎么做?
  • 我觉得list会更好,在构造函数中初始化一个ArrayList list,当用户点击item时,list.add(position); ,每当您想将用户重定向到下一个活动时,将列表放在构造函数中,将其分配给下一个活动中的新列表...需要更多帮助吗?
  • 请您用密码回答好吗?我是新手。而且我需要保存在 sharedPrefrences 中,以便用户以后可以看到他们喜欢的项目。
  • 我需要保存在 sharedPrefrences 中。
  • 也许这可能有效,我会试试这个并通知你@zee433
【解决方案4】:

用它来存储

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;

并在您的其他活动中使用它来检索

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

你也可以试试这个 就像在你的活动 A 创建Activity B的Intent

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

在你的活动 B

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

编辑

使用数组列表并将其从一个活动转移到另一个活动

 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);




            }
        });

现在在你的活动 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)

【讨论】:

  • 如果我点击另一个,这将替换 sharedPrefrences 中的值,我需要所有点击的值,为此它可能需要 Context.MODE_APPED?要不然是啥?请重新编辑您的答案
  • 为了什么目的你想要所有的位置
  • 我已经在我的问题中上传了上面的教程链接。我想做一样的,但是那个教程对我来说太难了,因为我是新手,所以我要求一个简单的,以便我能很好地理解
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-13
相关资源
最近更新 更多