Увеличение базового цветового класса на Android - PullRequest
0 голосов
/ 19 февраля 2020

У меня много кода, написанного для более поздних API Android (26+), которые поддерживают такие вещи, как Color.valueOf () и нумерация c цветовых каналов. Я хочу перенести часть этого кода в бэкпорт для работы со старыми устройствами API без необходимости менять каждый экземпляр моего класса Color на что-то другое.

Есть ли в Java способ изменить класс без необходимости создавать производный класс с новой функциональностью?

По сути, я хочу дополнить класс и код цвета меньшего API отсутствующими функциями, которые я использую.

По моему мнению, я с концептуальной точки зрения это выглядит так:

augment class Color() {

    // Add in missing functions
    public static int valueOf(float r, float g, float b) {
    }

    public static int valueOf(int r, int g, int b) {
    }

    // Other functions here
}

Это скомпилирует класс Color по умолчанию, добавляющий эти дополнительные функции, чтобы они были доступны с этого момента в этом приложении на устройстве с меньшим API.

Ответы [ 2 ]

1 голос
/ 19 февраля 2020

Есть ли способ в Java изменить класс без необходимости создания производного класса с новой функциональностью?

Для этого нет ничего встроенного в Java, извините.

Обратите внимание, что рассматриваемые методы (valueOf()) являются static методами. Ваш текущий код называет их так:

Color.valueOf(foo, bar, goo);

Для написания сценария, который заменяет эти вызовы, не понадобится много времени:

RickColorCompat.valueOf(foo, bar, goo);

Или попробуйте Редактировать> Найти> Заменить в Путь в Android Студия. Лично у меня есть сценарий командной строки gsub Ruby, который я написал некоторое время назад для такого рода работы поиска и замены.

В зависимости от того, что еще вы используете из Color, однако такой подход может не сработать.

0 голосов
/ 23 февраля 2020

Я думал, что опубликую свое решение на тот случай, если кому-то понадобится помощь.

Моя цель состояла в том, чтобы вернуть существующее приложение API 26 обратно в API 9, чтобы оно работало в серии Android 2.x , Несколько функций-членов Color отсутствовали, связанные с обработкой целочисленных цветов и цветовых каналов с плавающей точкой.

Чтобы обновить старый класс API Color, я создал класс Colorx и заменил все ссылки Color на Colorx. Вот исходный код После внесения этого изменения остальная часть моего дизайна (с использованием целых чисел и цветовых каналов с плавающей запятой) смогла продолжить работу без изменений, при этом требовался только рефакторинг от Color к Colorx.

Надеюсь, это кому-нибудь поможет. И если у вас есть предложения по другим изменениям / улучшениям / исправлениям ошибок, пожалуйста, дайте мне знать. Спасибо.

package ...;

import android.graphics.Color;

public class Colorx extends Color
{
    // Class variables
    public int m_red;
    public int m_grn;
    public int m_blu;
    public int m_alp;

    // Constant colors (taken from Color)
    public static final int BLACK       = 0xFF000000;
    public static final int DKGRAY      = 0xFF444444;
    public static final int GRAY        = 0xFF888888;
    public static final int LTGRAY      = 0xFFCCCCCC;
    public static final int WHITE       = 0xFFFFFFFF;
    public static final int RED         = 0xFFFF0000;
    public static final int GREEN       = 0xFF00FF00;
    public static final int BLUE        = 0xFF0000FF;
    public static final int YELLOW      = 0xFFFFFF00;
    public static final int CYAN        = 0xFF00FFFF;
    public static final int MAGENTA     = 0xFFFF00FF;
    public static final int TRANSPARENT = 0;

    // Constructors
    public Colorx()
    {
        super();

        // Initially set the alpha to 100%
        m_alp = 255;
    }

    public Colorx(float r, float g, float b)
    {
        String rrggbb;

        // Convert to integers
        m_red = (int)range(255.0f * r, 0.0f, 255.0f);
        m_grn = (int)range(255.0f * g, 0.0f, 255.0f);
        m_blu = (int)range(255.0f * b, 0.0f, 255.0f);

        // Parse the indicated color
        rrggbb = "#ff" + hexString2(m_red) + hexString2(m_grn) + hexString2(m_blu);
        parseColor(rrggbb);
    }

    public Colorx(float r, float g, float b, float a)
    {
        String aarrggbb;

        // Convert to integers
        m_red = (int)range(255.0f * r, 0.0f, 255.0f);
        m_grn = (int)range(255.0f * g, 0.0f, 255.0f);
        m_blu = (int)range(255.0f * b, 0.0f, 255.0f);
        m_alp = (int)range(255.0f * a, 0.0f, 255.0f);

        // Parse the indicated color
        aarrggbb = "#" + hexString2(m_alp) + hexString2(m_red) + hexString2(m_grn) + hexString2(m_blu);
        parseColor(aarrggbb);
    }

    public Colorx(int color)
    {
        String aarrggbb;

        // Convert to integers
        m_red = (int)range((color >> 16) & 0xff, 0, 255);
        m_grn = (int)range((color >>  8) & 0xff, 0, 255);
        m_blu = (int)range((color >>  0) & 0xff, 0, 255);
        m_alp = (int)range((color >> 24) & 0xff, 0, 255);

        // Parse the indicated color
        aarrggbb = "#" + hexString2(m_alp) + hexString2(m_red) + hexString2(m_grn) + hexString2(m_blu);
        parseColor(aarrggbb);
    }

    public float red()
    {
        return ((float)m_red / 255.0f);
    }

    public float green()
    {
        return ((float)m_grn / 255.0f);
    }

    public float blue()
    {
        return ((float)m_blu / 255.0f);
    }

    public float alp()
    {
        return ((float)m_alp / 255.0f);
    }

    public int toArgb()
    {
        int color =   ((m_alp & 0xff) << 24)
                    | ((m_red & 0xff) << 16)
                    | ((m_grn & 0xff) <<  8)
                    |  (m_blu & 0xff);

        return color;
    }

    public static Colorx valueOf(float r, float g, float b)
    {
        return new Colorx(r, g, b, 1.0f);
    }

    public static Colorx valueOf(float r, float g, float b, float a)
    {
        return new Colorx(r, g, b, a);
    }

    public static Colorx valueOf(int color)
    {
        return new Colorx(color);
    }

    public float range(float v, float vMin, float vMax)
    {
        return Math.max(vMin, Math.min(vMax, v));
    }

    public static String hexString2(int v)
    {
        String text;

        // Convert
        text = Integer.toHexString(v);

        // Evaluate
             if (text.length() == 2)  return text;        // It's the proper length
        else if (text.length() == 1)  return "0" + text;  // It's only one digits
        else                          return "00";        // It's an invalid length, force it to 00
    }
}
...