1

我正在使用这个 github 库https://github.com/amlcurran/ShowcaseView在用户入职期间(或安装后第一次打开应用程序)显示我的应用程序的视图元素的叠加层。

这个库需要视图作为输入,并显示覆盖在你的活动上,重点是那个视图,这样你就可以告诉用户更多关于那个视图的信息。

我有一个启用了快速滚动的 listView。我想在快速滚动拇指上显示叠加。因此,我想查看我的 listView 的快速滚动拇指,但由于 absListView 实现中没有任何公共方法,我无法做到这一点。

请帮忙。

4

1 回答 1

2

FastScroller实现ListView因 Android 版本而异。在 KitKat (API 19) 之前,拇指是Drawable直接绘制在ListView. 从 KitKat 开始,拇指是ImageView添加到ListView's 的ViewGroupOverlay. 无论哪种情况,通过反射很容易得到我们需要的东西。

由于最终目标是将其与 一起使用ShowcaseView,因此只关注拇指的尺寸和坐标是有意义的,无论其具体类型如何。这样,无论安卓版本,我们都可以使用ShowcaseView's 。PointTarget

以下反射方法获取 aListViewFastScroller实例,使用适当的类型确定拇指的大小和位置Point,如果可能,返回一个带有拇指中心点坐标的对象。

private Point getFastScrollThumbPoint(final ListView listView) {
    try {
        final Class<?> fastScrollerClass = Class.forName("android.widget.FastScroller");

        final int[] listViewLocation = new int[2];
        listView.getLocationInWindow(listViewLocation);
        int x = listViewLocation[0];
        int y = listViewLocation[1];

        final Field fastScrollerField;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            fastScrollerField = AbsListView.class.getDeclaredField("mFastScroll");
        }
        else {
            fastScrollerField = AbsListView.class.getDeclaredField("mFastScroller");
        }
        fastScrollerField.setAccessible(true);

        final Object fastScroller = fastScrollerField.get(listView);
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
            final Field thumbImageViewField = fastScrollerClass.getDeclaredField("mThumbImage");
            thumbImageViewField.setAccessible(true);
            final ImageView thumbImageView = (ImageView) thumbImageViewField.get(fastScroller);

            final int[] thumbViewLocation = new int[2];
            thumbImageView.getLocationInWindow(thumbViewLocation);

            x += thumbViewLocation[0] + thumbImageView.getWidth() / 2;
            y += thumbViewLocation[1] + thumbImageView.getHeight() / 2;
        }
        else {
            final Field thumbDrawableField = fastScrollerClass.getDeclaredField("mThumbDrawable");
            thumbDrawableField.setAccessible(true);
            final Drawable thumbDrawable = (Drawable) thumbDrawableField.get(fastScroller);
            final Rect bounds = thumbDrawable.getBounds();

            final Field thumbYField = fastScrollerClass.getDeclaredField("mThumbY");
            thumbYField.setAccessible(true);
            final int thumbY = (Integer) thumbYField.get(fastScroller);

            x += bounds.left + bounds.width() / 2;
            y += thumbY + bounds.height() / 2;
        }

        return new Point(x, y);
    }
    catch (Exception e) {
        e.printStackTrace();
    }

    return null;
}

要将它与 一起使用ShowcaseView,我们只需检查返回Point值是否不为空,并传递从返回值创建的Buildera PointTarget

Point thumbPoint = getFastScrollThumbPoint(listView);

if (thumbPoint != null) {
    new ShowcaseView.Builder(this)
        .setTarget(new PointTarget(thumbPoint))
        .setContentTitle("ShowcaseView")
        .setContentText("This is highlighting the fast scroll thumb")
        .hideOnTouchOutside()
        .build();
}
于 2016-08-07T08:15:05.063 回答