简体   繁体   English

如何在另一个片段中的 RecyclerView 上显示收藏夹列表

[英]How to display favorite list on RecyclerView in another Fragment

I already made a RecyclerView list of recipes which contains the image, title, and some description inside a fragment.我已经制作了一个 RecyclerView 食谱列表,其中包含图像、标题和片段中的一些描述。 I also add a star button in a row that if it clicked,it changes the color and change the favorite status of the recipe from 0 to 1.我还在一行中添加了一个星形按钮,如果单击它,它会更改颜色并将食谱的收藏状态从 0 更改为 1。

My question is, how do I display all the recipes whose favorite status equals to 1, on a RecyclerView on another fragment.我的问题是,如何在另一个片段的 RecyclerView 上显示收藏状态等于 1 的所有食谱。

DatabaseHandler.java 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);
    }
}

Recipe Model class配方 Model class

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 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();
        }
    }
}

There can be multiple ways to do achieve this.可以有多种方法来实现这一点。

  • ViewModel视图模型
  • EventBus事件总线
  • Interface界面

ViewModel视图模型

ViewModel is a class that is responsible for preparing and managing the data for an Activity or a Fragment. ViewModel 是一个 class,负责为 Activity 或 Fragment 准备和管理数据。 It also handles the communication of the Activity / Fragment with the rest of the application (eg calling the business logic classes).它还处理 Activity / Fragment 与应用程序 rest 的通信(例如调用业务逻辑类)。

Using ViewModel with LiveData we can communicate between multiple fragment by observing LiveData object. for example when user click on favorite button you will post the Recipe id by using method postValue().将 ViewModel 与 LiveData 结合使用,我们可以通过观察 LiveData object 在多个片段之间进行通信。例如,当用户单击收藏按钮时,您将使用方法 postValue() 发布食谱 ID。 so all observer will receive the id that has been posted and using this you can fetch new data and display into Adapter.因此所有观察者都将收到已发布的 ID,并使用它可以获取新数据并显示到 Adapter 中。

EventBus事件总线

EventBus is library and it's use publisher/subscriber pattern for loose coupling and it can be used for communicating between multiple component. EventBus 是一个库,它使用发布者/订阅者模式实现松散耦合,可用于多个组件之间的通信。

you can read more about it here你可以在这里阅读更多相关信息

Interface界面

Using this way you will create a Listener and implement in activity, so in this scenario Activity will be used to communicate between multiple fragments.使用这种方式,您将创建一个 Listener 并在 Activity 中实现,因此在这种情况下,Activity 将用于多个片段之间的通信。

I will suggest you to use ViewModel cause they are Life-Cycle aware component.我建议您使用 ViewModel,因为它们是生命周期感知组件。 and it's easy to implement and use.并且易于实施和使用。 in following link Communicating with fragments you can read about it.在以下链接Communicating with fragments中,您可以阅读相关内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM