我在Fragment中创建了一个RecyclerView。我也为此创建了一个绑定适配器(RecyclerViewBindingAdapter),RecyclerView可以正常工作。然后,我想创建另一个RecyclerView。因此,我为其创建了另一个RecyclerViewLayout和适配器(ProcessingOrdersRecyclerViewAdapter)。现在,当我运行该应用程序并转到第二个RecyclerView时,它崩溃并显示ProcessingOrdersRecyclerViewAdapter$AdapterDataItem cannot be cast to RecyclerViewBindingAdapter$AdapterDataItem
。而且错误来自第一个RecyclerView的绑定适配器(RecyclerViewBindingAdapter)。
自2天以来,我一直在尝试解决此问题,但我不知道为什么第二个RecyclerView调用第一个RecyclerView的绑定适配器getItemViewType
方法。谁能告诉我问题出在哪里?
package com.example.logisticsfree.adapters;
import android.databinding.DataBindingUtil;
import android.databinding.ObservableList;
import android.databinding.ViewDataBinding;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static android.support.constraint.Constraints.TAG;
public class ProcessingOrdersRecyclerViewAdapter extends RecyclerView.Adapter<ProcessingOrdersRecyclerViewAdapter.BindingViewHolder> {
private ObservableList<AdapterDataItem> data;
public ProcessingOrdersRecyclerViewAdapter(ObservableList<AdapterDataItem> data) {
this.data = data;
data.addOnListChangedCallback(new ObservableListCallback());
}
@Override
public BindingViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Log.d(TAG, "onCreateViewHolder: " + "Processing");
return new BindingViewHolder(DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), viewType, parent, false));
}
@Override
public void onBindViewHolder(ProcessingOrdersRecyclerViewAdapter.BindingViewHolder holder, int position) {
AdapterDataItem dataItem = data.get(position);
for (Pair<Integer, Object> idObjectPair : dataItem.idModelPairs) {
holder.bind(idObjectPair.first, idObjectPair.second);
}
// holder.bind();
holder.binding.executePendingBindings();
}
@Override
public int getItemCount() {
return data.size();
}
@Override
public int getItemViewType(int position) {
return data.get(position).layoutId;
}
private class ObservableListCallback extends ObservableList.OnListChangedCallback<ObservableList<ProcessingOrdersRecyclerViewAdapter.AdapterDataItem>> {
@Override
public void onChanged(ObservableList<AdapterDataItem> sender) {
notifyDataSetChanged();
}
@Override
public void onItemRangeChanged(ObservableList<AdapterDataItem> sender, int positionStart, int itemCount) {
notifyItemRangeChanged(positionStart, itemCount);
}
@Override
public void onItemRangeInserted(ObservableList<AdapterDataItem> sender, int positionStart, int itemCount) {
notifyItemRangeInserted(positionStart, itemCount);
}
@Override
public void onItemRangeMoved(ObservableList<AdapterDataItem> sender, int fromPosition, int toPosition, int itemCount) {
notifyDataSetChanged(); // not sure how to notify adapter of this event
}
@Override
public void onItemRangeRemoved(ObservableList<AdapterDataItem> sender, int positionStart, int itemCount) {
notifyItemRangeRemoved(positionStart, itemCount);
}
}
public class BindingViewHolder extends RecyclerView.ViewHolder {
private ViewDataBinding binding;
public BindingViewHolder(ViewDataBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
public void bind(int varId, Object obj) {
this.binding.setVariable(varId, obj);
}
}
public static class AdapterDataItem {
public int layoutId;
public List<Pair<Integer, Object>> idModelPairs;
public AdapterDataItem(int layoutId, int variableId, Object model) {
this.layoutId = layoutId;
this.idModelPairs = new ArrayList<>();
this.idModelPairs.add(new Pair<>(variableId, model));
}
public AdapterDataItem(int layoutId, Pair<Integer, Object>... idModelPairs) {
Log.d(TAG, "AdapterDataItem: " + layoutId);
this.layoutId = layoutId;
this.idModelPairs = Arrays.asList(idModelPairs);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AdapterDataItem that = (AdapterDataItem) o;
if (layoutId != that.layoutId) return false;
return idModelPairs != null ? idModelPairs.equals(that.idModelPairs) : that.idModelPairs == null;
}
@Override
public int hashCode() {
int result = layoutId;
result = 31 * result + (idModelPairs != null ? idModelPairs.hashCode() : 0);
return result;
}
}
}
ProcessingOrderListFragment.java
package com.example.logisticsfree.trip;
public class ProcessingOrderListFragment extends Fragment implements ListItemsPresenter {
private final String TAG = "ProcessingFragment";
private ObservableList<ProcessingOrdersRecyclerViewAdapter.AdapterDataItem> listItems;
private FirebaseUser mUser;
private FirebaseFirestore afs;
public ProcessingOrderListFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mUser = FirebaseAuth.getInstance().getCurrentUser();
afs = FirebaseFirestore.getInstance();
getActivity().setTitle("Orders List");
}
@android.support.annotation.Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @android.support.annotation.Nullable ViewGroup container,
@android.support.annotation.Nullable Bundle savedInstanceState) {
FragmentProcessingOrderRecyclerViewBinding mBinding = DataBindingUtil
.inflate(inflater, R.layout.fragment_processing_order_recycler_view, container, false);
mBinding.setListLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
mBinding.setModelList(initList());
mBinding.setItemAnimator(new DefaultItemAnimator());
Log.d(TAG, "onCreateView: ");
return mBinding.getRoot();
}
private void addToList(List<ProcessingOrdersRecyclerViewAdapter.AdapterDataItem> list, Invoice order) {
if (order != null) {
list.add(Utils.convertToOrder(new ItemModel(order), this));
}
}
private ObservableList initList() {
listItems = new ObservableArrayList<>();
listItems.add(new ProcessingOrdersRecyclerViewAdapter.AdapterDataItem(R.layout.layout_listitem_heading,
new Pair<Integer, Object>(BR.headingModel, new HeadingModel("Your Orders"))));
Log.d(TAG, "initList: " + R.layout.layout_listitem_heading);
return listItems;
}
@Override
public void onClick(ItemModel itemModel) {
}
@Override
public void onDeleteClick(ItemModel itemModel) { // used: only for testing purposes
// Toast.makeText(getActivity(), "Delete clicked", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onDeleteClick: " + itemModel);
HashMap<String, Object> data = new HashMap<>();
data.put("available", true);
FirebaseFirestore fs = FirebaseFirestore.getInstance();
FirebaseAuth user = FirebaseAuth.getInstance();
fs.document("/drivers/" + user.getUid()).set(data, SetOptions.merge());
fs.document("/ordered-trucks/" + itemModel.order.getCompanyID() + "/ordered-trucks/" + user.getUid())
.delete();
fs.document("/drivers/" + user.getUid() + "/orders/" + itemModel.order.getCompanyID()).delete();
}
@Override
public void onExpandClick(ItemModel itemModel) { // not used
Toast.makeText(getActivity(), "Expand clicked", Toast.LENGTH_SHORT).show();
}
@Override
public void onLoadMoreClick() { // not used
Toast.makeText(getActivity(), "loadMore clicked", Toast.LENGTH_SHORT).show();
}
}
fragment_processing_order_recycler_view.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="itemModel"
type="com.example.logisticsfree.models.ItemModel"/>
<variable
name="itemPresenter"
type="com.example.logisticsfree.presenters.ListItemsPresenter"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/orders_menu_item"
android:layout_marginTop="1dp"
android:layout_marginBottom="1dp"
android:layout_marginRight="1dp"
android:layout_marginLeft="1dp"
android:onClick="@{(v) -> itemPresenter.onClick(itemModel)}">
<LinearLayout android:layout_height="wrap_content"
android:layout_width="match_parent"
android:padding="10dp">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:textColor="#202020"
android:drawableStart="@drawable/ic_baseline_place"
android:foreground="?selectableItemBackground"
android:gravity="center_vertical"
android:text="@{itemModel.invoice.distributor.name}"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</layout>