与可扩展的嵌套回收器视图作斗争

问题描述 投票:0回答:1

我正在开发一个应用程序。它使用改造从 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;
        }
    }
}

java android rest nestedrecyclerview expandablerecyclerview
1个回答
0
投票

使用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();
        }
    });
}

现在应该可以工作了。

© www.soinside.com 2019 - 2024. All rights reserved.