Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

<style name="MyAppTheme" parent="***">
   <item name="android:colorEdgeEffect">@color/my_color</item>
</style>

Ответ 2

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

ОБНОВЛЕНИЕ: TL; DR: Скачать весь класс отсюда: https://github.com/consp1racy/android-commons/blob/71b5c65689786b1d52d701d81d8c7445495807c3/commons/src/main/java/net/xpece/android/widget/XpEdgeEffect.java

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

-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();
    }
  }
}

Ответ 3

Если вы используете последнюю реализацию 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, как указано Ахмедом.

Ответ 4

В 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);