Как изменить цвет края прокрутки и свечения над прокруткой

Как изменить цвет края прокрутки и свечения при прокрутке или как изменить белый цвет (цвет по умолчанию) леденца на палочке Android версии 5.0?


person Ad Dahoun    schedule 07.12.2014    source источник
comment
возможный дубликат цвета края эффекта прокрутки леденца на палочке Android   -  person alanv    schedule 07.12.2014


Ответы (4)


Цвет свечения при прокрутке наследует значение основного цвета, установленное android:colorPrimary во всем приложении. Но если вам нужно указать другое значение, просто используйте android:colorEdgeEffect (доступно только для API 21 и выше).

<style name="MyAppTheme" parent="...">
   <item name="android:colorEdgeEffect">@color/my_color</item>
</style>
person Ahmed Hegazy    schedule 07.12.2014
comment
Обратите внимание, что android:colorPrimary также устанавливает цвет панели действий или панели инструментов. В то время как android:colorEdgeEffect более конкретен и применяется только к ListViews, RecyclerViews и т. Д. - person Mr-IDE; 27.06.2017

На LOLLIPOP краевое свечение наследуется от colorPrimary. После создания вида цвет свечения края можно изменить только путем отражения. Это может быть полезно при динамической загрузке цветов с помощью Palette.

EDIT: TL; DR: Загрузите весь класс отсюда: https://github.com/consp1racy/android-commons/blob/71b5c65689786b1d52d701d81d8c7445495807c3/commons/src/main/java/net/xpece/android/widget/XpEdgeEffect.java

НАСТРОЙКА ПРОГРАММЫ: если вы собираетесь использовать это для виджетов из библиотеки поддержки, вам необходимо сохранить имена полей. Самый быстрый способ сделать это следующий (хотя и расточительный):

-keepclassmembers class android.support.v4.widget.EdgeEffectCompat {
    <fields>;    
}

Создайте служебный класс со следующим кодом:

private static final Class<?> CLASS_SCROLL_VIEW = ScrollView.class;
private static final Field SCROLL_VIEW_FIELD_EDGE_GLOW_TOP;
private static final Field SCROLL_VIEW_FIELD_EDGE_GLOW_BOTTOM;

private static final Class<?> CLASS_LIST_VIEW = AbsListView.class;
private static final Field LIST_VIEW_FIELD_EDGE_GLOW_TOP;
private static final Field LIST_VIEW_FIELD_EDGE_GLOW_BOTTOM;

static {
  Field edgeGlowTop = null, edgeGlowBottom = null;

  for (Field f : CLASS_SCROLL_VIEW.getDeclaredFields()) {
    switch (f.getName()) {
      case "mEdgeGlowTop":
        f.setAccessible(true);
        edgeGlowTop = f;
        break;
      case "mEdgeGlowBottom":
        f.setAccessible(true);
        edgeGlowBottom = f;
        break;
    }
  }

  SCROLL_VIEW_FIELD_EDGE_GLOW_TOP = edgeGlowTop;
  SCROLL_VIEW_FIELD_EDGE_GLOW_BOTTOM = edgeGlowBottom;

  for (Field f : CLASS_LIST_VIEW.getDeclaredFields()) {
    switch (f.getName()) {
      case "mEdgeGlowTop":
        f.setAccessible(true);
        edgeGlowTop = f;
        break;
      case "mEdgeGlowBottom":
        f.setAccessible(true);
        edgeGlowBottom = f;
        break;
    }
  }

  LIST_VIEW_FIELD_EDGE_GLOW_TOP = edgeGlowTop;
  LIST_VIEW_FIELD_EDGE_GLOW_BOTTOM = edgeGlowBottom;
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static void setEdgeGlowColor(AbsListView listView, int color) {
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    try {
      EdgeEffect ee;
      ee = (EdgeEffect) LIST_VIEW_FIELD_EDGE_GLOW_TOP.get(listView);
      ee.setColor(color);
      ee = (EdgeEffect) LIST_VIEW_FIELD_EDGE_GLOW_BOTTOM.get(listView);
      ee.setColor(color);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static void setEdgeGlowColor(ScrollView scrollView, int color) {
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    try {
      EdgeEffect ee;
      ee = (EdgeEffect) SCROLL_VIEW_FIELD_EDGE_GLOW_TOP.get(scrollView);
      ee.setColor(color);
      ee = (EdgeEffect) SCROLL_VIEW_FIELD_EDGE_GLOW_BOTTOM.get(scrollView);
      ee.setColor(color);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}
person Eugen Pechanec    schedule 07.12.2014
comment
Отлично! Я искал способ программно изменить цвет свечения, и каждый ответ был связан с установкой стиля в xml. Ваш работал у меня без проблем, и теперь я могу динамически изменять цвет в зависимости от контекста, как я это делаю для цвета строки состояния и панели инструментов. Спасибо! - person MrBrightside; 12.12.2014
comment
Спасибо. это прекрасно работает. а как насчет RecyclerView? - person ; 29.11.2015
comment
@sajad Вот класс, который я использую для обработки большинства прокручиваемых контейнеров pastebin.com/TAujMUu9 Единственный отсутствующий класс - HorizontalScrollView Думаю. - person Eugen Pechanec; 01.12.2015
comment
@Analizer Правильно, код pastebin вылетает на Android 4. К счастью, вчера я узнал, так что вот обновление: pastebin.com/JSefcHiB < / а> - person Eugen Pechanec; 11.02.2016
comment
ViewPager отсутствует, мне нужно то же самое, но для ViewPager! - person Felipe Ribeiro R. Magalhaes; 06.06.2016
comment
@ FelipeRibeiroR.Magalhaes В вашем распоряжении исходный код Android и мой исходный код, я уверен, что вы можете адаптировать его для ViewPager. - person Eugen Pechanec; 06.06.2016
comment
@ FelipeRibeiroR.Magalhaes На этой странице вы можете выбрать другую версию из счетчика вверху. Проверьте ссылку в ответе Я обновил его для ViewPager. Не тестировал, но должен работать. - person Eugen Pechanec; 07.06.2016
comment
@EugenPechanec Я тестировал, но, к сожалению, не сработало. Вы реализовали это для поддержки v4 ViewPager? Я очень ценю вашу помощь! - person Felipe Ribeiro R. Magalhaes; 07.06.2016
comment
@ FelipeRibeiroR.Magalhaes Если он вам нужен для ViewPager v13, все, что вам нужно сделать, это изменить v4 на v13 в строке import в верхней части файла. - person Eugen Pechanec; 07.06.2016
comment
@EugenPechanec Я, должно быть, неправильно выразился ... Я уже использую v4, и мне было интересно, сделали ли вы это для этой версии, что теперь ясно, что вы сделали. Но это не работает... - person Felipe Ribeiro R. Magalhaes; 07.06.2016
comment
@ FelipeRibeiroR.Magalhaes Исправлено. (И, конечно, нет ViewPager v13.) - person Eugen Pechanec; 07.06.2016
comment
@EugenPechanec большое спасибо, теперь он работает! - person Felipe Ribeiro R. Magalhaes; 07.06.2016
comment
@EugenPechanec, насчет веб-просмотров, я только что понял, что их тоже можно прокручивать, а также иметь эффект края! - person Felipe Ribeiro R. Magalhaes; 22.06.2016
comment
@ FelipeRibeiroR.Magalhaes Верно. Поскольку реализация Android 4.4 WebView предоставляется независимым APK, я не хочу углубляться в это. На старые устройства мне все равно. Не стесняйтесь исследовать, если это вас интересует. - person Eugen Pechanec; 22.06.2016
comment
@EugenPechanec имеет смысл, я займусь этим! Спасибо. - person Felipe Ribeiro R. Magalhaes; 22.06.2016
comment
Эта ссылка не работает, кстати. (github.com/consp1racy/android-commons/blob/master/android/src/) - person Martin Marconcini; 05.07.2017

Если вы используете последнюю версию RecyclerView, программно изменить цвет переполнения довольно просто. Используйте следующий код (реализация Kotlin):

recyclerView.edgeEffectFactory = object : RecyclerView.EdgeEffectFactory() {
    override fun createEdgeEffect(view: RecyclerView, direction: Int): EdgeEffect {
        return EdgeEffect(view.context).apply { setColor(color) }
    }
}

Обратите внимание, что это работает только для уровня API 21 (Lollipop) и выше. Если вы знаете значение во время компиляции, используйте colorEdgeEffect, как указано Ахмедом.

person Phoca    schedule 14.03.2018
comment
Для java ... getRecyclerView().setEdgeEffectFactory(new RecyclerView.EdgeEffectFactory() { @NonNull @Override protected EdgeEffect createEdgeEffect(@NonNull RecyclerView view, int direction) { EdgeEffect edge = new EdgeEffect(view.getContext()); edge.setColor(ContextCompat.getColor(view.getContext(), R.color.blue)); return edge; } }); - person Javatar; 07.06.2019

В pre-lollipop эффект свечения на самом деле является Drawable, встроенным в ресурсы ОС, вы можете применить к нему ColorFilter:

public static void changeOverScrollGlowColor(Resources res, int colorID ) {
    try {
        final int glowDrawableId = res.getIdentifier("overscroll_glow", "drawable", "android");
        final Drawable overscrollGlow = res.getDrawable(glowDrawableId);
        overscrollGlow.setColorFilter(res.getColor(colorID), android.graphics.PorterDuff.Mode.SRC_ATOP);

        final int edgeDrawableId = res.getIdentifier("overscroll_edge", "drawable", "android");
        final Drawable overscrollEdge = res.getDrawable(edgeDrawableId);
        overscrollEdge.setColorFilter(res.getColor(colorID), android.graphics.PorterDuff.Mode.SRC_ATOP);
    } catch (Exception ignored) {
    }
}

Достаточно один раз вызвать его в onCreate.

changeOverScrollGlowColor(getResources(), R.color.colorPrimary);
person John    schedule 21.08.2018