@insert在RecyclerView适配器中无法在工作间数据库中使用

时间:2019-12-07 07:27:06

标签: android android-room recycler-adapter android-livedata

我正在尝试通过使用@insert方法在数据库内部单击来插入recyclerView项 现在,单击后,我得到的是字符串a,b,但是每当我输入Viewmodel.insert(new FavNews(String a,String b)时,我就会得到null ...! 我的代码应该放在哪里还是应该在错误的线程中放置在错误的位置?

public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.NewsViewHolder> {

 Context context;
 ArrayList<Result> articles;


 public NewsAdapter(Context context, ArrayList<Result> articles) {
this.context = context;
this.articles = articles;
}

@NonNull
@Override
public NewsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.news_fragment_items, parent, false);
return new  NewsViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull NewsViewHolder holder, final int position) {
holder.tvName.setText(articles.get(position).getWebTitle());
holder.tvDesCription.setText(articles.get(position).getSectionName());




holder.itemView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
             //here need to put insert method

    }
});
 }

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

public class NewsViewHolder extends RecyclerView.ViewHolder{

TextView tvName;
TextView tvDesCription;

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

    tvName = itemView.findViewById(R.id.tvName);
    tvDesCription = itemView.findViewById(R.id.tvDesCription);


}
 }
 }

这是viewModel

  public class NoteViewModel extends AndroidViewModel {


private NewsRepository repository;
private LiveData<List<FavNews>> allNotes;



 public MutableLiveData<NewsResponse> getNewsRepository() {
   repository = NewsRepository.getInstance();
return repository.getNews( "b70d396f-d5b4-43f0-8b67-222524937f25");
}

 public NoteViewModel(@NonNull Application application) {
    super(application);
    repository = new NewsRepository(application);
    allNotes = repository.getAllNotes();
   }

 public void insert(FavNews favNews) {
repository.insert(favNews);
 }



  public LiveData<List<FavNews>> getAllNotes() {
return allNotes;
}
 }

这是存储库

public class NewsRepository {
    private FavNewsDao favNewsDao;
    private LiveData<List<FavNews>> allNotes

    private NewsApi newsApi;
    private static NewsRepository newsRepository;


    public static NewsRepository getInstance() {
        if (newsRepository == null) {
            newsRepository = new NewsRepository();
        }
        return newsRepository;
    }

    private NewsRepository() {
        newsApi = RetrofitService.cteateService(NewsApi.class);
    }


    public MutableLiveData<NewsResponse> getNews(String key) {
        final MutableLiveData<NewsResponse> newsData = new MutableLiveData<>();
        newsApi.getNewsList(key).enqueue(new Callback<NewsResponse>() {
            @Override
            public void onResponse(Call<NewsResponse> call,
                                   Response<NewsResponse> response) {

                if (response.isSuccessful()) {
                    newsData.setValue(response.body());
                }
            }

            @Override
            public void onFailure(Call<NewsResponse> call, Throwable t) {
                newsData.setValue(null);
            }
        });
        return newsData;
    }


    public NewsRepository(Application application) {
        FavNewsDatabase database = FavNewsDatabase.getInstance(application);
        favNewsDao = database.noteDao();
        allNotes = favNewsDao.getAllNotes();
    }

    public void insert(FavNews favNews) {
        new InsertNoteAsyncTask(favNewsDao).execute(favNews);
    }


    public LiveData<List<FavNews>> getAllNotes() {
        return allNotes;
    }

    private static class InsertNoteAsyncTask extends AsyncTask<FavNews, Void, Void> {
        private FavNewsDao favNewsDao;

        private InsertNoteAsyncTask(FavNewsDao favNewsDao) {
            this.favNewsDao = favNewsDao;
        }

        @Override
        protected Void doInBackground(FavNews... favNews) {
            favNewsDao.insert(favNews[0]);
            return null;
        }
    }
}

就像我说的那样,我在Log中尝试了所有操作,它向我显示了字符串,但是每当我插入insert方法代码时,它都会使我无效,请先帮忙谢谢。

编辑

NoteViewModel viewmodel;

 // and here 
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
         //here need to put insert method
          String a = articles.get(position).getWebTitle();
          String b = articles.get(position).getSectionName();
Log.e("test",a + b )
       everything till here works and i see the a + b in the log
     viewmodel.insert(new FavNews(a,b))     **here null exception**

  }
 });

新闻片段

public class NewsFragment extends Fragment {


    ArrayList<Result> articleArrayList = new ArrayList<>();
    NewsAdapter newsAdapter;
    RecyclerView rvHeadline;
    private SwipeRefreshLayout swipeRefreshLayout;

    private static final String TAG = "NewsFragment";

    private NoteViewModel pageViewModel;

    public NewsFragment() {
        // Required empty public constructor
    }


    public static NewsFragment newInstance() {
        return new NewsFragment();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        pageViewModel = ViewModelProviders.of(this).get(NoteViewModel.class);

    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup
            container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View root = inflater.inflate(R.layout.news_fragment, container, false);
        rvHeadline = root.findViewById(R.id.rvNews);
        swipeRefreshLayout= root.findViewById(R.id.swip_refresh_layout);


        if (CheckInternet.isNetwork(getActivity())) {
            pageViewModel.getNewsRepository().observe(this, new
                    Observer<NewsResponse>() {
                        @Override
                        public void onChanged(NewsResponse newsResponse) {
                            List<Result> newsArticles = newsResponse.getResponse().getResults();
                            articleArrayList.addAll(newsArticles);

                            newsAdapter.notifyDataSetChanged();
                        }
                    });
        }else{
            Toast.makeText(getActivity(),"something",Toast.LENGTH_SHORT).show();
        }

        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                if (CheckInternet.isNetwork(getActivity())) {
                    pageViewModel.getNewsRepository().observe(getActivity(), new Observer<NewsResponse>() {
                        @Override
                        public void onChanged(NewsResponse newsResponse) {
                            List<Result> newsArticles = newsResponse.getResponse().getResults();
                            articleArrayList.addAll(newsArticles);

                            newsAdapter.notifyDataSetChanged();
                        }
                    });
                }else{
                    Toast.makeText(getActivity(),"something",Toast.LENGTH_SHORT).show();
                }
                swipeRefreshLayout.setRefreshing(false);
            }
        });



        setupRecyclerView();

        return root;
    }

    private void setupRecyclerView() {
        if (newsAdapter == null) {
            newsAdapter = new NewsAdapter(getActivity(), articleArrayList);
            rvHeadline.setLayoutManager(new LinearLayoutManager(getActivity()));
            rvHeadline.setAdapter(newsAdapter);
            rvHeadline.setItemAnimator(new DefaultItemAnimator());
            rvHeadline.setNestedScrollingEnabled(true);
        } else {
            newsAdapter.notifyDataSetChanged();
        }

    }
}

2 个答案:

答案 0 :(得分:1)

您必须将viewModel实例从片段传递到适配器,才能在viewModel内部访问insert。检查以下内容:

public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.NewsViewHolder> {

    Context context;
    ArrayList<Result> articles;
    NoteViewModel viewModel;


    public NewsAdapter(Context context, ArrayList<Result> articles, NoteViewModel viewModel) {
        this.context = context;
        this.articles = articles;
        this.viewModel = viewModel;
    }

    @Override
    public void onBindViewHolder(@NonNull NewsViewHolder holder, final int position) {

        ....

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //here need to put insert method
                String a = articles.get(position).getWebTitle();
                String b = articles.get(position).getSectionName();
                Log.e("test", a + b);
                //everything till here works and i see the a + b in the log
                viewmodel.insert(new FavNews(a, b)); /**here null exception **/

            }
        });
    }
}

然后在您的通话NewsAdapter中,如下所示:

newsAdapter = new NewsAdapter(getActivity(), articleArrayList, pageViewModel);

现在应该可以使用了。

答案 1 :(得分:0)

将1行代码更改为另一种方法后,它在这里起作用是问题..>!

repository = NewsRepository.getInstance(); 

只需将其从MutableLiveData更改为NoteViewModel方法

 public class NoteViewModel extends AndroidViewModel {


 private NewsRepository repository;
  private LiveData<List<FavNews>> allNotes;



public MutableLiveData<NewsResponse> getNewsRepository() {
 repository = NewsRepository.getInstance();   //from here
return repository.getNews( "b70d396f-d5b4-43f0-8b67-222524937f25");
 }

public NoteViewModel(@NonNull Application application) {
super(application);
 repository = NewsRepository.getInstance();    //// to here
repository = new NewsRepository(application);
allNotes = repository.getAllNotes();
 }

public void insert(FavNews favNews) {
repository.insert(favNews);
}



 public LiveData<List<FavNews>> getAllNotes() {
  return allNotes;
}
}