【问题标题】:How to make add to favorites button using share preferences but without any database in android?如何使用共享首选项添加到收藏夹按钮但在android中没有任何数据库?
【发布时间】:2023-03-25 10:10:02
【问题描述】:

我正在使用共享首选项创建切换按钮以添加到收藏夹功能,但是当我单击按钮以添加到收藏夹时它不起作用但是当我移回另一个活动并返回此活动时我的按钮未选中,当我再次点击时,它的说法已从收藏夹中删除,但它应该被标记为收藏,因为我已经将其标记为收藏

XML

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".BenefitDescriptionActivity">

    <ToggleButton
        android:id="@+id/favouritetogglebuttonID"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="5dp"
        android:textOff=""
        android:textOn=""
        app:layout_constraintBottom_toTopOf="@+id/benefitdescriptionscrollviewID"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/benefitimageviewID" />

</android.support.constraint.ConstraintLayout>

Java

import android.content.Context;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import android.widget.ToggleButton;

import static android.text.Html.FROM_HTML_MODE_COMPACT;

public class BenefitDescriptionActivity extends AppCompatActivity {

    private ToggleButton favouriteToggleButton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_benefit_description);

        favouriteToggleButton = (ToggleButton)findViewById(R.id.favouritetogglebuttonID);
        favouriteToggleButton.setBackgroundDrawable(ContextCompat.getDrawable(getApplicationContext(),R.drawable.ic_favorite_border_black_24dp));
        favouriteToggleButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                boolean isFavourite = readstate();
                if (isFavourite) {                 favouriteToggleButton.setBackgroundDrawable(ContextCompat.getDrawable(getApplicationContext(),R.drawable.ic_favorite_black_24dp));
Toast.makeText(BenefitDescriptionActivity.this,"Added to favorites",Toast.LENGTH_SHORT).show();
                    isFavourite = false;
                    savestate(isFavourite);
                }
                else {
                    favouriteToggleButton.setBackgroundDrawable(ContextCompat.getDrawable(getApplicationContext(),R.drawable.ic_favorite_border_black_24dp));
Toast.makeText(BenefitDescriptionActivity.this,"Removed from favorites",Toast.LENGTH_SHORT).show();
                    isFavourite = true;
                    savestate(isFavourite);
                }
            }
        });

    private void savestate(boolean isFavourite){
        SharedPreferences aSharedPreferences = this.getSharedPreferences("Favourite", Context.MODE_PRIVATE);
        SharedPreferences.Editor aSharedPreferencesEdit = aSharedPreferences.edit();
        aSharedPreferencesEdit.putBoolean("State",isFavourite);
        aSharedPreferencesEdit.apply();
    }
    private boolean readstate(){
        SharedPreferences asharedPreferences = this.getSharedPreferences("Favourite",Context.MODE_PRIVATE);
        return asharedPreferences.getBoolean("State",true);
    }
}

【问题讨论】:

  • readstate() 的返回值是什么?当您返回切换活动时,它是否返回正确的值?

标签: java android sharedpreferences


【解决方案1】:

返回活动时,您似乎没有设置存储的值。您需要在onResume 中检查并设置它。还可以像这样更改onClickListener 中的代码:

  favouriteToggleButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    boolean isFavourite = readstate();
                    if (!isFavourite) {                 favouriteToggleButton.setBackgroundDrawable(ContextCompat.getDrawable(getApplicationContext(),R.drawable.ic_favorite_black_24dp));
                        Toast.makeText(BenefitDescriptionActivity.this,"Added to favorites",Toast.LENGTH_SHORT).show();
                        isFavourite = true;
                        savestate(isFavourite);
                    }
                    else {
                        favouriteToggleButton.setBackgroundDrawable(ContextCompat.getDrawable(getApplicationContext(),R.drawable.ic_favorite_border_black_24dp));
                        Toast.makeText(BenefitDescriptionActivity.this,"Removed from favorites",Toast.LENGTH_SHORT).show();
                        isFavourite = false;
                        savestate(isFavourite);
                    }
                }
            });


        }
        private void savestate(boolean isFavourite){
            SharedPreferences aSharedPreferences = this.getSharedPreferences("Favourite", Context.MODE_PRIVATE);
            SharedPreferences.Editor aSharedPreferencesEdit = aSharedPreferences.edit();
            aSharedPreferencesEdit.putBoolean("State",isFavourite);
            aSharedPreferencesEdit.apply();
        }
        private boolean readstate(){
            SharedPreferences asharedPreferences = this.getSharedPreferences("Favourite",Context.MODE_PRIVATE);
            return asharedPreferences.getBoolean("State",false);
        }

        @Override
        protected void onResume() {
            super.onResume();
            boolean isFavourite = readstate();
            Log.e("main","value = " + isFavourite);
            if (!isFavourite) {
                favouriteToggleButton.setBackgroundDrawable(ContextCompat.getDrawable(getApplicationContext(),R.drawable.ic_favorite_border_black_24dp));
            }
            else {
                favouriteToggleButton.setBackgroundDrawable(ContextCompat.getDrawable(getApplicationContext(),R.drawable.ic_favorite_black_24dp));
            }
        }

【讨论】:

  • 第一次点击显示已从收藏夹中删除(已为空)
  • 我也按了两次来获取我一直使用的吐司笔记,我一直在使用按钮而不是切换,它甚至没有保存结果
【解决方案2】:

您总是为您的 favouriteToggleButton 设置一个固定的背景,您需要读取您的 SharedPreferences State 值并为您的 favouriteToggleButton 设置一个背景,只需将这些行添加到您的活动中

  @Override
    protected void onResume() {
        super.onResume();
        if (! readstate()) {
            favouriteToggleButton.setBackgroundDrawable(ContextCompat.getDrawable(getApplicationContext(),R.drawable.ic_favorite_border_black_24dp));
        }
        else {
            favouriteToggleButton.setBackgroundDrawable(ContextCompat.getDrawable(getApplicationContext(),R.drawable.ic_favorite_black_24dp));
        }

【讨论】:

    【解决方案3】:

    尝试设置

        favouriteButton.setChecked(true);   //or false depending
    

    在你的 onClickListener

    【讨论】:

      【解决方案4】:

      我在代码中添加了一些注释,这些注释可以帮助您的应用更好地执行。

      并且在代码中,您可以将 AsyncTask 替换为其他工具。

      只是阻止在 UI 线程中执行 IO 工作。

      import android.content.Context;
      import android.content.SharedPreferences;
      import android.os.AsyncTask;
      import android.os.Bundle;
      import android.support.v4.content.ContextCompat;
      import android.support.v7.app.AppCompatActivity;
      import android.view.View;
      import android.widget.Toast;
      import android.widget.ToggleButton;
      
      import java.lang.ref.WeakReference;
      
      public class BenefitDescriptionActivity extends AppCompatActivity {
      
          private ToggleButton favouriteToggleButton;
          private boolean favourite = false;
          private CheckAsyncTask task;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_benefit_description);
      
              favouriteToggleButton = (ToggleButton) findViewById(R.id.favouritetogglebuttonID);
              favouriteToggleButton.setBackgroundDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.ic_favorite_border_black_24dp));
              favouriteToggleButton.setOnClickListener(new View.OnClickListener() {
                  @Override
                  public void onClick(View v) {
      
                      //use a variable, not read file every time click
                      if (favourite) {
                          favouriteToggleButton.setBackgroundDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.ic_favorite_black_24dp));
                          Toast.makeText(BenefitDescriptionActivity.this, "Added to favorites", Toast.LENGTH_SHORT).show();
                          favourite = false;
                          savestate(favourite);
                      } else {
                          favouriteToggleButton.setBackgroundDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.ic_favorite_border_black_24dp));
                          Toast.makeText(BenefitDescriptionActivity.this, "Removed from favorites", Toast.LENGTH_SHORT).show();
                          favourite = true;
                          savestate(favourite);
                      }
                  }
              });
          }
      
          @Override
          public void onResume() {
              super.onResume();
              //when activity visible, read boolean value from file and set button state
              if (task == null) {
                  task = new CheckAsyncTask(favouriteToggleButton);
              }
              task.execute();
          }
      
          @Override
          protected void onStop() {
              super.onStop();
              //stop task when activity invisible, prevent memory leak
              if (task != null) {
                  task.cancel(true);
              }
          }
      
          // you also can execute savestate in a background thread
          private void savestate(boolean isFavourite) {
              SharedPreferences aSharedPreferences = getSharedPreferences("Favourite", Context.MODE_PRIVATE);
              SharedPreferences.Editor aSharedPreferencesEdit = aSharedPreferences.edit();
              aSharedPreferencesEdit.putBoolean("State", isFavourite);
              aSharedPreferencesEdit.apply();
          }
      
          private static class CheckAsyncTask extends AsyncTask<Void, Void, Boolean> {
      
              private WeakReference<ToggleButton> buttonWeakReference;
      
              public CheckAsyncTask(ToggleButton button) {
                  buttonWeakReference = new WeakReference<>(button);
              }
      
              @Override
              protected Boolean doInBackground(Void... voids) {
                  //do you read file job in background thread may perform better
                  if (buttonWeakReference.get() != null) {
                      SharedPreferences asharedPreferences = buttonWeakReference.get().getContext().getSharedPreferences("Favourite", Context.MODE_PRIVATE);
                      favorite = asharedPreferences.getBoolean("State", true);
                      return favorite;
                  }
      
                  return false;
              }
      
              @Override
              protected void onPostExecute(Boolean aBoolean) {
                  super.onPostExecute(aBoolean);
                  //got read file result set Button state in UI thread
                  if (aBoolean && buttonWeakReference != null && buttonWeakReference.get() != null) {
                      buttonWeakReference.get().setBackgroundDrawable(ContextCompat.getDrawable(getApplicationContext(), R.drawable.ic_favorite_black_24dp));
                  }
              }
          }
      
      }
      
      

      【讨论】:

      • 你是说我们需要在每次活动恢复时使用AsyncTask,我们从 sharedpref 中获取价值?
      • @sanjeev 不完全是,使用AsyncTask只是想在后台线程中进行IO操作。把读取逻辑放在onResume()中只是一个例子,你可以把它放在按钮创建后的onCreate(),onPostCreate(),onCreateView()
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多