英文:
Add to favorite using room Database
问题
我在项目中参考了这个教程 ==> https://uniqueandrocode.com/add-to-favourites-and-display-favourites-in-recyclerview/,我在项目中使用了底部导航栏。我正在尝试在第一个选项卡中添加收藏夹,并在底部导航栏的第二个选项卡中显示收藏夹。我正在使用 Room 库。
当活动加载时,首先所有的收藏夹都是空白的,但是当我将第一行设为收藏夹并转到收藏夹选项卡时,它会正确显示。但是当我返回到第一个选项卡时,它会自动填充所有的收藏夹图标(这不是我所做的,我只做了第一行)。
Dao:
@Dao
public interface FavoriteDao {
@Insert
public void addData(FavoriteList favoriteList);
@Query("select * from favoritelist")
public List<FavoriteList> getFavoriteData();
@Query("SELECT EXISTS (SELECT 1 FROM favoritelist WHERE id=:id)")
public int isFavorite(int id);
@Delete
public void delete(FavoriteList favoriteList);
}
Database:
@Database(entities={FavoriteList.class},version = 1)
public abstract class FavoriteDatabase extends RoomDatabase {
public abstract FavoriteDao favoriteDao();
}
FavoriteList:
@Entity(tableName="favoritelist")
public class FavoriteList {
@PrimaryKey
private int id;
@ColumnInfo(name = "source")
private String source;
@ColumnInfo(name = "author")
private String author;
@ColumnInfo(name = "title")
private String title;
@ColumnInfo(name = "description")
private String description;
@ColumnInfo(name = "url")
private String url;
@ColumnInfo(name = "urlToImage")
private String urlToImage;
@ColumnInfo(name = "publishedAt")
private String publishedAt;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrlToImage() {
return urlToImage;
}
public void setUrlToImage(String urlToImage) {
this.urlToImage = urlToImage;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
}
News Fragment:
public class news extends Fragment {
// ... (代码继续)
Adapter:
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
// ... (代码继续)
英文:
I'm referring this tutorial ==> https://uniqueandrocode.com/add-to-favourites-and-display-favourites-in-recyclerview/ in my project I have bottom navigation...I am trying to add favourites in the first tab and displaying favourites in the second tab in the bottom navigation bar. I'm using Room library.
When activity loads favourites are all blank at first, but when I first row as favourite and go-to favourite tab it displays properly but when I came back to the first tab it fills all the favourites icon automatically (which I have not done I had only done the first row)
Really need help. Thanks in advance.
Dao:
@Dao
public interface FavoriteDao {
@Insert
public void addData(FavoriteList favoriteList);
@Query("select * from favoritelist")
public List<FavoriteList> getFavoriteData();
@Query("SELECT EXISTS (SELECT 1 FROM favoritelist WHERE id=:id)")
public int isFavorite(int id);
@Delete
public void delete(FavoriteList favoriteList);
}
Database:
@Database(entities={FavoriteList.class},version = 1)
public abstract class FavoriteDatabase extends RoomDatabase {
public abstract FavoriteDao favoriteDao();
}
FavoriteList:
@Entity(tableName="favoritelist")
public class FavoriteList {
@PrimaryKey
private int id;
@ColumnInfo(name = "source")
private String source;
@ColumnInfo(name = "author")
private String author;
@ColumnInfo(name = "title")
private String title;
@ColumnInfo(name = "description")
private String description;
@ColumnInfo(name = "url")
private String url;
@ColumnInfo(name = "urlToImage")
private String urlToImage;
@ColumnInfo(name = "publishedAt")
private String publishedAt;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrlToImage() {
return urlToImage;
}
public void setUrlToImage(String urlToImage) {
this.urlToImage = urlToImage;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
}
News fragment:
public class news extends Fragment {
ImageView favbtn;
RecyclerView recyclerView;
SwipeRefreshLayout swipeRefreshLayout;
EditText etQuery;
Button btnSearch;
Adapter adapter;
List<Articles> articles = new ArrayList<>();
public static FavoriteDatabase favoriteDatabase;
public news() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_news, container, false);
swipeRefreshLayout = view.findViewById(R.id.swiprefresh);
etQuery = view.findViewById(R.id.etQuery);
btnSearch = view.findViewById(R.id.btnSearch);
favoriteDatabase= Room.databaseBuilder(getActivity(),FavoriteDatabase.class,"myfavdb").
allowMainThreadQueries().build();
recyclerView = view.findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
final String country = getCountry();
retrieveJson("", country, API_Key);
btnSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!etQuery.getText().toString().equals("")) {
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
retrieveJson(etQuery.getText().toString(), country, API_Key);
}
});
retrieveJson(etQuery.getText().toString(), country, API_Key);
} else {
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
retrieveJson("", country, API_Key);
}
});
retrieveJson("", country, API_Key);
}
}
});
return view;
}
private void showChangeLanguageDialog() {
}
public void retrieveJson(String query, String country, String apiKey) {
swipeRefreshLayout.setRefreshing(true);
Call<Headlines> call;
if (!etQuery.getText().toString().equals("")) {
call = ApiClient.getInstance().getApi().getSpecifiedData(query, apiKey);
} else {
call = ApiClient.getInstance().getApi().getHeadLines(country, apiKey);
}
call.enqueue(new Callback<Headlines>() {
@Override
public void onResponse(Call<Headlines> call, Response<Headlines> response) {
if (response.isSuccessful() && response.body().getArticles() != null) {
swipeRefreshLayout.setRefreshing(false);
// articles.clear();
articles = response.body().getArticles();
adapter = new Adapter(getContext(), articles);
recyclerView.setAdapter(adapter);
}
}
@Override
public void onFailure(Call<Headlines> call, Throwable t) {
swipeRefreshLayout.setRefreshing(false);
Toast.makeText(getContext(), t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
});
}
public String getCountry() {
Locale locale = Locale.getDefault();
String country = locale.getCountry();
return country.toLowerCase();
}
}
Adapter:
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {
Context context;
List<Articles> articles;
public Adapter(Context context, List<Articles> articles) {
this.context = context;
this.articles = articles;
}
@NonNull
@Override
public Adapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull final Adapter.ViewHolder holder, final int position) {
final Articles a = articles.get(position);
String imageUrl = a.getUrlToImage();
String url = a.getUrl();
holder.tvTitle.setText(a.getTitle());
Picasso.get().load(imageUrl).into(holder.imageView);
holder.tvSource.setText(a.getSource().getName());
holder.tvDate.setText(dateTime(a.getPublishedAt()));
holder.cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context,DetailedActivity.class);
intent.putExtra("title",a.getTitle());
intent.putExtra("source",a.getSource().getName());
intent.putExtra("time",dateTime(a.getPublishedAt()));
intent.putExtra("desc",a.getDescription());
intent.putExtra("imageUrl",a.getUrlToImage());
intent.putExtra("url",a.getUrl());
context.startActivity(intent);
}
});
if (news.favoriteDatabase.favoriteDao().isFavorite(articles.get(position).getId())==1)
holder.bookmark.setImageResource(R.drawable.ic_bookmark);
else
holder.bookmark.setImageResource(R.drawable.ic_baseline_bookmark_border_24);
holder.bookmark.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FavoriteList favoriteList = new FavoriteList();
int id = articles.get(position).getId();
String source = articles.get(position).getSource().getName();
String author = articles.get(position).getAuthor();
String publishedAt = articles.get(position).getPublishedAt();
String description = articles.get(position).getDescription();
String title = articles.get(position).getTitle();
String url = articles.get(position).getUrl();
String urlToImage = articles.get(position).getUrlToImage();
favoriteList.setId(id);
favoriteList.setAuthor(author);
favoriteList.setDescription(description);
favoriteList.setSource(source);
favoriteList.setPublishedAt(publishedAt);
favoriteList.setTitle(title);
favoriteList.setUrl(url);
favoriteList.setUrlToImage(urlToImage);
favoriteList.setPublishedAt(dateTime(articles.get(position).getPublishedAt()));
if (news.favoriteDatabase.favoriteDao().isFavorite(id)!=1){
holder.bookmark.setImageResource(R.drawable.ic_bookmark);
news.favoriteDatabase.favoriteDao().addData(favoriteList);
}else {
holder.bookmark.setImageResource(R.drawable.ic_baseline_bookmark_border_24);
news.favoriteDatabase.favoriteDao().delete(favoriteList);
}
}
});
}
@Override
public int getItemCount() {
return articles.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView tvTitle, tvSource, tvDate;
ImageView imageView;
ImageButton bookmark;
CardView cardView;
public ViewHolder(@NonNull View itemView) {
super(itemView);
tvTitle = itemView.findViewById(R.id.tvId);
tvSource = itemView.findViewById(R.id.tvSource);
tvDate = itemView.findViewById(R.id.tvDate);
imageView = itemView.findViewById(R.id.image);
cardView = itemView.findViewById(R.id.cardView);
bookmark = itemView.findViewById(R.id.favrr);
}
}
答案1
得分: 1
步骤进行调试:
- 添加2-3个项目到收藏夹。
- 重新启动应用程序。
检查在重新启动应用程序后是否显示这些项目为收藏项。
还要在更改可绘制项的条件下添加日志。
在查看您的JSON后,看起来是ID在造成问题。所有JSON项目的ID都为空,因此当收藏一个时,它会对所有项目显示为收藏。
解决方案:使用另一个字段来检查数据是否已添加到收藏列表中。
删除也不起作用
尝试
@Query("DELETE FROM favoritelist WHERE title = :title")
void deleteByUserId(String title);
删除项目
另外,您可以使用https://github.com/amitshekhariitbhu/Android-Debug-Database这个库来调试您的数据库。
英文:
Steps to debug:
- Add 2-3 items as Favs.
- Restart the Application.
Check if it shows those items as fav after restarting application .
also add logs to those if conditions where you are changing the drawables.
After looking at your JSON it looks like id is what creating problems. Id is null for all your json items so when fav. one it shows fav. to all.
Solution : Use another field to check if the data is added to fav.list
Delete will not work either
Try
@Query("DELETE FROM favoritelist WHERE title = :title")
void deleteByUserId(String title);
To delete item
Also https://github.com/amitshekhariitbhu/Android-Debug-Database
check this library to debug your database
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论