Изменение параметров пользовательской ViewGroup неизвестного типа, которая подклассов абстрактного класса
Фон
Я делаю библиотеку, которая включает в себя набор видов клавиатуры, которые будут использоваться для монгольского ввода в приложении (не как системная клавиатура). Пользователи могут переключаться между клавиатурами долгим нажатием кнопки клавиатуры. Вот два из них:
Каждая клавиатура является подклассом абстрактного класса Keyboard, который сам является подклассом ViewGroup
, Еще один обычай ViewGroup
(который я назвал ImeContainer
) содержит представления клавиатуры и выключает их при необходимости.
public class KeyboardQwerty extends Keyboard {...}
public abstract class Keyboard extends ViewGroup {...}
public class ImeContainer extends ViewGroup implements Keyboard.KeyboardListener {...}
Поскольку это библиотека, разработчик может включить столько раскладок клавиатуры, сколько пожелает. Они могут даже создавать свои собственные Keyboard
подклассы, о которых моя библиотека ничего не знает.
// keyboards to include
Keyboard aeiou = new KeyboardAeiou(this);
Keyboard qwerty = new KeyboardQwerty(this);
Keyboard custom = new CustomKeyboard(this); // locally defined keyboard (not in library)
// add keyboards to the IME container
ImeContainer imeContainer = findViewById(R.id.keyboard);
ImeContainer.Builder builder = new ImeContainer.Builder(aeiou);
builder.addKeyboard(qwerty);
builder.addKeyboard(custom);
imeContainer.apply(builder);
проблема
Приведенный выше код работает нормально (см. Исходный код демонстрационного приложения). Однако проблемы возникают, когда я хочу разрешить пользователю библиотеки изменять свойства, такие как цвет ключа, радиус границы, размер шрифта, цвет выделения всплывающих окон и так далее.
Поскольку клавиатуры создаются программно, я думал использовать конструктор для изменения любых параметров и возврата нового подкласса клавиатуры.
// keyboards to include
Keyboard.Builder builder = new Keyboard.Builder(getApplicationContext());
builder.setKeyBackgroundColor(Color.GREEN)
.setKeyPressedColor(Color.RED)
.setKeyBorderColor(Color.BLACK)
.setKeyBorderRadius(7)
.setKeyBorderWidth(2)
.setPopupBackgroundColor(Color.BLACK)
.setPopupTextColor(Color.WHITE)
.setPopupHighlightColor(Color.BLUE)
.setKeyPrimaryTextColor(Color.BLACK)
.setKeySecondaryTextColor(Color.GRAY)
.setKeySpacing(10);
Keyboard aeiou = builder.build(this, KeyboardAeiou.class); // in library
Keyboard qwerty = builder.build(this, KeyboardQwerty.class); // in library
Keyboard custom = builder.build(this, CustomKeyboard.class); // NOT in library, locally defined
Но мое поверхностное восприятие дженериков очевидно проявляется, когда я пытаюсь создать объект клавиатуры в компоновщике:
public Keyboard build(Context context, Class<? extends Keyboard> keyboardClass) {
return ???
}
Я иду в совершенно неверном направлении в этом? Я хотел бы сделать так, чтобы пользователь библиотеки мог добавлять несколько клавиатур, даже тех, которых нет в библиотеке.
Другие вещи, которые я пробовал
- Я попытался добавить установщики свойств на клавиатуру
ViewGroup
но столкнулся с проблемой детей (то есть клавиш клавиатуры), не получая не перерисовывать, когдаinvalidate()
называется (см. этот связанный вопрос). И действительно, я вообще не хочу перерисовывать. Я просто, что предоставить значения свойств во время создания. Но, похоже, нет хорошего способа сделать это программно (см. Этот связанный вопрос). - В идеале я хотел бы сначала создать экземпляр текущей клавиатуры. Они другие могут быть лениво созданы, если пользователь выбирает их. Но это сделало этот вопрос слишком сложным, поэтому я не учел его, кроме этого комментария.