SharedPreferences 和 ViewPager 唯一键

SharedPreferences and ViewPager Unique Key

在学校,我们必须开发我们的第一个 Android 应用程序。 Android 对我来说是新手,我来这里是为了学习一些东西。

今天我第一次使用 SharedPreferences 来保存有关 ImageButton 状态的信息。该布局使用 ViewPager。用户可以滑动 10 个项目。 ViewPager 包含一个对项目进行计数的 TextView。效果很好:例如第一项的 TextView 显示 [1/10],最后一项显示 [10/10]。在 TextView 之后,您可以找到一张图片。那效果也不错。

现在解决我的问题:我在图像下安装了一个 ImageButton。它表示某个项目是否是最喜欢的。最喜欢的被描绘成红色的心,没有最喜欢的是灰色的心(默认 ImageResource)。

这是我的ViewPager的主布局:

<android.support.v4.view.ViewPager
    android:id="@+id/image_swipe"
    android:layout_width="match_parent"
    android:layout_height="590dp"
    android:layout_marginTop="130dp" />

这是 寻呼机布局:

<TextView
    android:id="@+id/image_count"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:text="Here we count..."
    android:textColor="@android:color/black"
    android:textSize="16sp" />

<ImageView
    android:id="@+id/swipe_image"
    android:layout_width="match_parent"
    android:layout_height="365dp"
    android:layout_marginBottom="20dp"
    android:layout_marginLeft="30dp"
    android:layout_marginRight="30dp"
    android:layout_marginTop="30dp"
    android:adjustViewBounds="false"
    android:onClick="onClickImage" />

<ImageButton
    android:id="@+id/favourite_button"
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:layout_gravity="center"
    android:background="@android:color/transparent"
    android:scaleType="fitCenter"
    android:src="@drawable/heart"
    android:onClick="onClickFav" />

所有项目都需要一个 唯一键 才能保存每个项目的 ImageButton 状态。密钥由字符串 "fav" 和一个计数器(可以是 1-10)组成。这意味着我们有 10 个唯一键:fav1 - fav10。当为给定的项目位置创建页面时,我尝试检查是否为给定的键存储了一些东西。

一个键后面可以有2个可能的值:0和1。0表示没有最喜欢的,1是最喜欢的。如果尚未设置任何键,则该值将为 0,这是默认的 ImageButton 状态。拿到item key的值后,就可以设置ImageButton的ImageResource了。

创建页面的下一步是保存新密钥。该键的名称为 "count" 并指示此时加载的项目。

我刚才告诉你的都在这个适配器方法中 (instantiateItem):

     /*
        Create the page for the given position
        Set image resources and text about current position
     */
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View item_view = layoutInflater.inflate(R.layout.swipe_layout,container,false);
        ImageView imageView = (ImageView) item_view.findViewById(R.id.swipe_image);
        TextView textView = (TextView) item_view.findViewById(R.id.image_count);
        ImageButton imageButton = (ImageButton) item_view.findViewById(R.id.favourite_button);

        imageView.setImageResource(image_resources[position]);
        textView.setText("["+(position+1)+"/10]");

        SharedPreferences prefs = context.getSharedPreferences("favInfo", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();

        // get the unique key consisting of fav and the current item position
        String key = "fav" + (position+1);

        String value = prefs.getString(key, "0");

        // check if value of favorite key is 0
        // set image resource dependent on what value is set
        if (value.equals("1")) {
            imageButton.setImageResource(R.drawable.heart_red);
        } else {
            imageButton.setImageResource(R.drawable.heart);
        }

        int p = (position+1);
        String count = Integer.toString(p);

        // store index of current adapter item as shared pref
        editor.putString("count", count);
        editor.commit();

        container.addView(item_view);

        return item_view;
    }

这是加载项目的时间。之后,用户可以单击 ImageButton,它会在主 activity:

中按照 onClick 方法 激活
/*
    Method for click actions on the favorite button
    @heart grey heart symbolizes no favorite (flag 0)
    @heart_red red heart symbolizes marked as favorite (flag 1)
*/
public void onClickFav(View v) {
    ImageButton favouriteButton = (ImageButton) findViewById(R.id.favourite_button);

    SharedPreferences prefs = getSharedPreferences("favInfo", MODE_PRIVATE);
    SharedPreferences.Editor editor = prefs.edit();

    // get the count value of the item which is loaded at the moment
    String count = prefs.getString("count", "");

    // get the unique key consisting of fav and the count text
    String key = "fav" + count;

    // get value stored with that key, default: if no value exists take 0
    String value = prefs.getString(key, "0");

    // check if value of favorite key is 0,
    // set image resource dependent on what value is stored behind the key
    if (value.equals("0")) {
        favouriteButton.setImageResource(R.drawable.heart_red);
    } else {
        favouriteButton.setImageResource(R.drawable.heart);
    }

    String isFav;

    // switch value to opposite
    if (value.equals("0")) {
        isFav = "1";
    } else {
        isFav = "0";
    }

    // store shared preferences
    editor.putString(key, isFav);
    editor.commit();
}

基本上我在这里做的是:获取当前项目("count" 键)并用它构建唯一键。然后检查它后面的值并相应地设置 ImageResource。之后我将值更改为相反并保存唯一键。

我的问题: 发生了一些事情,但不是正确的事情。当用户点击 ImageButton 时,之前的 item 的 ImageButton 会发生变化。例如用户单击项目 7 的 ImageButton。不是项目 7 的 ImageButton 更改,而是项目 6 或 8 的 ImageButton。

问题是每次刷屏都不会调用instantiateItem()。 当加载第一个 activity 时,您的适配器会实例化每个寻呼机布局。 对了,主要的activity期望每次屏幕变化时调用instantiateItem()

所以,不是在instantiateItem()中更新计数,而是需要找到一个每次切换屏幕时调用的方法。 例如,您可以检测分页器标签栏中的转换并执行以下操作:

navigationTabBar.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageSelected(final int position) {
            // set "count" this position
        }
    });

P.S
为了高效处理,最好将选择的屏幕索引直接传递给activity,而不是每次切换屏幕时都使用首选项。

你的问题是你在 SharedPreferences 中使用 "count" 值,它一直覆盖适配器,所以你必须更新现有的键值,所以你说你使用

创建键
String key = "fav" + count;

但在更新中你只是更新随机计数

// get the count value of the item which is loaded at the moment
    String count = prefs.getString("count", "");
     String key = "fav" + count;

所以你的键在这里不匹配所以做一件事添加位置作为 imagebutton 的标签,如 instantiateItem 方法添加下面的行

// get the unique key consisting of fav and the current item position
        String key = "fav" + (position+1);
    imageButton.setTag(key)

现在 onClick

替换

// get the unique key consisting of fav and the count text
    String key = "fav" + count;

// get the unique key consisting of fav and the count text
        String key =v.getTag().toString();

您也不需要在 onClick

中查找按钮

替换

ImageButton favouriteButton = (ImageButton) findViewById(R.id.favourite_button);

 ImageButton favouriteButton = (ImageButton)v; 

因为已经是同一个按钮的点击事件和实例

此外,此共享偏好方法仅适用于固定图像,对于动态图像,最好使用 SQLite。

编辑

用于将当前位置发送到新 activity

在您的 instantiateItem 方法中设置

    ImageView imageView = (ImageView) item_view.findViewById(R.id.swipe_image);
 imageView.setTag(postion);//set tag as current position

/*
    Method for click actions on the suggestion image
*/


 public void onClickImage(View v){


        Intent detailIntent = new Intent(activity, DetailActivity.class);
        detailIntent.putExtra("key_position",Integer.parseInt(v.getTag().toString()));///get tag and send it as int extra
        startActivity(detailIntent);
    }

现在在新 activity oncreate

/* onCreate method in new activity (DetailActivity) */ 

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);

        ImageView imageView = (ImageView) findViewById(R.id.swipe_image);

        Toolbar sToolbar = (Toolbar) findViewById(R.id.detail_toolbar);
        setSupportActionBar(sToolbar);




        int count = getIntent().getIntExtra("key_position",0);//get int extra from calling activity

        TextView headline = (TextView) findViewById(R.id.island_name);
        ImageView image = (ImageView) findViewById(R.id.detailImage);
        TextView description = (TextView) findViewById(R.id.description);

        headline.setText(island_name[count]);
        image.setImageResource(image_resources[count]);
        description.setText(description_text[count]);
    }