亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

具有相互通信的多個視圖類型的 Recyclerview?

具有相互通信的多個視圖類型的 Recyclerview?

largeQ 2024-01-17 20:49:20
具有多種視圖類型的 RecyclerView 是否可以相互傳遞數據/通信/監聽?我有一個具有 3 種視圖類型的 RecyclerView(分別命名為頂部、中間、底部)。我有 2 個編輯文本位于第二個視圖類型中,名為重量和數量。第三個視圖類型中的 1 個文本視圖計算并顯示輸入的重量和數量的體積。我希望第三個視圖類型包含在輸入重量或數量字段時動態動態更改的總體積。
查看完整描述

1 回答

?
波斯汪

TA貢獻1811條經驗 獲得超4個贊

您可以使用Google Android架構中的LiveData以及一些接口來實現您想要的。

-> 聲明Interfaces您需要調用的各種方法ViewHolders來實現您想要的邏輯

interface AnimalVolumeChangeListener{


? ? public void onAnimalVolumeChanged(int groupId, double previousVolume, double currentVolume);


}


interface TotalVolumeInterface{


? ? public Pair<LifecycleOwner,LiveData<Double>> getTotalVolume(int groupId);


? ? public void removeObservers(int groupId);


}

-> 將這些接口作為對象傳遞到 Recycler Adapter 的構造函數中。


class Animal_Volume_Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

? ? private ArrayList<AnimalsArray> mList;

? ? private TotalVolumeInterface mTotalVolumeInterface;

? ? private AnimalVolumeChangeListener mAnimalVolumeChangeListener;

? ? private double volume = 0;


? ? public Animal_Volume_Adapter(ArrayList<AnimalsArray> list,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?TotalVolumeInterface totalVolumeInterface,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?AnimalVolumeChangeListener animalVolumeChangeListener) {

? ? ? ? this.mList = list;

? ? ? ? this.mTotalVolumeInterface = totalVolumeInterface;

? ? ? ? this.mAnimalVolumeChangeListener = animalVolumeChangeListener;

? ? }

-> 在創建視圖持有者時將您作為參數傳遞給相應視圖持有者的接口設置


@Override

? ? public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

? ? ? ? switch (viewType) {

? ? ? ? ? ? case AnimalsArray.TOP:

? ? ? ? ? ? ? ? View top = LayoutInflater.from(parent.getContext()).inflate(R.layout.animal_top_layout, parent, false);

? ? ? ? ? ? ? ? return new Top(top);

? ? ? ? ? ? case AnimalsArray.MIDDLE:

? ? ? ? ? ? ? ? View data = LayoutInflater.from(parent.getContext()).inflate(R.layout.animal_middle_layout, parent, false);

? ? ? ? ? ? ? ? Middle middleHolder = new Middle(data);

? ? ? ? ? ? ? ? middleHolder.setAnimalVolumeChangeListener(mAnimalVolumeChangeListener);

? ? ? ? ? ? ? ? return middleHolder;

? ? ? ? ? ? case AnimalsArray.BOTTOM:

? ? ? ? ? ? ? ? View footer = LayoutInflater.from(parent.getContext()).inflate(R.layout.animal_bottom_layout, parent, false);

? ? ? ? ? ? ? ? Bottom bottomHolder = new Bottom(footer);

? ? ? ? ? ? ? ? bottomHolder.setTotalVolumeInterface(mTotalVolumeInterface);

? ? ? ? ? ? ? ? return bottomHolder;


? ? ? ? }

? ? ? ? return null;

? ? }

修改ViewHolder類


static class Middle extends RecyclerView.ViewHolder {

? ? Context context;

? ? EditText weight;

? ? EditText quantity;

? ? TextView volume;

? ? AnimalVolumeChangeListener animalVolumeChangeListener;


? ? Middle(final View itemView) {

? ? ? ? super(itemView);

? ? ? ? context = itemView.getContext();

? ? ? ? volume = (EditText) itemView.findViewById(R.id.volume);

? ? ? ? weight = (EditText) itemView.findViewById(R.id.weight);

? ? ? ? quantity= (EditText) itemView.findViewById(R.id.quantity);

? ? }


? ? public void setAnimalVolumeChangeListener(AnimalVolumeChangeListener animalVolumeChangeListener) {

? ? ? ? this.animalVolumeChangeListener = animalVolumeChangeListener;

? ? }


}


static class Bottom extends RecyclerView.ViewHolder {

? ? TextView volume;

? ? TotalVolumeInterface totalVolumeInterface;


? ? Bottom(View itemView) {

? ? ? ? super(itemView);

? ? ? ? volume = (TextView) itemView.findViewById(R.id.volumeText);



? ? }


? ? public void setTotalVolumeInterface(TotalVolumeInterface totalVolumeInterface) {

? ? ? ? this.totalVolumeInterface = totalVolumeInterface;

? ? }


}

-> 在需要時從 onBindViewHolder 中的界面調用方法。


在您的情況下,您需要有一種方法來識別 ViewHolderMiddle的總體積對 ViewHolder 的值有貢獻Bottom(因此下面我用來groupId表示此參數)。


@Override

? ? public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {

? ? ? ? final AnimalsArray object = mList.get(position);


? ? ? ? /* middle holders contributing to the total volume of the same have the

? ? ? ? ?*same groupId together with their corressponding bottom holder.

? ? ? ? ?*TODO: Assigned this value in accordance to however you are assigning Middle ViewHolders to Bottom ViewHolders*/

? ? ? ? int groupId = 0;


? ? ? ? if (object != null) {

? ? ? ? ? ? switch (object.getCategory()) {


? ? ? ? ? ? ? ? case AnimalsArray.TOP:

? ? ? ? ? ? ? ? ? ? break;



? ? ? ? ? ? ? ? case AnimalsArray.MIDDLE:


? ? ? ? ? ? ? ? ? ? Middle middleHolder = (Middle) holder;



? ? ? ? ? ? ? ? ? ? middleHolder.weight.addTextChangedListener(new TextWatcher() {

? ? ? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? ? ? public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {

? ? ? ? ? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? ? ? public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int arg3) {


? ? ? ? ? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? ? ? public void afterTextChanged(Editable arg0) {


? ? ? ? ? ? ? ? ? ? ? ? ? ? //While this edittext is being changed, I would like the 3rd viewtype which contains the volume to be calculated on the fly as the user enters numbers in this field.



? ? ? ? ? ? ? ? ? ? ? ? ? ? String volumeBeforeChange = middleHolder.volume.getText().toString();

? ? ? ? ? ? ? ? ? ? ? ? ? ? double previousVolume = Double.parseDouble(volumeBeforeChange);


? ? ? ? ? ? ? ? ? ? ? ? ? ? if (arg0.toString().isEmpty() || arg0.toString().length() <= 0 || arg0.toString().equals("") || arg0.toString() == null || arg0.toString().equals("0") || arg0.toString().startsWith(".")) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? middleHolder.weight.setText("0");

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? middleHolder.animalVolumeChangeListener.onAnimalVolumeChanged(middleHolder.groupId,previousVolume,0);

? ? ? ? ? ? ? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? volume = calculateWarmUpVolume(context, arg0.toString(), ((Middle) holder).quantity.getText().toString());

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? middleHolder.animalVolumeChangeListener.onAnimalVolumeChanged(middleHolder.groupId,previousVolume,volume);


? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? });



? ? ? ? ? ? ? ? ? ? middleHolder.quantity.addTextChangedListener(new TextWatcher() {

? ? ? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? ? ? public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {

? ? ? ? ? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? ? ? public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int arg3) {

? ? ? ? ? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? ? ? public void afterTextChanged(Editable arg0) {


? ? ? ? ? ? ? ? ? ? ? ? ? ? //While this edittext is being changed, I would like the 3rd viewtype which contains the volume to be calculated on the fly as the user enters numbers in this field.


? ? ? ? ? ? ? ? ? ? ? ? ? ? String volumeBeforeChange = middleHolder.volume.getText().toString();

? ? ? ? ? ? ? ? ? ? ? ? ? ? double previousVolume = Double.parseDouble(volumeBeforeChange);


? ? ? ? ? ? ? ? ? ? ? ? ? ? if (arg0.toString().isEmpty() || arg0.toString().length() <= 0 || arg0.toString().equals("") || arg0.toString() == null || arg0.toString().equals("0") || arg0.toString().startsWith(".")) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ((Middle) holder).quantity.setText("0");

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? middleHolder.animalVolumeChangeListener.onAnimalVolumeChanged(middleHolder.groupId,previousVolume,0);

? ? ? ? ? ? ? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? volume = calculateWarmUpVolume(context, ((Middle) holder).weight.getText().toString(), arg0.toString());

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? middleHolder.animalVolumeChangeListener.onAnimalVolumeChanged(middleHolder.groupId,previousVolume,volume);


? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? });


? ? ? ? ? ? ? ? ? ? break;



? ? ? ? ? ? ? ? case AnimalsArray.BOTTOM:


? ? ? ? ? ? ? ? ? ? Bottom bottomHolder = ((Bottom) holder);



? ? ? ? ? ? ? ? ? ? Pair<LifecycleOwner, LiveData<Double>> totalVolumePair = bottomHolder.totalVolumeInterface.getTotalVolume(groupId);

? ? ? ? ? ? ? ? ? ? totalVolumePair.second.observe(totalVolumePair.first,

? ? ? ? ? ? ? ? ? ? ? ? ? ? new Observer<Double>(){

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? @Override

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? public void onChanged(Double aDouble) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //Check if double is a whole number. If it is, remove decimal by converting to integer

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? String volumedWeight;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if ((aDouble % 1) == 0) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int roundedVolume = aDouble.intValue();

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? volumedWeight = Integer.toString(roundedVolume);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? volumedWeight = Double.toString(volume);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? bottomHolder.volume.setText(String.valueOf(volumedWeight));

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? );



? ? ? ? ? ? ? ? ? ? break;

? ? ? ? ? ? }


? ? ? ? }

? ? }


? ? @Override

? ? public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {

? ? ? ? super.onViewRecycled(holder);

? ? ? ? /* middle holders contributing to the total volume of the same have the

? ? ? ? ?*same groupId together with their corressponding bottom holder.

? ? ? ? ?*/

? ? ? ? int groupId = 0;

? ? ? ? if(holder instanceof Bottom){

? ? ? ? ? ? ((Bottom) holder).totalVolumeInterface.removeObservers(groupId);

? ? ? ? }

? ? }

-> 最后為接口的重寫方法編寫邏輯。


public class SetupRecyclerClass extends AppCompatActivity implements TotalVolumeInterface, AnimalVolumeChangeListener{


? ? HashMap<Integer, MutableLiveData<Double>> mTotalVolumesMap = new HashMap<>();


? ? @Override

? ? protected void onCreate(@Nullable Bundle savedInstanceState) {

? ? ? ? super.onCreate(savedInstanceState);


? ? ? ? ArrayList<AnimalsArray> animalsArrayArrayList = new ArrayList<>();

? ? ? ? Animal_Volume_Adapter adapter = new Animal_Volume_Adapter(animalsArrayArrayList,this, this);

? ? }


? ? @Override

? ? public Pair<LifecycleOwner, LiveData<Double>> getTotalVolume(int groupId) {


? ? ? ? if(mTotalVolumesMap.get(groupId) == null){

? ? ? ? ? ? mTotalVolumesMap.put(groupId,new MutableLiveData<>(0.0));

? ? ? ? }


? ? ? ? return new Pair<>(this,mTotalVolumesMap.get(groupId));

? ? }


? ? @Override

? ? public void removeObservers(int groupId) {


? ? ? ? mTotalVolumesMap.get(groupId).removeObservers(this);


? ? }


? ? @Override

? ? public void onAnimalVolumeChanged(int groupId, double previousVolume, double currentVolume) {

? ? ? ? if(mTotalVolumesMap.get(groupId) == null){

? ? ? ? ? ? mTotalVolumesMap.put(groupId,new MutableLiveData<>(0.0));

? ? ? ? }


? ? ? ? double newTotalVolume = (mTotalVolumesMap.get(groupId).getValue()-previousVolume)+currentVolume;

? ? ? ? mTotalVolumesMap.get(groupId).setValue(newTotalVolume);

? ? }

}

希望這可以幫助。


查看完整回答
反對 回復 2024-01-17
  • 1 回答
  • 0 關注
  • 183 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號