我正在尝试通过使用@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();
}
}
}
答案 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;
}
}