美文网首页
网易云微专业安卓-揭秘IOC注入框架,实现RecycleView

网易云微专业安卓-揭秘IOC注入框架,实现RecycleView

作者: 呵呵_9e25 | 来源:发表于2020-03-16 00:38 被阅读0次

文章纯属个人学习的代码实现

网易云微专业公开课上面利用反射实现了类似ButterKnifeBindViewOnClick,后面也没讲怎么实现RecyclerView的事件点击,这里我利用了addOnItemTouchListener实现单击事件,代码如下

 recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(this, new RecyclerItemClickListener.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                Toast.makeText(MainActivity.this, "show" + position, Toast.LENGTH_SHORT).show();
            }
        }));

这里的RecyclerItemClickListener主要实现列表单击事件。代码如下

public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {

    private OnItemClickListener mListener;

    public interface OnItemClickListener {
         void onItemClick(View view, int position);
    }

    GestureDetector mGestureDetector;

    public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
        mListener = listener;
        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }
        });
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
        View childView = view.findChildViewUnder(e.getX(), e.getY());
        if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
            mListener.onItemClick(childView, view.getChildPosition(childView));
            return true;
        }
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }

}

这是正常的使用逻辑,但是今天我们就要用到反射去实现注解的注入,首先我们需要定义一个注解如下

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OnItemClick {
    int value();
}

注解看不懂的同学建议去看一下网易云这个公开课,b站上面就有
然后主要核心就是怎么实现注入,代码如下

public class InjectManager {
    public static  void  inject(Activity activity){
        injectListOnClickEvents(activity);
    }

    private static void injectListOnClickEvents(final Activity activity) {
        Class<? extends Activity> clazz = activity.getClass();

        Method[] methods = clazz.getDeclaredMethods();
        for (final Method method:methods) {
            OnItemClick onItemClick= method.getAnnotation(OnItemClick.class);

                if(onItemClick!=null){
                   int recycleViewId= onItemClick.value();
                    View recycleView = activity.findViewById(recycleViewId);
                    if(recycleView instanceof  RecyclerView){
                        ((RecyclerView) recycleView).addOnItemTouchListener(new RecyclerItemClickListener(activity, new RecyclerItemClickListener.OnItemClickListener() {
                            @Override
                            public void onItemClick(View view, int position)
                            {
                                try {
                                    method.invoke(activity,view,position);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }));
                    }
                }

        }
    }

}

其实就是通过反射先找到当前activity的所有方法,然后通过获取方法注解找到我们注解的那个方法OnItemClick onItemClick= method.getAnnotation(OnItemClick.class);一旦这个变量返回不为空,说明这个方法上面就有咱们的注解,具体代码注解样式如下

   @OnItemClick(R.id.recycler_view)
    public void OnRecycleItemClick(View view,int position){
        Toast.makeText(MainActivity.this, "OnRecycleItemClick"+position, Toast.LENGTH_SHORT).show();
    }

这里我们通过注解的value()方法获取到RecyclerView的布局ID,那我们就可以直接通过activity.findViewById(recycleViewId);找到这个控件,然后直接就和正常的代码逻辑书写即可

((RecyclerView) recycleView).addOnItemTouchListener(new RecyclerItemClickListener(activity, new RecyclerItemClickListener.OnItemClickListener() {
                            @Override
                            public void onItemClick(View view, int position)
                            {
                                try {
                                    method.invoke(activity,view,position);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }));

上面有的同学看到了,在onItemClick方法里要调用method.invoke(activity,view,position);这里很好理解,其实就是调用其他开发人员用这个注解时,具体的点击事件处理逻辑,比如我这里是打印一个Toast吐司

 @OnItemClick(R.id.recycler_view)
    public void OnRecycleItemClick(View view,int position){
        Toast.makeText(MainActivity.this, "OnRecycleItemClick"+position, Toast.LENGTH_SHORT).show();
    }

最后别忘了在BaseActivity注入我们的插入代码如下

public  class BaseActivity extends AppCompatActivity {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        InjectManager.inject(this);
    }
}

当然你如果不希望全局用,你也可以在当前Activity层的OnCreate方法加入这行代码InjectManager.inject(this);

代码全部在我的github
上面会持续更新网易云微专业相关的实现代码。

相关文章

网友评论

      本文标题:网易云微专业安卓-揭秘IOC注入框架,实现RecycleView

      本文链接:https://www.haomeiwen.com/subject/vfniehtx.html