[Android開發,Java] RecycleViewAdapter和ViewHolder解耦

本文详细介绍了如何在Android中创建一个可复用的ViewHolder基类OptionBaseViewHolder,以及如何使用泛型自定义WeekItemViewHolder。还展示了如何使用OptionListAdapter管理数据并处理item点击事件,最后提到了最佳实践关于ViewHolder中的Listener管理。
摘要由CSDN通过智能技术生成

1.寫一個基類viewHolder 

    public static   class OptionBaseViewHolder<T,B extends ViewBinding> extends RecyclerView.ViewHolder implements View.OnClickListener {
        public B binding;
        OptionListAdapter adapter;
        T data;
        Context context;

        //構造參數傳入 binding和adapter,傳adapter可以方便獲取adpter內部方法和上下文
        public OptionBaseViewHolder(@NonNull B binding ,OptionListAdapter adapter) {
            super(binding.getRoot());
            this.binding = binding;
            this.adapter  =adapter;
            this.context = adapter.context;
        }

        protected void dataBindView(T data){this.data = data;}

        @Override
        public  void onClick(View v){};

    }

2.寫一個繼承基類的自定義ViewHolder    泛型傳入<資料類型,Item的ViewBinding>

    public static class WeekItemViewHolder extends OptionBaseViewHolder<String, ItemTimerWeekBinding>{
    public static ItemCallback<String> listener;//static listener記得在不需要用到時使listener=null
        public WeekItemViewHolder(@NonNull ItemTimerWeekBinding binding, OptionListAdapter adapter) {
            super(binding, adapter);
            binding.item.setOnClickListener(this);
        }

        @Override
        protected void dataBindView(String data) {
            super.dataBindView(data);
            binding.itemName.setText(data);
        }

        @Override
        public void onClick(View v) {
            super.onClick(v);
            if(v == binding.item){
                if(listener!=null)listener.onClickItem(data);

            }
        }
    }

    public static abstract class ItemCallback<T>{
        public void onClickItem(T data){};
    }

3.寫一個共通的Adapter

public  class OptionListAdapter extends RecyclerView.Adapter<OptionListAdapter.OptionBaseViewHolder>   {
    protected ArrayList<Object> dataList; //資料源
    protected Context context;
    private  Class<? extends ViewBinding> viewBindingClazz ;
    private   Class<? extends OptionBaseViewHolder> viewHolderClazz;


//構造參數傳入上下文,dataList,自定義ViewHolder.class
    public OptionListAdapter(Context context , ArrayList<Object> dataList, Class<? extends OptionBaseViewHolder> viewHolderClazz){
        this.context = context;
        this.dataList = dataList;
        this.viewHolderClazz = viewHolderClazz;
        this.viewBindingClazz = getViewBindingClass(viewHolderClazz);
    }

    //透過viewHolder泛型參數的取得ViewBinding的Class
    private Class getViewBindingClass(Class<? extends OptionBaseViewHolder> viewHolderClazz){
        ParameterizedType parameterizedType = (ParameterizedType) viewHolderClazz.getGenericSuperclass();
        Type viewBindingActualTypeArgument = parameterizedType.getActualTypeArguments()[1];
        return (Class<? extends ViewBinding>)viewBindingActualTypeArgument;
    }

    //透過反射動態生成viewHolder
    @NonNull
    @Override
    public  OptionListAdapter.OptionBaseViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        try {
            Method inflateMethod = viewBindingClazz.getMethod("inflate", LayoutInflater.class, ViewGroup.class, boolean.class);
            ViewBinding binding = (ViewBinding) inflateMethod.invoke(null, LayoutInflater.from(context), parent, false);
            Constructor<?> constructor = Constructor<?> constructor = viewHolderClazz.getConstructor(viewBindingClazz,this.getClass());
            OptionListAdapter.OptionBaseViewHolder viewHolder = (OptionListAdapter.OptionBaseViewHolder) constructor.newInstance(binding,this);
            return  viewHolder;

        } catch (Exception e) {

        }

        return null;
    }

//傳入資料源
    @Override
    public  void onBindViewHolder(@NonNull OptionListAdapter.OptionBaseViewHolder holder, int position) {
        holder.dataBindView(dataList.get(position));
    }


    @Override
    public int getItemCount() {
        return dataList.size();
    }

}

4.Activity調用運行:

  public void initRecycleView(){
            ArrayList<String> options= new ArrayList<>();
            options.add("選項1");
            options.add("選項2");
            options.add("選項3");    
            OptionListAdapter adapter = new OptionListAdapter(this,options,
                  WeekItemViewHolder.class);
            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
            binding.testRecyclerview.setLayoutManager(linearLayoutManager);
            binding.testRecyclerview.setAdapter(adapter)
            WeekItemViewHolder.listener = new ItemCallback<String>() {
                @Override
                public void onClickItem(String data) {
                    super.onClickItem(data);
                    Log.d("test","點擊了---"+data)
                }
            };
}

5.Activity銷毀注意:

    @Override
    public void onDestroy() {
        super.onDestroy();
        WeekItemViewHolder.listener = null;
    }

6.其實後來實際用一用發現listener還是不要用static比較好 ,建議大家把listener從Adapter的構造參數傳入,用反射傳進去viewHolder,不然一直在onDestroy設null手好痠好麻煩,而且在忘記設的時候,可能有無法預期的內存洩漏導致閃退。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值