Реализация FastScroller
для ListView
зависит от версии для Android. До KitKat (API 19) большой палец представляет собой Drawable
, который нарисован непосредственно на ListView
. Начиная с KitKat, большой палец - это ImageView
, который добавлен в ListView
's ViewGroupOverlay
. В любом случае, достаточно легко получить то, что нам нужно, через отражение.
Поскольку конечная цель состоит в том, чтобы использовать это с помощью ShowcaseView
, имеет смысл просто касаться размеров и координат большого пальца независимо от его конкретного типа. Таким образом, мы можем использовать ShowcaseView
PointTarget
, вне зависимости от версии Android.
В следующем отражательном методе захватывает FastScroller
экземпляра ListView
«с, определяет большой палец размера и местоположение, используя соответствующий тип, и возвращает объект 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
не равно нулю, и передать Builder
в 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();
}
Ну, вы можете сделать это с отражением, но все зависит от версии Android. Какие версии вы поддерживаете? –
Спасибо за комментарий, @MikeM. Я хочу поддерживать все версии выше API 14. Можете ли вы посоветовать немного больше, пожалуйста? –
Начиная с API 18, большой палец является «ImageView», поэтому это достаточно просто, но имя поля для него отличается в зависимости от конкретной версии. Не ахти какое дело. Тем не менее, перед API 18 большой палец является «Drawable», который нарисован непосредственно в «ListView», поэтому нет специального «представления», который вы можете передать в библиотеку. Я не использовал эту библиотеку, поэтому я не знаю, есть ли другие доступные опции. –