尝试从RecyclerView适配器检查Room DB

时间:2019-06-05 22:01:55

标签: android android-recyclerview adapter android-room

我正在尝试从RecyclerView适配器插入,删除和检查我的Room DB,但是我无法正确完成,因为就像适配器一直在重置项目一样。

我正在寻找的基本功能是直接从RecyclerView适配器向数据库添加一个项。

即使我在数据库中进行插入和删除操作,也无法根据数据库中每个项目的存在来保持切换按钮的状态为选中状态。

enter image description here enter image description here

PS不在乎所有这些记录...

这是我的适配器

public class MovieListRvAdapter extends RecyclerView.Adapter<MovieListRvAdapter.MoviesViewHolder>  {
private Context mContext;
private List<Movie> mMovies;
private static RvClickListener listener;
private boolean isInFavsAlready;
private static String LOG_TAG = MovieListRvAdapter.class.getSimpleName();

public interface RvClickListener{
     void rvClickListener(View v, int position);
}

public void swapData(List<Movie> movies)
{
    if(movies == null || movies.size()==0)
        return;
    if (mMovies != null && mMovies.size()>0)
        mMovies.clear();
    mMovies.addAll(movies);
    notifyDataSetChanged();
}

public MovieListRvAdapter(Context c, List<Movie> myMovieData, RvClickListener listener) {
    this.mContext = c;
    this.mMovies =myMovieData;
    this.listener = listener;

}

@NonNull
@Override
public MovieListRvAdapter.MoviesViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
    Context context = viewGroup.getContext();
    int layoutIdForListItem = R.layout.movie_list_item;
    LayoutInflater inflater = LayoutInflater.from(context);
    boolean shouldAttachToParentImmediately = false;
    View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
    MoviesViewHolder viewHolder = new MoviesViewHolder(view);
    return viewHolder;
}

@Override
public void onBindViewHolder(@NonNull MovieListRvAdapter.MoviesViewHolder holder, int position) {
    Movie movie = this.mMovies.get(position);
    Picasso.get()
            .load(movie.getPoster_path())
            .placeholder(R.drawable.ic_launcher_background)
            .error(R.drawable.ic_launcher_foreground)
            .into(holder.moviePosterIv);
    holder.movieTitleTv.setText(movie.getTitle());
    holder.ratingBar.setRating(Float.valueOf(movie.getVote_average())/2);
    holder.movieReleaseDateTv.setText(modifyDateLayout(movie.getRelease_date()));
     boolean bool =isMovieInFavorites(movie);
    Log.d(LOG_TAG, "isMovieInFavorites " +bool + " " +movie.getTitle());
    if(bool){
        holder.favButton.setChecked(true);

    }else{
        holder.favButton.setChecked(false);
    }
}

@Override
public int getItemCount() {
     return (null != mMovies ? mMovies.size() : 0);
}

/**
 * Cache of the children views for a list item.
 */
public class MoviesViewHolder extends RecyclerView.ViewHolder
        implements View.OnClickListener {
    ImageView moviePosterIv;
    TextView movieTitleTv;
    RatingBar ratingBar;
    TextView movieReleaseDateTv;
    ToggleButton favButton;

    public MoviesViewHolder(View itemView) {
        super(itemView);
        ratingBar = itemView.findViewById(R.id.rating);
        moviePosterIv = itemView.findViewById(R.id.poster_path);
        movieTitleTv = itemView.findViewById(R.id.movieTitleListItem);
        movieReleaseDateTv = itemView.findViewById(R.id.movieReleaseDate);
        favButton = itemView.findViewById(R.id.toggleButton);
        favButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                int position = getLayoutPosition();
                final Movie movie = mMovies.get(position);
                if (isChecked && !isMovieInFavorites(movie)){
                final AppDatabase mDb = AppDatabase.getInstance(mContext);
                    Log.d(LOG_TAG, "isMovieInFavorites " +isMovieInFavorites(movie));
                AppExecutors.getInstance().diskIO().execute(new Runnable() {
                    @Override
                    public void run() {
                        mDb.movieDao().insertMovie(movie);
                        Log.d(LOG_TAG, " " + movie);
                    }
                });
                    favButton.setChecked(true);
                }
                else if (!isChecked){
                    final AppDatabase mDb = AppDatabase.getInstance(mContext);
                    AppExecutors.getInstance().diskIO().execute(new Runnable() {
                        @Override
                        public void run() {
                            mDb.movieDao().deleteMovie(movie);
                            Log.d(LOG_TAG, "movie deleted " + movie);
                        }
                    });
                    favButton.setChecked(false);
                }
            }
        });
        itemView.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        Context context = v.getContext();
        int clickedPosition = getAdapterPosition();
        Intent i = new Intent(context, MovieDetailsActivity.class);
        Movie movie = mMovies.get(clickedPosition);
        i.putExtra(MovieDetailsActivity.EXTRA_MOVIE, movie);
        context.startActivity(i);
        listener.rvClickListener(v, clickedPosition);
    }
}

public boolean isMovieInFavorites(Movie movie) {
    final AppDatabase mDb = AppDatabase.getInstance(mContext);
    AppExecutors.getInstance().diskIO().execute(new Runnable() {
        @Override
        public void run() {
            int dbMovieID = mDb.movieDao().searchFavsByMovieID(movie.getId());
            Log.d(LOG_TAG, "result of " + dbMovieID + " " + movie.getTitle());
            if(dbMovieID !=0){
                isInFavsAlready = true;

            }else{
                isInFavsAlready= false;
            }
        }
    });

// Log.d(LOG_TAG,“ method1的结果” + isInFavsAlready +“” + movie.getTitle());         返回isInFavsAlready;     }

@Dao
public interface MovieDao {

@Query("SELECT * FROM moviesTable ORDER BY id")
LiveData<List<Movie>> loadAllMovies();

@Query("SELECT * FROM moviesTable WHERE id = :id")
LiveData<Movie> loadMovieById(int id);

@Query("SELECT id FROM moviesTable WHERE id = :id")
int searchFavsByMovieID(int id);

@Query("SELECT id FROM moviesTable WHERE id = :id")
LiveData<Integer> searchFavsByMovieIDLive(int id);

@Insert
void insertMovie(Movie movie);

@Query("DELETE FROM moviesTable WHERE movieId = :movieID")
void deleteByID(int movieID);

@Delete
void deleteMovie(Movie movie);

}

2 个答案:

答案 0 :(得分:0)

我的猜测是这是LiveData问题。一年多以前,我在LiveData出现之前就做了这个项目。上周末,我更新为使用Room和LiveData。我遇到了这个完全相同的问题。 Here's the commit进行修复的位置。我将所有电影存储在数据库中,并有一列存储它是否是收藏夹。不幸的是,我在提交中做了很多重构,但是我认为相关的部分在这里(忽略可怕的方法名,因为我的网络调用很乱):

public boolean isFavoriteAlreadyInBackground(int movieId) {
    //  old code
    //    LiveData<Movie> movie = movieDao.getMovie(movieId);
    //    return movie.getValue() != null && movie.getValue().getFavorite();
        //new code
        Movie movie = movieDao.getMovie(movieId);
        return movie != null && movie.getFavorite();
    }

当我检查LiveData Movie时,isFavorite的值被重新设置为false,因此我开始检查db对象的非实时数据版本,并且它具有正确的值。我敢肯定,我的项目与您的项目看起来有很大不同,但是可以随时浏览并借用对您有用的任何部分,尽管这是一个正在进行的工作。希望这会有所帮助。

答案 1 :(得分:0)

这里的问题是您的函数# use pandas to open csv files and slice and dice as you please import pandas as pd bank_csv_path = os.path.join("Bank/Resources/budget_data.csv") df = pd.read_csv(bank_csv_path) df.head() print(df) df.shape print(df.size) print(len(df)) #prints data frame (df) length print(df.columns) #prints column headers print(df['column 1']) #slicing data print(df["column 2"][:4]) #prints everything in column 2 starting at index 3 print(df["column 2"][4]) #prints index 4 on column 2 。 在Room完成查询之前(您的查询在io线程中运行)之前,将触发此返回语句isMovieInFavorites。因此,您可以在更新UI之前等待查询完成

return isInFavsAlready;