简体   繁体   English

如何摆脱重复的RecyclerView Adapter?

[英]How to get rid of duplicates RecyclerView Adapter?

I have a universal Adapter with all states. 我有一个所有状态的通用Adapter I use it everywhere. 我到处都用它。 But this class is very cumbersome, and does not comply with the principles of DRY 但是此类非常繁琐,不符合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;
    }
}

Is it possible to reduce or inherit by leaving the onBindDefaultViewHolder method and the MyViewHolder class for implementation? 是否可以通过保留onBindDefaultViewHolder方法和MyViewHolder类进行实现来减少或继承?

You could make your SpecialistAdapter abstract: 您可以使SpecialistAdapter抽象:

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

    public abstract RecyclerView.ViewHolder makeViewHolder();
}

Then, when you extend SpecialistAdapter, you'll still need to implement onBindViewHolder() , as well as the new makeViewHolder() method. 然后,在扩展SpecialistAdapter时,仍然需要实现onBindViewHolder()以及新的makeViewHolder()方法。

Under onCreateViewHolder() , you can call makeViewHolder() instead of creating a new MyViewHolder instance: 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何摆脱打印线内的重复项 - how to get rid of duplicates inside a printline 如何从位置适配器 RecyclerView 获取价值 - How to get value from position adapter RecyclerView 无法获取 Cardview、E/RecyclerView:未连接适配器; 跳过布局错误,如何将适配器添加到 recyclerView? - Unable to get the Cardview, E/RecyclerView: No adapter attached; skipping layout error , how to add adapter to recyclerView? 如何消除此 Java 代码中的重复项? - How can I get rid of duplicates in this Java code? 如何使用 AsyncTask、RecyclerView 和 RecyclerView.Adapter 将手机中的图像获取到 RecyclerView? - How can I use AsyncTask, RecyclerView, and a RecyclerView.Adapter to get images from my phone into my RecyclerView? 如何从RecyclerView.Adapter类获取ArrayList - How get ArrayList from RecyclerView.Adapter class 如何从 android kotlin 中的 recyclerview 适配器获取 arraylist - How to get arraylist from recyclerview adapter in android kotlin 如何从 android studio 中的 recyclerview 适配器获取视频长度 - How to get a video length from a recyclerview adapter in android studio 如何从RecyclerView.Adapter访问LayoutManager以获取scrollToPosition? - How to access LayoutManager from RecyclerView.Adapter to get scrollToPosition? 如何从RecyclerView Adapter传递给MainActivity的变量? - How can I get a variable from RecyclerView Adapter passed to MainActivity?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM