【问题标题】:How to display favorite list on RecyclerView in another Fragment如何在另一个片段中的 RecyclerView 上显示收藏夹列表
【发布时间】:2021-10-22 04:10:31
【问题描述】:

我已经制作了一个 RecyclerView 食谱列表,其中包含图片、标题和片段内的一些描述。我还在一行中添加了一个星形按钮,如果单击该按钮,它会更改颜色并将食谱的收藏状态从 0 更改为 1。

我的问题是,我如何在另一个片段的 RecyclerView 上显示所有收藏状态等于 1 的食谱。

DatabaseHandler.java

public class DatabaseHandler {
    public DatabaseHandler(Context context) {
        super(context, Util.DATABASE_NAME, null, Util.DATABASE_VERSION);
    }


    //We create our table..
    @Override
    public void onCreate(SQLiteDatabase db) {
        //SQL- Structured Query Language
       /* 
        create table _name(id, name, desc, ingredient, image);
        */
        String CREATE_CONTACT_TABLE = "CREATE TABLE " + Util.TABLE_NAME + "("
                + Util.KEY_ID + " INTEGER PRIMARY KEY," + Util.KEY_NAME + " TEXT,"
                + Util.KEY_DESCRIPTION + " TEXT," + Util.KEY_INGREDIENT + " TEXT,"
                + Util.KEY_IMAGE + " BLOB," + Util.KEY_FAV_STATUS + " TEXT" + ")";
        db.execSQL(CREATE_CONTACT_TABLE); //Creating our table..
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        String DROP_TABLE = String.valueOf(R.string.db_drop);
        db.execSQL(DROP_TABLE, new String[]{Util.DATABASE_NAME});

        //Create table again
        onCreate(db);
    }

    //Add Recipe
    public void addRecipe(Recipe recipe) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(Util.KEY_NAME, recipe.getName());
        values.put(Util.KEY_DESCRIPTION, recipe.getDescription());
        values.put(Util.KEY_INGREDIENT, recipe.getIngredient());
        values.put(Util.KEY_IMAGE, recipe.getImage());
        values.put(Util.KEY_FAV_STATUS, recipe.getFavStatus());

        //Insert into row..
        db.insert(Util.TABLE_NAME, null, values);
        Log.d("DBHandler", "addRecipe: " + "item added");
        db.close();
    }


    //Get a recipe
    public Recipe getRecipe(int id) {
        SQLiteDatabase db = this.getReadableDatabase();

        Cursor cursor = db.query(Util.TABLE_NAME,
                new String[] { Util.KEY_ID, Util.KEY_NAME, Util.KEY_DESCRIPTION, Util.KEY_FAV_STATUS,
                        Util.KEY_INGREDIENT, Util.KEY_IMAGE}, Util.KEY_ID +"=?",
                new String[]{String.valueOf(id)},
                null, null, null);

        if (cursor != null)
            cursor.moveToFirst();

        Recipe recipe = new Recipe();
        recipe.setId(Integer.parseInt(cursor.getString(0)));
        recipe.setName(cursor.getString(1));
        recipe.setDescription(cursor.getString(2));
        recipe.setIngredient(cursor.getString(3));
        recipe.setImage(Integer.parseInt(cursor.getString(4)));
        recipe.setFavStatus(cursor.getString(5));

        return recipe;
    }


    //Get all Recipes
    public List<Recipe> getAllRecipes() {
        List<Recipe> recipeList = new ArrayList<>();

        SQLiteDatabase db = this.getReadableDatabase();

        //Select all recipes
        String selectAll = "SELECT * FROM " + Util.TABLE_NAME;
        Cursor cursor = db.rawQuery(selectAll, null);

        //Loop through our data
        if (cursor.moveToFirst()) {
            do {
                Recipe recipe = new Recipe();
                recipe.setId(Integer.parseInt(cursor.getString(0)));
                recipe.setName(cursor.getString(1));
                recipe.setDescription(cursor.getString(2));
                recipe.setIngredient(cursor.getString(3));
                recipe.setImage(Integer.parseInt(cursor.getString(4)));
                recipe.setFavStatus((cursor.getString(5)));

                //add recipe objects to our list
                recipeList.add(recipe);
            }while (cursor.moveToNext());
        }

        return recipeList;
    }

    public Cursor read_all_data(int id) {
        SQLiteDatabase db = this.getReadableDatabase();
        String sql = "SELECT * FROM " + Util.TABLE_NAME + " WHERE " + Util.KEY_ID + "=" + id + "";
        return db.rawQuery(sql, null, null);
    }


    //Update recipe
    public int updateRecipe (Recipe recipe) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(Util.KEY_NAME, recipe.getName());
        values.put(Util.KEY_DESCRIPTION, recipe.getDescription());
        values.put(Util.KEY_INGREDIENT, recipe.getIngredient());
        values.put(Util.KEY_IMAGE, recipe.getImage());
        values.put(Util.KEY_FAV_STATUS, recipe.getFavStatus());

        //Update the row
        return db.update(Util.TABLE_NAME, values, Util.KEY_ID + "=?",
                new String[]{String.valueOf(recipe.getId())});
    }


    //Delete single recipe
    public void deleteRecipe(Recipe recipe) {
        SQLiteDatabase db = this.getWritableDatabase();

        db.delete(Util.TABLE_NAME, Util.KEY_ID + "=?",
                new String[]{String.valueOf(recipe.getId())});
        db.close();
    }

    //Select all favorite list method.
    public Cursor getAllFavRecipes() {

        SQLiteDatabase db = this.getReadableDatabase();
        String sql = "SELECT * FROM " + Util.TABLE_NAME + " WHERE " + Util.KEY_FAV_STATUS + " ='1'";
        return db.rawQuery(sql, null, null);
    }
}

配方模型类

public class Recipe {
    private int id;
    private String name;
    private String description;
    private String ingredient;
    private int image;
    private String favStatus;


    public Recipe() {
    }


    public Recipe(int id, String name, String description, String ingredient, int image, String favStatus) {
        this.id = id;
        this.name = name;
        this.description = description;
        this.ingredient = ingredient;
        this.image = image;
        this.favStatus = favStatus;
    }


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getIngredient() {
        return ingredient;
    }

    public void setIngredient(String ingredient) {
        this.ingredient = ingredient;
    }

    public int getImage() {
        return image;
    }

    public void setImage(int image) {
        this.image = image;
    }

    public String getFavStatus() {
        return favStatus;
    }

    public void setFavStatus(String favStatus) {
        this.favStatus = favStatus;
    }
}

RecyclerViewAdapter.java

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> implements Filterable{

    private Context context;
    private List<Recipe> recipeList;
    private List<Recipe> recipeListFull;
    private DatabaseHandler db;
    private Recipe recipe;


    public RecyclerViewAdapter(Context context, List<Recipe> recipeList) {
        this.context = context;
        this.recipeList = recipeList;
        recipeListFull = new ArrayList<>(recipeList);
        db = new DatabaseHandler(context);
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {

        View view = LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.recipe_row, viewGroup, false);

        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int position) {
        Recipe recipe = recipeList.get(position); //each recipe object inside of our list

        readCursorData(recipe, viewHolder);
        viewHolder.recipeName.setText(recipe.getName());
        viewHolder.description.setText(recipe.getDescription());
        viewHolder.image.setImageResource(recipe.getImage());
    }

    @Override
    public int getItemCount() {
        return recipeList.size();
    }

    @Override
    public Filter getFilter() {
        return filterRecipe;
    }


    private Filter filterRecipe = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence charSequence) {
            String searchText = charSequence.toString().toLowerCase();
            List<Recipe> tempList = new ArrayList<>();
            if(searchText.length()==0 | searchText.isEmpty()) {
                tempList.addAll(recipeListFull);
            }else {
                for (Recipe item:recipeListFull) {
                    if (item.getName().toLowerCase().contains(searchText)) {
                        tempList.add(item);
                    }
                }
            }
            FilterResults filterResults = new FilterResults();
            filterResults.values = tempList;

            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults filterResults) {
            recipeList.clear();
            recipeList.addAll((Collection<? extends Recipe>) filterResults.values);
            notifyDataSetChanged();

        }
    };


    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        public TextView recipeName;
        public TextView description;
        public ImageView image;
        public ImageView favBtn;

        public ViewHolder(@NonNull  View itemView) {
            super(itemView);

            itemView.setOnClickListener(this);
            recipeName = itemView.findViewById(R.id.name);
            description = itemView.findViewById(R.id.description);
            image = itemView.findViewById(R.id.recipe_imageView);
            favBtn = itemView.findViewById(R.id.fav_image_btn);

            favBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int position = getAdapterPosition();
                    Recipe recipe = recipeList.get(position);

                    if (recipe.getFavStatus().equals("0")) {
                        recipe.setFavStatus("1");
                        db.updateRecipe(recipe);
                        favBtn.setImageResource(R.drawable.favourite_star);
                    } else {
                        recipe.setFavStatus("0");
                        db.updateRecipe(recipe);
                        favBtn.setImageResource(R.drawable.shadow_fav_star);
                    }
                }
            });

        }

        @Override
        public void onClick(View v) {

            int position = getAdapterPosition();
            Recipe recipe = recipeList.get(position);

            Intent intent = new Intent(context, DetailsActivity.class);
            intent.putExtra("name", recipe.getName());
            intent.putExtra("description", recipe.getDescription());
            intent.putExtra("ingredient", recipe.getIngredient());
            intent.putExtra("image", recipe.getImage());

            context.startActivity(intent);

            //Log.d("Clicked", "onClick: " + recipe.getName());

        }
    }

    //Create method to read and check for fav status for every row..
    private void readCursorData (Recipe recipe, ViewHolder viewHolder) {
        Cursor cursor = db.read_all_data(recipe.getId());
        SQLiteDatabase sqLiteDatabase = db.getReadableDatabase();
        try {
            while (cursor.moveToNext()) {
                String item_fav_status = cursor.getString(cursor.getColumnIndex(Util.KEY_FAV_STATUS));
                recipe.setFavStatus(item_fav_status);

                //check fav status
                if (item_fav_status != null && item_fav_status.equals("1")) {
                    viewHolder.favBtn.setImageResource(R.drawable.favourite_star);
                } else if (item_fav_status != null && item_fav_status.equals("0")) {
                    viewHolder.favBtn.setImageResource(R.drawable.shadow_fav_star);
                }
            }
        } finally {
            if (cursor != null && cursor.isClosed())
                cursor.close();
            db.close();
        }
    }
}

【问题讨论】:

  • 您的意思是如何查询数据,或者当在当前片段上发生更改时,它应该反映在另一个片段上?
  • 是的,当食谱切换为收藏时,它将显示在另一个片段上。

标签: java android android-studio android-recyclerview layout


【解决方案1】:

有多种方法可以做到这一点。

  • 视图模型
  • 事件总线
  • 接口

视图模型

ViewModel 是一个类,负责为 Activity 或 Fragment 准备和管理数据。它还处理 Activity / Fragment 与应用程序其余部分的通信(例如调用业务逻辑类)。

将 ViewModel 与 LiveData 结合使用,我们可以通过观察 LiveData 对象在多个片段之间进行通信。例如,当用户单击收藏按钮时,您将使用 postValue() 方法发布配方 ID。因此所有观察者都会收到已发布的 id,并使用它获取新数据并显示到适配器中。

EventBus

EventBus 是一个库,它使用发布者/订阅者模式进行松耦合,它可以用于多个组件之间的通信。

你可以阅读更多关于它here

界面

使用这种方式,您将创建一个监听器并在活动中实现,因此在这种情况下,活动将用于在多个片段之间进行通信。

我建议您使用 ViewModel,因为它们是生命周期感知组件。并且易于实施和使用。在下面的链接Communicating with fragments你可以阅读它。

【讨论】:

  • 感谢您的精彩解释。它真的帮助我理解这个想法,你是对的,最好使用 ViewModel。 :)
  • 不客气! ViewModel 很棒,使用 LiveData 会让事情变得更简单。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多