![](/img/trans.png)
[英]How to update Recyclerview oderBy().startAt() on selection of Spinner
[英]How to update recyclerview based on spinner selection MVVM + LiveData
我有一个 Android 应用程序(Java),它使用 MVVM + LiveData 按季节显示节目列表。 当用户第一次登陆片段时,我希望第 1 季的标题显示在 RecyclerView 中。 然后我希望用户能够 select 另一个赛季然后显示这些标题。 我可以将所选季节发送到我的 ViewModel,但我不知道如何使用所选季节的标题更新我的 RecyclerView。 任何帮助是极大的赞赏!
这是我的片段:
public class ShowFragment extends Fragment {
private ShowTitlesAdapter showTitlesAdapter;
private ArrayList<Titles> titlesList;
private FragmentShowBinding binding;
private TitlesViewModel titlesViewModel;
private String ShowTag, ShowTitle, ShowImgUrl;
private RecyclerView rvTitles;
private Spinner popupSpinner;
public ShowFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
binding = FragmentShowBinding.inflate(inflater, container, false);
View view = binding.getRoot();
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
titlesList = new ArrayList<>();
titlesViewModel = new ViewModelProvider(this).get(TitlesViewModel.class);
initAdapter();
init();
ShowFragmentArgs args = ShowFragmentArgs.fromBundle(getArguments());
ShowTag = args.getFranchiseTag();
titlesViewModel.getAllTitles(ShowTag);
ShowImgUrl = args.getShowImg();
ShowTitle = args.getShowTitle();
titlesViewModel.getAllTitles(ShowTitle);
binding.showTitle.setText(ShowTitle);
Drawable placeHolder = getResources().getDrawable(R.drawable.placeholder_1080x1080);
Glide.with(getContext())
.load(ShowImgUrl) //image url
.placeholder(placeHolder)
.into(binding.showImage);
}
private void initAdapter() {
binding.rvTitles.setLayoutManager(new LinearLayoutManager(getContext()));
showTitlesAdapter = new ShowTitlesAdapter(getContext(), titlesList);
binding.rvTitles.setAdapter(showTitlesAdapter);
}
private void init() {
titlesList.clear();
titlesViewModel.sortedSeasonListOne.observe(getViewLifecycleOwner(), new Observer<List<Titles>>() {
@Override
public void onChanged(List<Titles> titles) {
titlesList.addAll(titles);
showTitlesAdapter.setShowTitlesList(titlesList);
}
});
titlesViewModel.getAllTitles(ShowTag);
createDropDownList(titlesList);
}
public void createDropDownList(ArrayList<Titles> titles) {
List<String> seasonListStr = new ArrayList<>();
titlesViewModel.seasonsStrList.observe(getViewLifecycleOwner(), new Observer<List<String>>() {
@Override
public void onChanged(List<String> seasons) {
seasonListStr.addAll(seasons);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
seasonListStr.replaceAll(s -> "Season " + s);
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_list_item_1, seasonListStr);
adapter.setDropDownViewResource(android.R.layout.simple_list_item_1);
binding.popupSpinner.setAdapter(adapter);
binding.popupSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long l) {
titlesViewModel.populateTitlesInSeason(parent.getItemAtPosition(position).toString());
// showTitlesAdapter.setShowTitlesList(titlesList); --> I don't know how to update this list with another season of titles!
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
binding.popupSpinner.setAdapter(adapter);
}
});
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
视图模型:
public class TitlesViewModel extends ViewModel {
Repository repository;
private final io.reactivex.rxjava3.disposables.CompositeDisposable disposables = new CompositeDisposable();
public MutableLiveData<ArrayList<Titles>> titlesListLiveData;
public List<String> seasonsList;
public LiveData<List<Titles>> sortedList;
public LiveData<List<Titles>> sortedSeasonListOne;
public LiveData<List<Titles>> sortedSeasonListSeason;
public LiveData<List<Integer>> seasons;
public LiveData<List<String>> seasonsStrList;
@Inject
public TitlesViewModel(Repository repository) {
this.repository = repository;
titlesListLiveData = repository.getTitlesLiveData();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
sortedList = Transformations.map(titlesListLiveData, titlesList -> titlesList.stream().sorted(Comparator.comparing(Titles::getSeasonNumber).thenComparing(Titles::getEpisodeNumber)).collect(Collectors.toList()));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
seasons = Transformations.map(sortedList, list -> list.stream().map(Titles::getSeasonNumber).distinct().collect(Collectors.toList()));
seasonsStrList = Transformations.map(seasons, strList -> strList.stream().map(Object::toString).collect(Collectors.toList()));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
sortedSeasonListOne = Transformations.map(titlesListLiveData, srtList -> srtList.stream().sorted(Comparator.comparing(Titles::getSeasonNumber).thenComparing(Titles::getEpisodeNumber)).filter(list ->1 == list.getSeasonNumber()).collect(Collectors.toList()));
}
}
public void populateTitlesInSeason(String season) {
String seasonNo = season.substring(7);
int seasonNum = 1;
try{
seasonNum = Integer.parseInt(seasonNo);
}catch(NumberFormatException ex){
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
int finalSeasonNum = seasonNum;
sortedSeasonListSeason = Transformations.map(titlesListLiveData, seasonList -> seasonList.stream().sorted(Comparator.comparing(Titles::getSeasonNumber).thenComparing(Titles::getEpisodeNumber)).filter(list -> finalSeasonNum == list.getSeasonNumber()).collect(Collectors.toList()));
}
}
/////////Titles
public void getAllTitles(String tag) {
repository.getAllTitles(tag);
}
@RequiresApi(api = Build.VERSION_CODES.N)
public MutableLiveData<ArrayList<Titles>> getTitlesListLiveData() {
return repository.getTitlesLiveData();
}
@Override
protected void onCleared() {
super.onCleared();
disposables.clear();
}
}
存储库:
public class Repository {
final ApiService apiService;
private final MutableLiveData<ArrayList<Titles>> titlesList = new MutableLiveData<>();
@Inject
public Repository(ApiService service){this.apiService = service;}
public void getAllTitles(String tag){
apiService.getTitles(tag).enqueue(new Callback<ArrayList<Titles>>() {
@Override
public void onResponse(Call<ArrayList<Titles>> call, Response<ArrayList<Titles>> response) {
if (response.body() != null) {
titlesList.postValue(response.body());
}
}
@Override
public void onFailure(Call<ArrayList<Titles>> call, Throwable t) {
Log.d("Titles","onFailure"+Thread.currentThread().getName());
}
});
}
public MutableLiveData<ArrayList<Titles>> getTitlesLiveData(){
return titlesList;
}
}
RecyclerView 适配器:
public class ShowTitlesAdapter extends RecyclerView.Adapter<ShowTitlesAdapter.ShowTitlesViewHolder> {
private ItemShowTitleBinding binding;
private ArrayList<Titles> showTitles;
private Context context;
int pos;
public ShowTitlesAdapter(Context context, ArrayList<Titles> showTitles){
this.context = context;
this.showTitles = showTitles;
}
@NonNull
@Override
public ShowTitlesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
binding = ItemShowTitleBinding.inflate(inflater, parent, false);
return new ShowTitlesViewHolder(binding);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onBindViewHolder(@NonNull ShowTitlesViewHolder holder, int position) {
holder.binding.showTitleLayout.setClipToOutline(true);
holder.binding.episodeNo.setText(Integer.toString(showTitles.get(position).getEpisodeNumber()));
holder.binding.episodeTitle.setText(showTitles.get(position).getTitle());
pos = position;
holder.binding.showTitleLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ShowFragmentDirections.ActionShowFragmentToMovieShowDetailFragment action =
ShowFragmentDirections.actionShowFragmentToMovieShowDetailFragment(showTitles.get(position).getId(), showTitles.get(position).getFranchiseTag());
Navigation.findNavController(v).navigate((NavDirections) action);
}
});
}
@Override
public int getItemCount() {
if(showTitles != null){
return showTitles.size();
}
return 0;
}
public class ShowTitlesViewHolder extends RecyclerView.ViewHolder {
private ItemShowTitleBinding binding;
public ShowTitlesViewHolder(ItemShowTitleBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
public void setShowTitlesList(ArrayList<Titles> showTitles){
this.showTitles = showTitles;
notifyDataSetChanged();
}
}
简而言之:
ShowFragment
中,您需要观察sortedSeasonListSeason
的TitlesViewModel
populateTitlesInSeason
(您已经这样做了)populateTitlesInSeason
方法中,您应该通过MutableLiveData
将sortedSeasonListSeason
列表传回ShowFragment
TitlesViewModel
中为sortedSeasonListSeason
列表创建MutableLiveData
以传递选定的数据,例如sortedSeasonListSeasonLiveData
sortedSeasonListSeasonLiveData.postValue(sortedSeasonListSeason)
ShowFragment
并从我的指令的第 1 阶段处理观察者中收到的具体标题列表
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.