- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 RecyclerView
来显示最喜欢的电影列表,当用户单击
我的 RecyclerView
列表中的项目时,它将打开 DetailActivity
,在此 Activity
中,用户可以从 Collection 夹列表中删除数据。当用户点击 DetailActivity
中的 onBackPressed
时,我的 RecyclerView
没有任何反应,它仍然显示已删除的数据。
这是我的电影 fragment :
public class MovieFragment extends BaseFragment<FragmentMovieBinding, MovieViewModel>
implements MovieNavigator, MovieAdapter.MovieAdapterListener {
@Inject
MovieAdapter adapter;
@Inject
LinearLayoutManager mLayoutManager;
@Inject
ViewModelProviderFactory factory;
FragmentMovieBinding fragmentMovieBinding;
private MovieViewModel movieViewModel;
private static final String ARG_PARAM = "flag_data";
private int mData;
public static MovieFragment newInstance(int data) {
Bundle args = new Bundle();
MovieFragment fragment = new MovieFragment();
args.putInt(ARG_PARAM, data);
fragment.setArguments(args);
return fragment;
}
@Override
public int getBindingVariable() {
return BR.viewModel;
}
@Override
public int getLayoutId() {
return R.layout.fragment_movie;
}
@Override
public MovieViewModel getViewModel() {
movieViewModel = ViewModelProviders.of(this, factory).get(MovieViewModel.class);
return movieViewModel;
}
@Override
public void handleError(String error) {
// handle error
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mData = getArguments().getInt(ARG_PARAM);
}
movieViewModel.setNavigator(this);
adapter.setListener(this);
movieViewModel.fetchData(mData);
subscribeToLiveData();
}
@Override
public void onRetryClick() {
movieViewModel.fetchData(mData);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
fragmentMovieBinding = getViewDataBinding();
setUp();
}
private void subscribeToLiveData() {
movieViewModel.getMovieListLiveData().observe(this, movieList -> {
movieViewModel.setMovieDataList(movieList);
adapter.setData(movieList);
});
}
@Override
public void updateData(List<Movie> movieList) {
adapter.addItems(movieList);
}
private void setUp() {
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
fragmentMovieBinding.recyclerMovie.setLayoutManager(mLayoutManager);
fragmentMovieBinding.recyclerMovie.setItemAnimator(new DefaultItemAnimator());
fragmentMovieBinding.recyclerMovie.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
这是我的适配器:
public class MovieAdapter extends RecyclerView.Adapter<BaseViewHolder> {
public static final int VIEW_TYPE_EMPTY = 0;
public static final int VIEW_TYPE_NORMAL = 1;
private List<Movie> mMovieList;
private MovieAdapterListener mListener;
private Context mContext;
public MovieAdapter(Context context, List<Movie> movieList) {
this.mContext = context;
this.mMovieList = movieList;
}
@Override
public int getItemCount() {
if (mMovieList != null && mMovieList.size() > 0) {
return mMovieList.size();
} else {
return 1;
}
}
@Override
public int getItemViewType(int position) {
if (mMovieList != null && !mMovieList.isEmpty()) {
return VIEW_TYPE_NORMAL;
} else {
return VIEW_TYPE_EMPTY;
}
}
@Override
public void onBindViewHolder(BaseViewHolder holder, int position) {
holder.onBind(position);
}
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case VIEW_TYPE_NORMAL:
ItemMovieBinding itemMovieBinding = ItemMovieBinding.inflate(LayoutInflater.from(parent.getContext()),
parent, false);
return new MovieViewHolder(itemMovieBinding);
case VIEW_TYPE_EMPTY:
default:
ItemEmptyMovieBinding emptyViewBinding = ItemEmptyMovieBinding.inflate(LayoutInflater.from(parent.getContext()),
parent, false);
return new EmptyViewHolder(emptyViewBinding);
}
}
public void addItems(List<Movie> movieList) {
mMovieList.addAll(movieList);
notifyDataSetChanged();
}
public void setData(List <Movie> movieList){
if (mMovieList !=null&& mMovieList.size()>0){
mMovieList.clear();
mMovieList.addAll(movieList);
}
notifyDataSetChanged();
}
public void clearItems() {
mMovieList.clear();
}
public void setListener(MovieAdapterListener listener) {
this.mListener = listener;
}
public interface MovieAdapterListener {
void onRetryClick();
}
public class MovieViewHolder extends BaseViewHolder implements MovieItemViewModel.MovieItemViewModelListener {
private ItemMovieBinding mBinding;
private MovieItemViewModel mMovieItemViewModel;
public MovieViewHolder(ItemMovieBinding binding) {
super(binding.getRoot());
this.mBinding = binding;
}
@Override
public void onBind(int position) {
final Movie movie = mMovieList.get(position);
mMovieItemViewModel = new MovieItemViewModel(movie, this);
mBinding.setViewModel(mMovieItemViewModel);
mBinding.executePendingBindings();
}
@Override
public void onItemClick(int id) {
Intent intent = DetailActivity.newIntent(mContext);
intent.putExtra(INTENT_ID, id);
intent.putExtra(INTENT_FLAG, 1);
mContext.startActivity(intent);
}
}
public class EmptyViewHolder extends BaseViewHolder implements MovieEmptyItemViewModel.MovieEmptyItemViewModelListener {
private ItemEmptyMovieBinding mBinding;
public EmptyViewHolder(ItemEmptyMovieBinding binding) {
super(binding.getRoot());
this.mBinding = binding;
}
@Override
public void onBind(int position) {
MovieEmptyItemViewModel emptyItemViewModel = new MovieEmptyItemViewModel(this);
mBinding.setViewModel(emptyItemViewModel);
}
@Override
public void onRetryClick() {
mListener.onRetryClick();
}
}
}
这是我的 MovieViewModel
。类:
public class MovieViewModel extends BaseViewModel<MovieNavigator> {
private final MutableLiveData<List<Movie>> movieListLiveData;
private final ObservableList<Movie> movieDataList = new ObservableArrayList<>();
public MovieViewModel(DataManager dataManager, SchedulerProvider schedulerProvider) {
super(dataManager, schedulerProvider);
movieListLiveData = new MutableLiveData<>();
// fetchData();
}
public void fetchData(int data) {
setIsLoading(true);
if (data == 1) {
getCompositeDisposable().add(getDataManager()
.getApiHelper().doMovieCall(URLConfig.API_KEY, getDataManager().getLanguage())
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(movieResponse -> {
if (movieResponse != null && movieResponse.getResults() != null) {
movieListLiveData.setValue(movieResponse.getResults());
}
setIsLoading(false);
}, throwable -> {
setIsLoading(false);
}));
}else if (data == 2){
getCompositeDisposable().add(getDataManager()
.getDbHelper().getAllFavMovie()
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(movieResponse -> {
if (movieResponse != null) {
movieListLiveData.setValue(movieResponse);
}
setIsLoading(false);
}, throwable -> {
setIsLoading(false);
}));
}
}
public LiveData<List<Movie>> getMovieListLiveData() {
return movieListLiveData;
}
public ObservableList<Movie> getMovieDataList() {
return movieDataList;
}
public void setMovieDataList(List<Movie> movies) {
movieDataList.clear();
movieDataList.addAll(movies);
}
}
有关详细信息,这是我的 DetailActivity
:
public class DetailActivity extends BaseActivity<ActivityDetailBinding, DetailViewModel> implements DetailNavigator {
@Inject
ViewModelProviderFactory factory;
private DetailViewModel detailViewModel;
public static final String INTENT_ID = "id_intent";
public static final String INTENT_FLAG = "id_flag";
private ActivityDetailBinding mActivityDetailBinding;
public static Intent newIntent(Context context) {
return new Intent(context, DetailActivity.class);
}
@Override
public int getBindingVariable() {
return BR.viewModel;
}
@Override
public int getLayoutId() {
return R.layout.activity_detail;
}
@Override
public DetailViewModel getViewModel() {
detailViewModel = ViewModelProviders.of(this, factory).get(DetailViewModel.class);
return detailViewModel;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivityDetailBinding = getViewDataBinding();
detailViewModel.setNavigator(this);
initData(savedInstanceState);
initView();
}
private void initData(Bundle savedInstanceState) {
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if (extras != null) {
int id = extras.getInt(INTENT_ID, 0);
int flag = extras.getInt(INTENT_FLAG, 0);
if (isNetworkConnected()) {
detailViewModel.fetchDetail(id, flag);
detailViewModel.setIsConnected(true);
} else {
detailViewModel.setIsConnected(false);
CommonUtils.ShowSnackBars(mActivityDetailBinding.getRoot(), getString(R.string.msg_error_connection), 0, this);
}
}
}
}
private void initView() {
if (getSupportActionBar() != null) {
getSupportActionBar().hide();
}
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
@Override
public void ShowProgressDialog(Boolean loading) {
if (loading) {
showLoading();
} else {
hideLoading();
}
}
@Override
public void onBackArrowClick() {
onBackPressed();
}
@Override
public void onFavProcess(int flag) {
if (flag == 0) {
CommonUtils.ShowSnackBars(mActivityDetailBinding.getRoot(), getString(R.string.msg_success_add_fav), 1, this);
}else {
CommonUtils.ShowSnackBars(mActivityDetailBinding.getRoot(), getString(R.string.msg_success_remove_fav), 1, this);
}
}
@Override
public String noDesc() {
return getResources().getString(R.string.no_desc);
}
}
这是我的 DetailViewModel
类:
public class DetailViewModel extends BaseViewModel<DetailNavigator> {
private final ObservableField<String> originalName = new ObservableField<>();
private final ObservableField<String> releaseDate = new ObservableField<>();
private final ObservableField<String> overview = new ObservableField<>();
private final ObservableField<String> genreMovie = new ObservableField<>();
private final ObservableField<String> posterPath = new ObservableField<>();
private final ObservableField<String> voteAverage = new ObservableField<>();
private MutableLiveData<Integer> idDetail = new MutableLiveData<>();
private MutableLiveData<Boolean> flagDetail = new MutableLiveData<>();
private MutableLiveData<Integer> flagScreen = new MutableLiveData<>();
private Movie movie;
private TvShow tvShow;
public DetailViewModel(DataManager dataManager, SchedulerProvider schedulerProvider) {
super(dataManager, schedulerProvider);
}
public void fetchDetail(int id, int flag) {
if (flag == 1) {
getNavigator().ShowProgressDialog(true);
getCompositeDisposable().add(getDataManager()
.getApiHelper().doDetailMovie(id, URLConfig.API_KEY, getDataManager().getLanguage())
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(detailResponse -> {
flagScreen.setValue(flag);
setUpData(detailResponse);
getNavigator().ShowProgressDialog(false);
}, throwable -> {
getNavigator().ShowProgressDialog(false);
}));
} else if (flag == 2) {
getNavigator().ShowProgressDialog(true);
getCompositeDisposable().add(getDataManager()
.getApiHelper().doDetailTV(id, URLConfig.API_KEY, getDataManager().getLanguage())
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(detailResponse -> {
flagScreen.setValue(flag);
setUpData(detailResponse);
getNavigator().ShowProgressDialog(false);
}, throwable -> {
getNavigator().ShowProgressDialog(false);
}));
}
}
private void setUpData(DetailResponse detailResponse) {
if (flagScreen.getValue() == 1) {
movie = new Movie();
movie.setId(detailResponse.getId());
movie.setTitle(detailResponse.getOriginal_title());
movie.setPoster_path(detailResponse.getPoster_path());
movie.setRelease_date(detailResponse.getRelease_date());
movie.setVote_average(detailResponse.getVote_average());
} else {
tvShow = new TvShow();
tvShow.setId(detailResponse.getId());
tvShow.setTitle(detailResponse.getOriginal_name());
tvShow.setPoster_path(detailResponse.getPoster_path());
tvShow.setFirst_air_date(detailResponse.getFirst_air_date());
tvShow.setVote_average(detailResponse.getVote_average());
}
if (detailResponse.getOriginal_name() != null) {
originalName.set(detailResponse.getOriginal_name());
} else if (detailResponse.getOriginal_title() != null) {
originalName.set(detailResponse.getOriginal_title());
} else {
}
if (detailResponse.getFirst_air_date() != null) {
releaseDate.set(detailResponse.getFirst_air_date());
} else {
releaseDate.set(detailResponse.getRelease_date());
}
if (!detailResponse.getOverview().equals("")) {
overview.set(detailResponse.getOverview());
} else {
overview.set(getNavigator().noDesc());
}
posterPath.set(String.valueOf(detailResponse.getPoster_path()));
voteAverage.set(String.valueOf(detailResponse.getVote_average()));
String genres = "";
for (int i = 0; i < detailResponse.getGenreList().size(); i++) {
genres = genres + detailResponse.getGenreList().get(i).getName();
if (i != detailResponse.getGenreList().size() - 1) {
genres = genres + ", ";
}
}
genreMovie.set(genres);
idDetail.setValue(detailResponse.getId());
setUpFlagFav();
}
private void setUpFlagFav() {
if (flagScreen.getValue() == 1) {
getCompositeDisposable().add(getDataManager()
.getDbHelper().getMovie(idDetail.getValue())
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(response -> {
if (response.size() > 0) {
flagDetail.setValue(true);
} else {
flagDetail.setValue(false);
}
Log.i("CEK INSERT", String.valueOf(flagDetail.getValue()));
}, throwable -> {
flagDetail.setValue(false);
}));
}else if (flagScreen.getValue() == 2) {
getCompositeDisposable().add(getDataManager()
.getDbHelper().getTv(idDetail.getValue())
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(response -> {
if (response.size() > 0) {
flagDetail.setValue(true);
} else {
flagDetail.setValue(false);
}
Log.i("CEK INSERT", String.valueOf(flagDetail.getValue()));
}, throwable -> {
flagDetail.setValue(false);
}));
}
}
public void onBackArrowClick() {
getNavigator().onBackArrowClick();
}
public void onFavClick() {
if (flagScreen.getValue() == 1) {
if (flagDetail.getValue()) {
getCompositeDisposable().add(getDataManager()
.getDbHelper().deleteMovie(idDetail.getValue())
.flatMap(aBoolean -> getDataManager().getDbHelper().deleteMovie(idDetail.getValue()))
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(aBoolean -> {
getNavigator().onFavProcess(1);
flagDetail.setValue(false);
Log.i("CEK delete", String.valueOf(aBoolean));
}, throwable -> {
getNavigator().onFavProcess(1);
}));
} else {
getCompositeDisposable().add(getDataManager()
.getDbHelper().saveMovie(movie)
.flatMap(aBoolean -> getDataManager().getDbHelper().saveMovie(movie))
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(aBoolean -> {
getNavigator().onFavProcess(0);
flagDetail.setValue(true);
Log.i("CEK INSERT", String.valueOf(aBoolean));
}, throwable -> {
getNavigator().onFavProcess(0);
}));
}
}else {
if (flagDetail.getValue()) {
getCompositeDisposable().add(getDataManager()
.getDbHelper().deleteTv(idDetail.getValue())
.flatMap(aBoolean -> getDataManager().getDbHelper().deleteMovie(idDetail.getValue()))
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(aBoolean -> {
getNavigator().onFavProcess(1);
flagDetail.setValue(false);
}, throwable -> {
getNavigator().onFavProcess(1);
}));
} else {
getCompositeDisposable().add(getDataManager()
.getDbHelper().saveTv(tvShow)
.flatMap(aBoolean -> getDataManager().getDbHelper().saveMovie(movie))
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(aBoolean -> {
getNavigator().onFavProcess(0);
flagDetail.setValue(true);
}, throwable -> {
getNavigator().onFavProcess(0);
}));
}
}
}
public ObservableField<String> getOriginalName() {
return originalName;
}
public ObservableField<String> getReleaseDate() {
return releaseDate;
}
public ObservableField<String> getOverview() {
return overview;
}
public ObservableField<String> getGenreMovie() {
return genreMovie;
}
public ObservableField<String> getPosterPath() {
return posterPath;
}
public ObservableField<String> getVoteAverage() {
return voteAverage;
}
public MutableLiveData<Boolean> getFlagDetail() {
return flagDetail;
}
}
让我感到困惑的是,我已经使用此代码在MovieFragment
中订阅了LiveData
:
private void subscribeToLiveData () {
movieViewModel.getMovieListLiveData (). observe (this, movieList -> {
movieViewModel.setMovieDataList (movieList);
adapter.setData (movieList);
});
}
但是当我在 DetailActivity
中执行 onBackPressed
时,RecyclerView
没有任何变化。但是,如果我先转到另一个菜单(例如 Catalog
),然后再返回到Favorite
,数据将会改变,然后 RecyclerView
就会改变。
希望有人能帮我解决这个问题。谢谢
最佳答案
您没有在适配器的 clearItems()
方法中提到 notifyDataSetChanged()
。
关于java - 房间数据库 : RecyclerView does not update after delete data in detail activity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58178044/
我对 Android 很陌生,如果问题重复,请避免并发送链接。有三个 Activity A、B 和 C。 Activity A 获取一个用户名,我想在 Activity C 中显示该用户名,但我想先运
我正在尝试制作记事本应用程序,因此每次打开新笔记时,布局都会相同。另外, Activity 的数量(新注释)不应定义得尽可能多 最佳答案 如果 Activity 始终相同,您可能应该创建一个适配器,允
我有 3 个 Activity 。 主窗口 5 个按钮 在按钮的主窗口中按下此窗口打开(将其称为父窗口) 在父窗口按钮上按下此窗口打开调用它作为结束子窗口。 现在从子窗口我从父窗口获取值如下:
我遇到了一个 Activity backstack 问题。假设我的后台有 5 个 Activity :比如 Activity A、 Activity B、 Activity C、 Activity D
我正在寻找必须具有以下附加特征的 JMS 提供程序: 采用多代理,所有代理都必须处于事件状态(无单点故障) 仅在两台机器上进行扩展就足以满足我们的需求 能够保证订购(如果 1 个生产者 + 1 个消费
假设,我有一个由 TabHost 组成的选项卡 Activity 。 TabHost 包含 2 个选项卡,每两个选项卡都有一个 Activity 组。每个 Activity 组包含一项 Activit
我正在开发一个应用程序,我需要根据某些操作导航到特定 Activity 。这是一张图片 我的第一个 Activity 是 ReadingActivity。基于某些操作,用户将被带到 NewProjec
我创建了一个与服务器异步通信的应用程序。当应用程序发出服务器请求时,将创建一个带有“正在加载”通知的新对话框( Activity )。主要 Activity 实现了处理服务器响应的方法,我想在主要 A
我想在我的所有应用程序 Activity 中显示相同的选项菜单。我创建了一个实现菜单的通用 Activity ,并且我所有的进一步 Activity 都扩展了它。 问题:当我需要扩展其他特定 Acti
我有四个 Activity ,即 java 文件 - Activity1.java、activity2.java、activity3.java、activity4.java 和 xml 文件 - Ac
我有两个 Activity 。我想将数据从第二个 Activity 发送到上一个 Activity 。第一个 Activity 有自定义 ListView 和 bean 类。当我点击第二个 Activ
根 Activity 是堆栈中当前的第一个 Activity 还是 list 中指定为启动 Activity 的 Activity ? 支持应用程序 P 在启动时启动 Activity A。然后 A
你好 我想知道您在绘制 Activity 图选择“Activity ”时考虑了哪些关键点? 您如何从要建模的问题中选择 Activity ? 谢谢 最佳答案 Activity 图用于对正在开发的系统和
如何从主 Activity 启动 Activity 并在子 Activity 返回主 Activity 中退出操作后返回主 Activity ? 我已将子 Activity 作为启动器 Intent
我的工作流程如下: 登录 Activity -> ActivityB -> ActivityC -> ActivityD 我想将数据从LoginActivity传递到ActivityD,但不直接传递到
我之前曾尝试获得此问题的答案,但找不到可以解决我的问题的答案。我正在制作保存圆盘高尔夫球分数的应用程序。我的 MainActivity 有 4 个按钮。新比赛、恢复比赛、类(class)和球员。 At
我有一个 tts 非 UI 类和 Activity 类。现在在 Activity 类中,我有一个按钮,用户可以从中选择男声或女声,具体取决于我想要将字符串传递给 tts 类的选择,然后一次tts 类根
问题有点复杂,首先, Activity A 和 Activity B 的 list 中都有 android:noHistory = true 。我有一个自定义 serialized 类,假设 MyCl
在我的应用程序中,我有两个 Activity (AuthenticationActivity 和 MainActivity),每个 Activity 都有一个导航图和大量 fragment 。我创建了
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: How can i use compose email activity in tabView? 我想在选项
我是一名优秀的程序员,十分优秀!