我正在开发一个应用程序。它使用改造从 API 获取列表(国家和城市列表)。在我的主要活动中,我有一辆房车,它是主要房车,还显示国家/地区列表。我的国家/地区列表项有一个子 rv,显示国家/地区列表的城市。到目前为止一切都很好。但我在这里想做的是当我展开国家/地区列表项时显示城市列表。当我运行我的应用程序并展开随机国家/地区列表项并向下滚动时,我看到一些国家/地区列表项也展开了,而我没有。我做错了什么?
这是我的代码:
public class CountryRvAdapter extends RecyclerView.Adapter<CountryRvAdapter.ViewHolder> {
private ArrayList<CountryList> countryArrayList;
public CountryRvAdapter(ArrayList<CountryList> countryArrayList) {
this.countryArrayList = countryArrayList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
CountryBinding binding = CountryBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
return new ViewHolder(binding);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
CountryList countryList = countryArrayList.get(position);
holder.binding.countryName.setText(countryList.getCountry());
CityRvAdapter cityRvAdapter = new CityRvAdapter(countryList.getCitiesList());
holder.binding.cityListRv.setAdapter(cityRvAdapter);
holder.binding.expandCountryButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
RecyclerView cityListRv= holder.binding.cityListRv;
if (cityListRv.getVisibility() == View.GONE)
cityListRv.setVisibility(View.VISIBLE);
else
cityListRv.setVisibility(View.GONE);
cityRvAdapter.notifyDataSetChanged();
}
});
}
@Override
public int getItemCount() {
return countryArrayList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private CountryBinding binding;
public ViewHolder(CountryBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
}
使用recyclerview时,包含数据的视图将被回收。这意味着,如果第一个视图中的国家/地区列表项展开,则它将在其包含的下一个数据中保持展开状态。这就是您看到这种行为的原因。你必须找到一种方法来保存每个视图的状态,这样即使视图被回收,它们也会根据用户所做的更改来显示它们。
我可以想出一种方法来解决这个问题。你可以给你的
CountryList
对象一个新的属性,我们可以称之为 expanded
。这个属性是一个布尔对象,我们可以获取和设置。所以在你的 CountryList 类中,输入:
class CountryList {
// Initial state is false;
Boolean expanded = false;
public Boolean isExpanded(){
return expanded;
}
public void setExpanded(Boolean expanded){
this.expanded = expanded;
}
}
现在,在您的适配器上,我们必须检查状态是否已扩展。如果它已展开,那么让我们显示
cityListRv
。如果不是,我们就隐藏它。我们将在 onBindViewHolder
方法中进行检查。另外,当按下展开按钮时,不要忘记为 expanded
属性设置新值。
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
CountryList countryList = countryArrayList.get(position);
holder.binding.countryName.setText(countryList.getCountry());
// Set adapter for cityListRv
RecyclerView cityListRv = holder.binding.cityListRv;
CityRvAdapter cityRvAdapter = new CityRvAdapter(countryList.getCitiesList());
cityListRv.setAdapter(cityRvAdapter);
// Check if it's expanded or not and update the view
if (countryList.isExpanded()){
// It's expanded so show the cityListRv
cityListRv.setVisibility(View.VISIBLE);
} else {
// It's not expanded so hide the cityListRv
cityListRv.setVisibility(View.GONE);
}
holder.binding.expandCountryButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (cityListRv.getVisibility() == View.GONE) {
cityListRv.setVisibility(View.VISIBLE);
countryList.setExpanded(true);
} else {
cityListRv.setVisibility(View.GONE);
countryList.setExpanded(false);
}
cityRvAdapter.notifyDataSetChanged();
}
});
}
现在应该可以工作了。