如何以编程方式查看 android listView 快速滚动缩略图?
How to get view of android listView fast scroll thumb programmatically?
我正在使用此 github 库 https://github.com/amlcurran/ShowcaseView 在用户入门期间(或安装后首次打开应用程序)显示我应用程序的视图元素上的叠加层。
此库需要将视图作为输入并在您的 activity 上显示叠加层,专注于该视图,以便您可以告诉用户更多关于该视图的信息。
我有一个启用了快速滚动的列表视图。我想在快速滚动拇指上显示覆盖。因此,我想查看我的 listView 的快速滚动拇指,但由于在 absListView 实现中缺少任何 public 方法,我无法执行此操作。
请帮忙。
ListView
的 FastScroller
实现因 Android 版本而异。在 KitKat (API 19) 之前,拇指是直接绘制在 ListView
上的 Drawable
。从 KitKat 开始,拇指是添加到 ListView
的 ViewGroupOverlay
的 ImageView
。无论哪种情况,我们都可以很容易地通过反射得到我们需要的东西。
由于最终目标是将其与 ShowcaseView
一起使用,因此只关心拇指的尺寸和坐标是有意义的,而不管其具体类型如何。这样我们就可以使用ShowcaseView
的PointTarget
了,不管Android版本是什么
以下反射方法获取 ListView
的 FastScroller
实例,使用适当的类型确定拇指的大小和位置,并 returns 一个 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
一起使用,我们只需检查 returned Point
是否为空,然后将 Builder
传递给 PointTarget
来自 return.
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();
}
我正在使用此 github 库 https://github.com/amlcurran/ShowcaseView 在用户入门期间(或安装后首次打开应用程序)显示我应用程序的视图元素上的叠加层。
此库需要将视图作为输入并在您的 activity 上显示叠加层,专注于该视图,以便您可以告诉用户更多关于该视图的信息。
我有一个启用了快速滚动的列表视图。我想在快速滚动拇指上显示覆盖。因此,我想查看我的 listView 的快速滚动拇指,但由于在 absListView 实现中缺少任何 public 方法,我无法执行此操作。
请帮忙。
ListView
的 FastScroller
实现因 Android 版本而异。在 KitKat (API 19) 之前,拇指是直接绘制在 ListView
上的 Drawable
。从 KitKat 开始,拇指是添加到 ListView
的 ViewGroupOverlay
的 ImageView
。无论哪种情况,我们都可以很容易地通过反射得到我们需要的东西。
由于最终目标是将其与 ShowcaseView
一起使用,因此只关心拇指的尺寸和坐标是有意义的,而不管其具体类型如何。这样我们就可以使用ShowcaseView
的PointTarget
了,不管Android版本是什么
以下反射方法获取 ListView
的 FastScroller
实例,使用适当的类型确定拇指的大小和位置,并 returns 一个 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
一起使用,我们只需检查 returned Point
是否为空,然后将 Builder
传递给 PointTarget
来自 return.
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();
}