Как изменить цвет фона на изображении в виджете Android - PullRequest
1 голос
/ 11 марта 2019

У меня проблема с изменением цвета фона на изображении в виджете.Прямо сейчас я использую вот так:

try {
        Class c = Class.forName("android.widget.RemoteViews");
        Method m = c.getMethod("setDrawableParameters", int.class, boolean.class, int.class, int.class, PorterDuff.Mode.class, int.class);
        m.invoke(remoteViews, R.id.myImage, true, -1, Color.HSVToColor(color), PorterDuff.Mode.SRC_OVER, -1);
    } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
        e.printStackTrace();
    }

Все работает отлично, пока я не проверил на Android 9, здесь я получаю сообщение об ошибке:

java.lang.NoSuchMethodException:setDrawableParameters [int, boolean, int, int, класс android.graphics.PorterDuff $ Mode, int]

Есть ли у вас какие-либо идеи, как я могу заставить его работать на Android 9 также?Благодаря.

Ответы [ 2 ]

1 голос
/ 12 марта 2019

Другое решение, которое сработало для меня, - иметь источник изображения в формате XML android:src="@mipmap/myImage" и в коде remoteViews.setInt(R.id.myImageView,"setColorFilter", myColor);

1 голос
/ 11 марта 2019

setDrawableParameters(..) называется setDrawableTint(..) в Android 9.0 .

Вот исходный код нового метода setDrawableTint(..), доступного в Android 9.0, я думаю, он делает то же самоеРабота в setDrawableParameters(..) в предыдущей версии Android, но вы должны попробовать это в вашем проекте.

/** 
 * Equivalent to calling 
 * {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)}, 
 * on the {@link Drawable} of a given view. 
 * <p> 
 * The operation will be performed on the {@link Drawable} returned by the 
 * target {@link View#getBackground()} by default.  If targetBackground is false, 
 * we assume the target is an {@link ImageView} and try applying the operations 
 * to {@link ImageView#getDrawable()}. 
 * <p> 
 */ 
private class SetDrawableTint extends Action { 
    SetDrawableTint(int id, boolean targetBackground, 
            int colorFilter, @NonNull PorterDuff.Mode mode) { 
        this.viewId = id; 
        this.targetBackground = targetBackground; 
        this.colorFilter = colorFilter; 
        this.filterMode = mode; 
    } 

    SetDrawableTint(Parcel parcel) { 
        viewId = parcel.readInt(); 
        targetBackground = parcel.readInt() != 0; 
        colorFilter = parcel.readInt(); 
        filterMode = PorterDuff.intToMode(parcel.readInt()); 
    } 

    public void writeToParcel(Parcel dest, int flags) { 
        dest.writeInt(viewId); 
        dest.writeInt(targetBackground ? 1 : 0); 
        dest.writeInt(colorFilter); 
        dest.writeInt(PorterDuff.modeToInt(filterMode)); 
    } 

    @Override 
    public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { 
        final View target = root.findViewById(viewId); 
        if (target == null) return; 

        // Pick the correct drawable to modify for this view 
        Drawable targetDrawable = null; 
        if (targetBackground) { 
            targetDrawable = target.getBackground(); 
        } else if (target instanceof ImageView) { 
            ImageView imageView = (ImageView) target; 
            targetDrawable = imageView.getDrawable(); 
        } 

        if (targetDrawable != null) { 
            targetDrawable.mutate().setColorFilter(colorFilter, filterMode); 
        } 
    } 

    @Override 
    public int getActionTag() { 
        return SET_DRAWABLE_TINT_TAG; 
    } 

    boolean targetBackground; 
    int colorFilter; 
    PorterDuff.Mode filterMode; 
} 

Вы можете проверить, как работает новый метод и какие параметры нужны, а затем иметь в своем проекте что-то вроде:

if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.P){
    // Your actual implementation with "setDrawableParameters"
    changeImageBackgroundColorBeforeAndroidPIE()
} else{
    // Your new implementation with "setDrawableTint"
    changeImageBackgroundColorAndroidPIEAndLater()
}

Другое решение может быть:

Как я вижу, метод setDrawableParameters(..) скрыт, поэтому он не предназначен для использования таким образом,Я думаю, это не будет оптимальным решением для решения вашей проблемы.Это выглядит как хакерское решение, но на самом деле оно может ухудшиться, если его изменить или если оно не будет поддерживаться так, как вы думали, оно работает.

Давайте начнем с самого начала, вы хотите изменитьЦвет фона изображения в виджете, точнее в RemoteView, возможно, вы могли бы преобразовать drawable в bitmap и затем вызвать RemoteViews.setImageBitmap ()

Вот как преобразовать рисованный объект в растровое изображение

ОБНОВЛЕНИЕ: еще одно решение, которое только что нашел автор, было

Другое решение, котороеработал для меня, чтобы иметь источник изображения в макете xml android: src = "@ mipmap / myImage" и в коде remoteViews.setInt (R.id.myImageView, "setColorFilter", myColor);

Вот ответ автора: https://stackoverflow.com/a/55123126/3564632

...