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

来源:互联网 发布:名不虚传软件官网 编辑:程序博客网 时间:2024/06/01 08:12

观察到现在很多列表视图和网格视图需要返回指定位置下的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;    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

写一个很简单的测试程序来测试一下该方法: 
其中布局文件中加一个自定义的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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

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);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

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);            }        });    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

测试结果如下:

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

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