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);
? ? }
}
希望這可以幫助。
添加回答
舉報