Android RecycleView 的findChildViewUnder()方法,十分方便返回指定位置的childView

观察到现在很多列表视图和网格视图需要返回指定位置下的view,例如小米手机的相册功能,滑动到不同的日期的图片,提示框出现的日期也随之变化。在listview和gridview中,估计需要自己写方法来获取,但强大的RecycleView提供了一个非常便利的findChildViewUnder(float x ,float y)来给开发者带来方便

查看了一下此方法的源代码,非常简单:
这个ChildHelper类,它会协助获取RecyclerView中的childVIew,并提供忽略隐藏Children的功能,也就是说,调它的getChildAt只会在当前显示的Children中去查找,如果想查HiddenChildren,需要调getUnfilteredChildAt。

public View findChildViewUnder(float x, float y) {
        final int count = mChildHelper.getChildCount();
        for (int i = count - 1; i >= 0; i--) {
            final View child = mChildHelper.getChildAt(i);
            final float translationX = ViewCompat.getTranslationX(child);
            final float translationY = ViewCompat.getTranslationY(child);
            //判断该点是否在childView的范围内
            if (x >= child.getLeft() + translationX &&
                    x <= child.getRight() + translationX &&
                    y >= child.getTop() + translationY &&
                    y <= child.getBottom() + translationY) {
                return child;
            }
        }
        return null;
    }

写一个很简单的测试程序来测试一下该方法:
其中布局文件中加一个自定义的DrawView来标定位置:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView  android:id="@+id/recycleView" android:layout_width="match_parent" android:layout_height="match_parent"/>
    <com.example.yuanh.surfacetest.DrawView  android:layout_width="match_parent" android:layout_height="match_parent" />

</FrameLayout>

DrawView的onDraw代码:

public class DrawView extends View {
    public DrawView(Context context) {
        super(context);
    }
    @Override
    protected void onDraw(Canvas canvas) {
    //画一条标定的线条
        Paint paint = new Paint();
        paint.setColor(0x333333);
        paint.setAntiAlias(true);
        paint.setAlpha(255);
        paint.setStrokeWidth(10);
        canvas.drawLine(0,100,320,100,paint);
    }
}

MainActivity的代码如下

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initDate();

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycleView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        recyclerView.setAdapter(new MyRecycleViewAdapter(this, contacts));

        //利用滚动监听器来监听滚动时间,在onScrolled()方法中调用findChildViewUnder()方法
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            //由于返回的是一个view,需要调用findViewById方法找到子类的view
                View v = recyclerView.findChildViewUnder(100,100);
                TextView textView = (TextView)v.findViewById(R.id.textName);
                String name = textView.getText().toString();
                Log.v("scroll","child:"+name);
            }
        });
    }

测试结果如下:

02-05 15:50:59.815 4486-4486/com.example.yuanh.surfacetest V/scroll: child:Danny
02-05 15:50:59.832 4486-4486/com.example.yuanh.surfacetest V/scroll: child:Danny
02-05 15:50:59.850 4486-4486/com.example.yuanh.surfacetest V/scroll: child:HTC Sammi
02-05 15:50:59.865 4486-4486/com.example.yuanh.surfacetest V/scroll: child:HTC Sammi
02-05 15:51:03.646 4486-4486/com.example.yuanh.surfacetest V/scroll: child:ne
02-05 15:51:03.679 4486-4486/com.example.yuanh.surfacetest V/scroll: child:ne

测试成功,非常好用的一个方法

    原文作者:selfreeyuan
    原文地址: https://blog.csdn.net/selfreeyuan/article/details/50628391
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞