如何摆脱重复的RecyclerView Adapter?

时间:2018-10-21 14:25:11

标签: java android android-recyclerview adapter android-adapter

我有一个包含所有状态的通用CA。我到处都用它。但是此类非常繁琐,不符合Adapter

的原则
DRY

是否可以通过保留public class AdapterWithStates extends RecyclerView.Adapter { private static final int STATE_NORMAL = 0; public static final int STATE_LOADING = 1; public static final int STATE_EMPTY = 3; public static final int STATE_ERROR = 4; public static final int STATE_ERROR_CONNECTION = 5; private static final int TYPE_NORMAL = 1000; private static final int TYPE_LOADING = 1001; private static final int TYPE_LOADING_MORE = 1002; private static final int TYPE_EMPTY = 1003; private static final int TYPE_ERROR = 1004; private static final int TYPE_ERROR_CONNECTION = 1005; private static final int TYPE_ERROR_LOADING = 1006; private static final int TYPE_ERROR_CONNECTION_LOADING = 1007; private int state = STATE_LOADING; private List<Specialist> specialistsList; private Context context; private boolean loading = false; private AdapterListener mListener; public AdapterWithStates(Context context, List<Specialist> specialistsList, AdapterListener adapterListener) { this.specialistsList = specialistsList; this.context = context; this.mListener = adapterListener; } @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { switch (viewType) { case TYPE_LOADING: return new ViewHolders.LoadingViewHolder(LayoutInflater.from(context) .inflate(R.layout.loading_row, parent, false)); case TYPE_LOADING_MORE: return new ViewHolders.LoadMoreProgressViewHolder(LayoutInflater.from(context) .inflate(R.layout.load_more_row, parent, false)); case TYPE_EMPTY: return new ViewHolders.EmptyViewHolder(LayoutInflater.from(context) .inflate(R.layout.error_empty_row, parent, false)); case TYPE_ERROR: if (specialistsList.size() > 0) { return new ViewHolders.LoadMoreProgressViewHolder(LayoutInflater.from(context) .inflate(R.layout.load_more_row, parent, false)); } else { return new ViewHolders.ErrorViewHolder(LayoutInflater.from(context) .inflate(R.layout.error_row, parent, false)); } case TYPE_ERROR_CONNECTION: if (specialistsList.size() > 0) { return new ViewHolders.LoadMoreProgressViewHolder(LayoutInflater.from(context) .inflate(R.layout.load_more_row, parent, false)); } else { return new ViewHolders.ErrorConnectionViewHolder(LayoutInflater.from(context) .inflate(R.layout.error_connection_row, parent, false)); } case TYPE_ERROR_LOADING: return new ViewHolders.ErrorLoadMoreViewHolder(LayoutInflater.from(context) .inflate(R.layout.error_load_more_row, parent, false)); case TYPE_ERROR_CONNECTION_LOADING: return new ViewHolders.ErrorLoadMoreViewHolder(LayoutInflater.from(context) .inflate(R.layout.error_connection_load_more_row, parent, false)); default: return new MyViewHolder(LayoutInflater.from(context) .inflate(R.layout.specialist_short_layout_row, parent, false)); } } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { if (holder instanceof ViewHolders.LoadingViewHolder) { onBindLoadingViewHolder((ViewHolders.LoadingViewHolder) holder); } else if (holder instanceof ViewHolders.LoadMoreProgressViewHolder) { onBindLoadMoreViewHolder((ViewHolders.LoadMoreProgressViewHolder) holder, position); } else if (holder instanceof ViewHolders.ErrorLoadMoreViewHolder) { onBindErrorLoadMoreViewHolder((ViewHolders.ErrorLoadMoreViewHolder) holder, position); } else if (holder instanceof ViewHolders.EmptyViewHolder) { onBindEmptyViewHolder((ViewHolders.EmptyViewHolder) holder, position); } else if (holder instanceof ViewHolders.ErrorViewHolder) { onBindErrorViewHolder((ViewHolders.ErrorViewHolder) holder, position); } else if (holder instanceof ViewHolders.ErrorConnectionViewHolder) { onBindErrorConnectionViewHolder((ViewHolders.ErrorConnectionViewHolder) holder, position); } else if (holder instanceof MyViewHolder) { onBindDefaultViewHolder((MyViewHolder) holder, position); } } private void onBindDefaultViewHolder(MyViewHolder holder, int position) { Specialist specialist = specialistsList.get(position); holder.mName.setText(specialist.getFullName()); holder.mService.setText(specialist.getSex()); holder.mRatingBar.setRating(specialist.getRating() != null ? Float.parseFloat(specialist.getRating()) : 0); } private void onBindErrorViewHolder(ViewHolders.ErrorViewHolder holder, final int position) { holder.retryBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (mListener != null) mListener.onRetryClickListener(position); } }); } private void onBindErrorConnectionViewHolder(ViewHolders.ErrorConnectionViewHolder holder, final int position) { holder.retryBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (mListener != null) mListener.onRetryClickListener(position); } }); } private void onBindEmptyViewHolder(ViewHolders.EmptyViewHolder holder, final int position) { holder.mEmptyLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (mListener != null) mListener.onEmptyClickListener(position); } }); } private void onBindLoadMoreViewHolder(ViewHolders.LoadMoreProgressViewHolder holder, final int position) { holder.errorLayout.setVisibility(View.GONE); holder.progressBar.setVisibility(View.VISIBLE); holder.progressBar.setIndeterminate(true); if (!loading) { if (mListener != null) { mListener.onLoadMore(position); } loading = true; } } private void onBindErrorLoadMoreViewHolder(ViewHolders.ErrorLoadMoreViewHolder holder, final int position) { holder.retryBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (mListener != null) mListener.onRetryClickListener(position); } }); } private void onBindLoadingViewHolder(ViewHolders.LoadingViewHolder holder) { holder.progressBar.setIndeterminate(true); } @Override public int getItemCount() { switch (state) { case STATE_LOADING: case STATE_EMPTY: case STATE_ERROR_CONNECTION: case STATE_ERROR: if (specialistsList != null && specialistsList.size() != 0) return specialistsList.size(); else return 1; default: return specialistsList.size(); } } @Override public int getItemViewType(int position) { switch (state) { case STATE_LOADING: if (specialistsList.size() == 0) return TYPE_LOADING; else if (specialistsList.get(position) == null) return TYPE_LOADING_MORE; else return TYPE_NORMAL; case STATE_EMPTY: return TYPE_EMPTY; case STATE_ERROR: if (specialistsList.size() == 0) return TYPE_ERROR; else if (specialistsList.get(position) == null) return TYPE_ERROR_LOADING; else return TYPE_NORMAL; case STATE_ERROR_CONNECTION: if (specialistsList.size() == 0) return TYPE_ERROR_CONNECTION; else if (specialistsList.get(position) == null) return TYPE_ERROR_CONNECTION_LOADING; else return TYPE_NORMAL; default: if (specialistsList.get(position) != null) { return TYPE_NORMAL; } else { return TYPE_LOADING_MORE; } } } class MyViewHolder extends RecyclerView.ViewHolder { CardView mRoot; TextView mName; TextView mService; RatingBar mRatingBar; MyViewHolder(View view) { super(view); mRoot = view.findViewById(R.id.root_layout); mName = view.findViewById(R.id.name_tv); mService = view.findViewById(R.id.service_tv); mRatingBar = view.findViewById(R.id.ratingBar); mRoot.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (mListener != null) mListener.onItemClickListener(getAdapterPosition()); } }); } } public int getState() { return state; } public void setState(int state) { this.state = state; notifyDataSetChanged(); } public void update(List<Specialist> newList) { specialistsList = newList; notifyItemInserted(specialistsList.size()); } public void removeLastItem() { if (specialistsList != null && specialistsList.size() != 0) specialistsList.remove(specialistsList.size() - 1); notifyDataSetChanged(); } public void setLoaded() { state = STATE_NORMAL; loading = false; } } 方法和onBindDefaultViewHolder类进行实现来减少或继承?

1 个答案:

答案 0 :(得分:2)

您可以使您的SpecialistAdapter抽象:

public abstract class SpecialistAdapter extends RecyclerView.Adapter {
    //...

    public abstract RecyclerView.ViewHolder makeViewHolder();
}

然后,当您扩展SpecialistAdapter时,您仍然需要实现onBindViewHolder()以及新的makeViewHolder()方法。

onCreateViewHolder()下,您可以调用makeViewHolder()而不是创建新的MyViewHolder实例:

@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    RecyclerView.ViewHolder vh;
    if (viewType == VIEW_ITEM) {
        vh = makeViewHolder();
    } else {
        View v = LayoutInflater.from(context).inflate(R.layout.loading_row, parent, false);
        vh = new ProgressViewHolder(v);
    }
    return vh;
}