Как внести небольшое изменение в исходный код Android и включить его в свой собственный проект

Я хочу внести небольшое изменение в стандартный класс Android TimePicker. В частности, я пытаюсь изменить его так, чтобы он работал с шагом 15 минут, а не с шагом 1 минута.

Этот пост помог мне ограничить диапазон минутных значений до {0, 15, 30, 45}, как требуется в моем приложении. Но, как я указал в последующем комментарии, счетчик минут по-прежнему показывает предыдущую минуту как текущее значение - 1, а следующую минуту как текущее значение + 1, что создает неаккуратный пользовательский интерфейс.

Я изучил соответствующий Исходный код Android, и кажется, что изменения I нужно будет сделать довольно просто. Но когда я попытался скопировать исходный код в свой проект, я получил огромное количество ошибок, связанных с объявлением package, где найти Widget, как разрешить переменные R.id и т. д.

Итак, мой вопрос:

Как лучше всего внести небольшое изменение в данный класс из исходного кода Android и включить его в свой собственный проект?

В моем случае мне просто нужно внести несколько небольших изменений в TimePicker и NumberPicker, но я не уверен, как правильно настроить это в моем проекте.

Спасибо за любые предложения.


person gcl1    schedule 18.04.2013    source источник


Ответы (2)


Но когда я попытался скопировать исходный код в свой проект, я получил около миллиона ошибок, связанных с объявлением пакета.

Каталог вашего исходного файла должен соответствовать имени пакета. А поскольку вы не можете перезаписать android.widget.TimePicker, вам нужно либо переместить этот класс в новый пакет, либо дать ему новое имя.

где найти виджет

Это означает, что вы скопировали TimePicker в один из ваших пакетов. Это нормально, но тогда вам нужно добавить соответствующие операторы import для классов, на которые TimePicker ссылается из исходного пакета. Либо, вам нужно оставить свой (переименованный) TimePicker в android.widget, добавив этот пакет в свой проект. Это элементарная Java.

как разрешить переменные R.id

Если TimePicker использует ресурсы, не входящие в Android SDK, вам также потребуется скопировать эти ресурсы из AOSP в свой проект.

Как лучше всего внести небольшое изменение в данный класс из исходного кода Android и включить его в свой собственный проект?

ИМХО, на это нельзя ответить абстрактно. Вообще говоря, вы делаете то, что я перечислил выше.

person CommonsWare    schedule 18.04.2013
comment
Спасибо за ответ. Учитывая ваши комментарии, будет ли выполнимым подход: 1) добавить пакет android.widget в мой проект, 2) скопировать классы TimePicker и NumberPicker из Android с открытым исходным кодом в новые классы в моем проекте, 3) переименовать TimePicker и NumberPicker во что-то еще и внести небольшие изменения, которые я уже определил? - person gcl1; 18.04.2013
comment
Также @CommonsWare: если вышеуказанный подход имеет смысл, как/где я могу получить android.widget в виде пакета? - person gcl1; 18.04.2013
comment
@gcl1: будет ли следующий подход выполнимым - это, безусловно, стоит попробовать. как/где я могу получить android.widget в виде пакета? -- Кажется, я не понимаю вашего вопроса. В Java пакет обозначается строкой package в исходном коде, которая должна совпадать с путем к исходному файлу. В вашем случае добавьте src/android/widget/ и поместите туда код. Кроме того, обязательно соблюдайте условия лицензии для повторно используемого кода. - person CommonsWare; 18.04.2013

Лучше всего создать подклассы соответствующих классов и переопределить методы, которые вы хотели бы изменить.

В Java вы можете сделать следующее в подклассе:

  • Унаследованные поля можно использовать напрямую, как и любые другие поля.
  • Вы можете объявить поле в подклассе с тем же именем, что и в суперклассе, тем самым скрыв его (не рекомендуется).
  • Вы можете объявить новые поля в подклассе, которых нет в суперклассе.
  • Унаследованные методы можно использовать напрямую, как они есть.
  • Вы можете написать новый метод экземпляра в подклассе, который имеет ту же сигнатуру, что и метод в суперклассе, тем самым переопределяя его.
  • Вы можете написать новый статический метод в подклассе, который будет иметь ту же сигнатуру, что и в суперклассе, тем самым скрыв его.
  • Вы можете объявлять новые методы в подклассе, которых нет в суперклассе.
  • Вы можете написать конструктор подкласса, который вызывает конструктор суперкласса либо неявно, либо с помощью ключевого слова super.

    Подробнее о создании подклассов в Java

person Crake    schedule 18.04.2013
comment
Спасибо за ответ. Это кажется хорошим способом, но в моем случае мне нужно изменить приватную переменную (mMinuteSpinner), для которой нет прямого метода доступа. В частности, мне нужно изменить аргумент функции-члена (setOnValueChangedListener()), чтобы использовать другую версию анонимного внутреннего класса (MyNumberPicker для увеличения на 15 вместо NumberPicker, который увеличивается на 1). Как вы думаете, все это выполнимо с помощью подклассов? - person gcl1; 18.04.2013
comment
Вы можете попробовать использовать отражение, чтобы получить доступ к частной переменной, или просто переопределить любой метод, вызываемый для отображения элемента управления, и использовать другую переменную. Я уверен, что с помощью подкласса можно получить то, что вы хотите, но я не уверен, будет ли это в конечном итоге более или менее трудоемким, чем изменение источника (и связанные с этим головные боли, с которыми вы сталкиваетесь). - person Crake; 18.04.2013
comment
Оказывается, метод, который мне нужно изменить, — это конструктор класса TimePicker. И мне нужно внести изменение в другой класс, который он создает. Жаль, что Google не просто предоставил значение приращения минут для TimePicker, как это сделала Apple для его эквивалента в iOS! Я не думаю, что это будет очень сложно для тех, кто уже имеет свои руки в коде. Спасибо за ваши предложения. - person gcl1; 18.04.2013