【问题标题】:Item Position in RecyclerView and SharedPreferencesRecyclerView 和 SharedPreferences 中的项目位置
【发布时间】:2020-11-17 22:17:33
【问题描述】:

我有一个 RecyclerView ,当用户单击任何项​​目时,它将打开一个用户必须完成一些任务的活动,如果用户完成了任务,它将被记录在 SharePrefrences 中(到这里没有问题)然后如果用户返回到 recyclerView,我已经在布局中定义的图像将是可见的,这意味着这一步已经完成。但是当用户完成任务后返回到 recyclerView 时,问题就来了

例如,我点击item 1,完成所有任务然后返回recyclerView,除了item 1,item 8、16、24 也能看到图片。 这是查看的必要代码:

在任务活动中:

private void trophyGiftRecycler() {

        if ((Integer)img_test1_p1.getTag()==R.drawable.alph1_a) {
            SharedPreferences prefs1 = getSharedPreferences("prefs1", MODE_PRIVATE);
            boolean letter1 = prefs1.getBoolean("letter1", true);
            if (letter1) {
                trophyShared();
            }
        }
}

private void trophyShared() {

        if ((Integer)img_test1_p1.getTag()==R.drawable.alph1_a) {
            SharedPreferences prefs1 = getSharedPreferences("prefs1", MODE_PRIVATE);
            SharedPreferences.Editor editor = prefs1.edit();
            editor.putBoolean("letter1", true);
            editor.apply();
        }
}

In the MainAdapter

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

        holder.itemLetter.setImageResource(mainModelAlphabets.get(position).getItemImages());
        holder.itemTxt.setImageResource(mainModelAlphabets.get(position).getItemTxt());

        holder.itemLetter.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if(canStart) {
                    canStart = false; // do canStart false
                    // Do what you don't want to run twice due to double tap

                    if (position==0){

                        Activity activity = (Activity) context;
                        Intent intent = new Intent(context,Alphabet2.class);
                        intent.putExtra("alphabet_word1",R.drawable.alphabet_a1);
                        intent.putExtra("alphabet_word2",R.drawable.alphabet_a2);
                        intent.putExtra("alphabet_word3",R.drawable.alphabet_a3);
                        activity.startActivity(intent);
                        activity.overridePendingTransition(R.anim.activity_slide_in_left,R.anim.activity_slide_out_right);

                        Runtime.getRuntime().gc();
                        activity.onBackPressed();
                    }

                    if (position==1){

                        Activity activity = (Activity) context;
                        Intent intent = new Intent(context,Alphabet2.class);
                        intent.putExtra("alphabet_word1",R.drawable.alphabet_b1);
                        intent.putExtra("alphabet_word2",R.drawable.alphabet_b2);
                        intent.putExtra("alphabet_word3",R.drawable.alphabet_b3);
                        activity.startActivity(intent);
                        activity.overridePendingTransition(R.anim.activity_slide_in_left,R.anim.activity_slide_out_right);

                        Runtime.getRuntime().gc();
                        activity.onBackPressed();
                    }

        });

        setAnimation(holder.itemView,position);


        SharedPreferences prefs1 = context.getSharedPreferences("prefs1", MODE_PRIVATE);
        SharedPreferences prefs2 = context.getSharedPreferences("prefs2", MODE_PRIVATE);

        boolean letter1 = prefs1.getBoolean("letter1", false);
        boolean letter2 = prefs2.getBoolean("letter2", false);


        if (letter1){
            if (position==0){
                holder.itemTrophy.setVisibility(View.VISIBLE);
            }
        }

        if (letter2){
            if (position==1){
                holder.itemTrophy.setVisibility(View.VISIBLE);
            }
        }

    }

如您所见,它应该在位置 1 或 2 中可见,但在其他位置可见(不是全部_也是如此。

【问题讨论】:

  • 也添加 Else 部分。在onBindViewHolder 内。您设置了 if 部分的可见性,但没有设置 else 部分。
  • 这也将使图像在其他视图中不可见。

标签: java android


【解决方案1】:

查看这个sn-p,添加到onBindViewHolder的底部

boolean letter1 = prefs1.getBoolean("letter1", false);
boolean letter2 = prefs2.getBoolean("letter2", false);

if ((letter1 || letter2) && position==1) {
    holder.itemTrophy.setVisibility(View.VISIBLE);
}
else holder.itemTrophy.setVisibility(View.GONE);

查看RecyclerView 的工作原理以及在 Android 方面什么是回收。简而言之:Views/list 项目在某些项目滚动到屏幕外然后相同的View 从另一侧进入时被重用(滚动到顶部将显示在底部作为下一个列表项)。你没有设置View.GONE,所以回收的列表项仍然有View.VISIBLE作为你的奖杯图标

编辑:

简单的方法

if (position==1){
    holder.itemTrophy.setVisibility(letter1 ? View.VISIBLE : View.GONE);
}

更复杂

SharedPreferences prefs = context.getSharedPreferences("prefs" + (position+1), MODE_PRIVATE);
boolean letterSet = prefs.getBoolean("letter" + (position+1), false);
holder.itemTrophy.setVisibility(letterSet ? View.VISIBLE : View.GONE);

【讨论】:

  • else 语句也会使图像在其他视图中不可见。
  • else 语句将隐藏itemTrophy 用于特定position 的列表项,不是全部,这不是您需要的吗?另一种情况是您在 "letter1""letter2" 变量下存储的内容以及当满足 if 语句时
  • if ((letter1) && position==0){ itemView.itemTrophy.setVisibility(View.VISIBLE); } else { itemView.itemTrophy.setVisibility(View.INVISIBLE); }
  • 在有问题的代码中,letter1position==0 之间没有关系——letter 标志都与 position==1 相关(逻辑错误?)。当您了解回收的工作原理时,适合if else 的适当环境将不是问题
  • 我有 26 个 boolean letter1,2,3,...,26,当满足 letter1 条件时,它将让奖杯在回收站视图中可见,在 else 语句中你说它将不可见其余的,例如,如果您之后获得字母 2 的奖杯,那么它只会让位置 1 的奖杯可见,而其余的则不可见,因此在这种情况下,字母 1 也是不可见的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多