android - 基于 bool 值更改适配器类中回收器 View 中按钮的图标

标签 android button android-recyclerview

每次 Activity 根据自定义对象中的 bool 值启动时,我都试图更改回收站 View 中按钮的图标。我认为这必须在适配器内完成,因为并非每个组按钮都具有相同的背景。

下面是我的回收器 View 适配器的代码:

public class RecipeListAdapter extends RecyclerView.Adapter<RecipeListAdapter.ViewHolder>{

    private List<Recipe> mRecipeSet;
    private Button mAddToGroceriesButton;


    public RecipeListAdapter(List<Recipe> recipes){
        mRecipeSet = recipes;
    }

    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        //This is what will handle what happens when you click a recipe in the recycler view


        private TextView mRecipeName;
        private TextView mPrepTime;
        private TextView mCookTime;
        private TextView mServingSize;
        private RelativeLayout mRecipeTextSection;


        public ViewHolder(View v) {
            super(v);
            mRecipeName = (TextView) v.findViewById(R.id.recipe_list_recycler_view_recipe_name);
            mServingSize = (TextView) v.findViewById(R.id.recipe_list_recycler_view_serving_size);
            mPrepTime = (TextView) v.findViewById(R.id.recipe_list_recycler_view_prep_time);
            mCookTime = (TextView) v.findViewById(R.id.recipe_list_recycler_view_cook_time);
            mRecipeTextSection = (RelativeLayout) v.findViewById(R.id.recycled_item_section_view);

            mRecipeTextSection.setOnClickListener(this);

            mAddToGroceriesButton = (Button) v.findViewById(R.id.add_to_grocery_list);
            mAddToGroceriesButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int position = getAdapterPosition();
                    Recipe recipeToGrocery = mRecipeSet.get(position);

                    //RecipeDB dbHelper = new RecipeDB(v.getContext());
                    //dbHelper.addGroceryItem(recipeToGrocery);

                    if(!recipeToGrocery.isInList()) {
                        RecipeDB dbHelper = new RecipeDB(v.getContext());
                        dbHelper.addGroceryItem(recipeToGrocery);

                        recipeToGrocery.setInList(true);
                        dbHelper.updateRecipe(recipeToGrocery);
                        mAddToGroceriesButton.setBackgroundResource(R.mipmap.ic_playlist_add_check_black_24dp);
                        Toast.makeText(v.getContext(), recipeToGrocery.getRecipeName() + " added to grocery list.", Toast.LENGTH_SHORT).show();
                    }
                    else {
                        Toast.makeText(v.getContext(), "That recipe is already in the list.", Toast.LENGTH_SHORT).show();
                    }

                }
            });

        }

        @Override
        public void onClick(View v){
            int position = getAdapterPosition();
            Intent i = new Intent(v.getContext(), RecipeTextView.class);
            Recipe selectedRecipe = mRecipeSet.get(position);
            i.putExtra("view_recipe_key", selectedRecipe);
            v.getContext().startActivity(i);
        }

    }


    public void add(int position, Recipe item) {
        mRecipeSet.add(position, item);
        notifyItemInserted(position);
    }

    public void remove(Recipe item) {
        int position = mRecipeSet.indexOf(item);
        mRecipeSet.remove(position);
        notifyItemRemoved(position);
    }



    public RecipeListAdapter(ArrayList<Recipe> myRecipeset) {
        mRecipeSet = myRecipeset;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public RecipeListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // create a new view
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recipe_item_recycled, parent, false);
        ViewHolder vh = new ViewHolder(v);
        return vh;

    }


    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Recipe recipe = mRecipeSet.get(position);
        String recipeName = recipe.getRecipeName();
        String prepTime = "Prep Time: " + String.valueOf(recipe.getPrepTime()) + " minutes";
        String cookTime = "Cook Time: " + String.valueOf(recipe.getCookTime()) + " minutes";
        String servingSize = "Servings: " + String.valueOf(recipe.getServings());

        holder.mRecipeName.setText(recipeName);

        //Only display values if they are not null
        if(recipe.getServings() != null) {
            holder.mServingSize.setText(servingSize);
        }
        if (recipe.getPrepTime() != null) {
            holder.mPrepTime.setText(prepTime);
        }
        if(recipe.getCookTime() != null) {
            holder.mCookTime.setText(cookTime);
        }


    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        if(mRecipeSet != null) {
            return mRecipeSet.size();
        }
        return 0;
    }



}  

我知道如何在单击按钮时更改按钮的背景

mAddToGroceriesButton.setBackgroundResource(R.mipmap.ic_playlist_add_check_black_24dp);

但它显然不会在 Activity 重新启动时保存该按钮的状态。我只是不确定如何在 Activity 启动时检查每个组的 bool 值并相应地更改按钮背景。

我试过用

if(recipe.isInList()){
            mAddToGroceriesButton.setBackgroundResource(R.mipmap.ic_playlist_add_check_black_24dp);
        }

在 onBindViewHolder 方法中,但它什么也没做,而且我很确定无论如何这都不是正确的位置。我知道 bool 值工作正常,因为我在其他地方使用它并且工作正常。

这是相关的 XML 代码:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/apk/res/android"
    android:layout_margin="7dp"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="10dp"
    android:id="@+id/recycled_item_section_view"
    android:elevation="30dp"
    android:background="@drawable/background_border"
    >


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:text="Recipe name"
        android:textSize="24dp"
        android:textColor="@color/black"
        android:id="@+id/recipe_list_recycler_view_recipe_name"
        android:paddingBottom="3dp"
        android:maxWidth="275dip"
        android:singleLine="false"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="18dp"
        android:textColor="@color/black"
        android:layout_below="@id/recipe_list_recycler_view_recipe_name"
        android:id="@+id/recipe_list_recycler_view_serving_size"
        android:paddingBottom="3dp"/>

    <Button
        android:layout_width="35dp"
        android:layout_height="35dp"
        android:background="@mipmap/ic_playlist_add_black_24dp"
        android:height="36dp"
        android:padding="8dp"
        android:layout_alignParentRight="true"
        android:id="@+id/add_to_grocery_list"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true"
        />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/recipe_list_recycler_view_serving_size"
        android:layout_alignParentLeft="true"
        android:textSize="18dp"
        android:textColor="@color/black"
        android:id="@+id/recipe_list_recycler_view_prep_time"
        android:paddingBottom="3dp"
        />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/recipe_list_recycler_view_prep_time"
        android:textSize="18dp"
        android:textColor="@color/black"
        android:layout_alignParentLeft="true"
        android:id="@+id/recipe_list_recycler_view_cook_time"/>


</RelativeLayout> 

配方类:

public class Recipe implements Parcelable {

    //These are all of the qualities a recipe contains, we will create an arraylist of this in the activity
    private String mRecipeName;
    private int mID;
    private String mServings;
    private String mPrepTime;
    private String mCookTime;
    private boolean isInList;

    private List<String> mIngredients;
    private List<String> mDirections;


    public Recipe(){

    }

    public Recipe(int id, String name, String serving, String prep, String cook, List<String>
                  ingredientsList, List<String> directionsList, boolean inList){

        this.mID = id;
        this.mRecipeName = name;
        this.mServings = serving;
        this.mPrepTime = prep;
        this.mCookTime = cook;
        this.mIngredients = ingredientsList;
        this.mDirections = directionsList;
        this.isInList = inList;
    }

    public Recipe(String name, String serving, String prep, String cook, List<String>
            ingredientsList, List<String> directionsList, boolean inList){

        this.mRecipeName = name;
        this.mServings = serving;
        this.mPrepTime = prep;
        this.mCookTime = cook;
        this.mIngredients = ingredientsList;
        this.mDirections = directionsList;
        this.isInList = inList;
    }


    public String getRecipeName() {
        return mRecipeName;
    }

    public int getID() {
        return mID;
    }

    public void setID(int id){
        mID = id;
    }

    public String getServings() {
        return mServings;
    }

    public String getPrepTime() {
        return mPrepTime;
    }


    public void setRecipeName(String recipeName) {
        mRecipeName = recipeName;
    }

    public void setServingSize(String servings) {
        mServings = servings;
    }

    public void setPrepTime(String prepTime) {
        mPrepTime = prepTime;
    }

    public void setServings(String servings) {
        mServings = servings;
    }

    public List<String> getIngredients() {
        return mIngredients;
    }

    public List<String> getDirections() {
        return mDirections;
    }

    public String getCookTime() {
        return mCookTime;
    }

    public void setCookTime(String cookTime) {
        mCookTime = cookTime;
    }

    public void setIngredients(List<String> ingredients) {
        mIngredients = ingredients;
    }

    public void setDirections(List<String> directions) {
        mDirections = directions;
    }

    public boolean isInList() {
        return isInList;
    }

    public void setInList(boolean inList) {
        isInList = inList;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.mRecipeName);
        dest.writeInt(this.mID);
        dest.writeString(this.mServings);
        dest.writeString(this.mPrepTime);
        dest.writeString(this.mCookTime);
        dest.writeByte(this.isInList ? (byte) 1 : (byte) 0);
        dest.writeStringList(this.mIngredients);
        dest.writeStringList(this.mDirections);
    }

    protected Recipe(Parcel in) {
        this.mRecipeName = in.readString();
        this.mID = in.readInt();
        this.mServings = in.readString();
        this.mPrepTime = in.readString();
        this.mCookTime = in.readString();
        this.isInList = in.readByte() != 0;
        this.mIngredients = in.createStringArrayList();
        this.mDirections = in.createStringArrayList();
    }

    public static final Creator<Recipe> CREATOR = new Creator<Recipe>() {
        @Override
        public Recipe createFromParcel(Parcel source) {
            return new Recipe(source);
        }

        @Override
        public Recipe[] newArray(int size) {
            return new Recipe[size];
        }
    };
}

以及使用适配器的主要 Activity 类:

public class RecipeList extends AppCompatActivity{
    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
    private int REQUEST_CODE=1;
    private Button mNavigateGroceryButton;
    RecipeDB dbHelper = new RecipeDB(this);
    List<Recipe> recipes;


    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        recipes = dbHelper.getAllRecipes();

        setContentView(R.layout.activity_recipe_list);
        mRecyclerView = (RecyclerView) findViewById(R.id.list_recycler_view);


        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);

        mAdapter = new RecipeListAdapter(recipes);
        mRecyclerView.setAdapter(mAdapter);


        mNavigateGroceryButton = (Button) findViewById(R.id.navigate_to_groceries_button_list_view);
        mNavigateGroceryButton.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                Intent i = new Intent(RecipeList.this, ExpandableListViewActivity.class);
                //Log.d("Navigate", "navigate pressed" );
                startActivity(i);
            }
        });
    }

    @Override
    public void onBackPressed() {
    }

    public boolean onOptionsItemSelected(MenuItem item){
        //Handles menu buttons
        switch (item.getItemId()){
            case R.id.recipe_list_add_recipe_actionbar_button:
                //This button creates a new empty Recipe object and passes it to the EditRecipe class
                //The Recipe object is passed as a parcelable
                Recipe passedRecipe = new Recipe();
                Intent i = new Intent(RecipeList.this, EditRecipe.class);
                i.putExtra("passed_recipe_key", (Parcelable) passedRecipe);
                startActivityForResult(i, REQUEST_CODE);
                return true;
            default:
                Log.d("Name,", "default called");
                return super.onOptionsItemSelected(item);

        }
    }

    public void addNewReRecipe(Recipe recipe){
        dbHelper.addRecipe(recipe);
        recipes = dbHelper.getAllRecipes();
        mAdapter = new RecipeListAdapter(recipes);
        mRecyclerView.setAdapter(mAdapter);
    }

    //Makes the menu bar appear as it is in the action_bar_recipe_list_buttons menu layout file
    @Override
    public boolean onCreateOptionsMenu(Menu menu){
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.action_bar_recipe_list_buttons, menu);
        return true;
    }


    //This code is called after creating a new recipe. This is only for creating, and not editing.
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE){
            if(resultCode == Activity.RESULT_OK) {
                Recipe createdRecipe = data.getExtras().getParcelable("recipe_key");
                addNewReRecipe(createdRecipe);
            }
        }
    }


}     

最佳答案

看起来您需要在 ViewHolder 的顶部与其他 View 一起声明您的按钮。因此,将声明从适配器的顶部移开:

私有(private)按钮 mAddToGroceriesButton;

然后在您的 onBindViewHolder 方法中,您可以通过 holder 获取对按钮的引用并设置背景:

if(recipe.isInList()) {
     holder.mAddToGroceriesButton.setBackgroundResource(R.mipmap.ic_playlist_add_check_black_24dp);
}

关于android - 基于 bool 值更改适配器类中回收器 View 中按钮的图标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42336265/

相关文章:

android - 广播BroadcastRecord超时

ios - 在SwiftUI中点击Button时获取Tag值

android - 从 RecyclerView 检索数据

android - onclicklistener 不在 recyclerview 上工作

android - 带有流式 hls 的 html5 视频全屏

android - 来自Maven的ActionBarSherlock Gradle依赖项与androidsupportv4发生冲突

android - 检测哪个按钮被按下

java - 在 SherlockFragment 中创建一个 onclicklistener

android - 回收站 View : How to tell not to recycle?

android - 自定义线性布局