«Hijckr: незаконное присвоение ваших XML-тегов с 2018 года»
Hijckr - это новая библиотека Android, которая позволяет разработчикам перехватывать расширение файла макета XML и перенаправлять элементы XML на любые виджеты, которые им нравятся. Это позволяет разработчикам использовать свои существующие файлы макетов при изменении поведения и отображения виджета. Hijckr поддерживает перенаправление предпочтений для всего приложения или для каждой активности.
Начало работы: gradle
Для начала создайте новое приложение для Android и добавьте зависимость от библиотеки Hijckr в файл build.gradle:
dependencies { // ... implementation 'com.justinangel:hijckr:1+' }
Пример Hijckr: перенаправление тегов для всего приложения
В простейшем случае мы хотели бы выполнить дополнительный код в жизненном цикле существующих виджетов. Мы сделаем это, создав подкласс этого виджета и перенаправив его с виджета по умолчанию на наш наследующий виджет. Все, что нам для этого нужно сделать, - это настроить маршрутизацию классов, вызвав HijckrClassLoader.addGlobalClassRouting , и унаследовать мои действия от HijckrActivity.
В качестве тривиального примера предположим, что все наши теги ‹TextView /› xml должны создавать экземпляр com.my.AppTextView, который изменяет цвет текста на красный и размер шрифта на 18.
Мы начинаем с файла макета XML, используя ‹TextView /›.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /> </LinearLayout>
Затем мы создадим класс AppTextView.
public class AppTextView extends TextView { // .. c'tors @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); this.setTextSize(28); this.setTextColor(Color.RED); } }
Теперь пора окропить магией Hijckr. Сначала мы скажем Hijckr перенаправить все теги XML, принадлежащие TextView, в AppTextView. Мы настроим их перенаправление в пользовательском приложении onCreate ().
public class App extends Application { @Override public void onCreate() { super.onCreate(); HijckrClassLoader.addGlobalClassRouting(TextView.class, AppTextView.class); } }
Для другой части сказочной пыли Hijckr мы изменим нашу активность, чтобы наследовать от HijckrActivity в качестве базового класса вместо Activity.
import com.justinangel.hijckr.HijckrActivity; public class MainActivity extends HijckrActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
И когда мы запускаем наше приложение, мы видим, что наш ‹TextView /› использует новый AppTextView, потому что текст красный, а размер шрифта равен 18.
Hijckr: перенаправление тегов для конкретных действий
Есть случаи, когда мы не хотим настраивать перенаправление для всего приложения или мы не можем просто изменить наш базовый класс активности. В таких случаях мы можем настроить перенаправление тегов для конкретных действий.
В качестве тривиального примера предположим, что мы хотим, чтобы все ‹EditText /› в рамках определенного действия находили любые строки «:)» и заменяли их эмодзи 😀. Начнем с файла макета с тегом ‹EditText /›.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Type a smiley face"/> </LinearLayout>
Затем мы пишем настраиваемый виджет, который наследуется от EditText и добавляет желаемое дополнительное поведение.
public class SmileyEditText extends EditText { // .. c'tors @Override protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { super.onTextChanged(text, start, lengthBefore, lengthAfter); if (text.toString().contains(":)")) { setText(text.toString().replace(":)", "\uD83D\uDE0A")); } } }
В рамках нашей деятельности мы переопределим getClassLoader, чтобы вернуть новый HijckrClassLoader с желаемой перемаршрутизацией.
import com.justinangel.hijckr.HijckrClassLoader; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public ClassLoader getClassLoader() { return new HijckrClassLoader(super.getClassLoader()) .withClassRouting(EditText.class, S.class); } }
Когда мы запускаем этот образец и набираем «:)», мы видим, что текст был заменен.
Когда мне следует использовать Hijckr? Какие лучшие практики?
Я использую перенаправление тегов в стиле Hijckr уже несколько лет, и мы разработали несколько лучших практик в наших приложениях.
- Можно добавить поведение к существующим виджетам с помощью Hijckr, добавив код в c’tors или переопределив жизненный цикл Android.
- Используйте конструктор и виджеты Android Studio по умолчанию. Hijckr позволяет вам продолжать использовать виджеты по умолчанию в конструкторе по умолчанию.
- Не используйте Hijckr исключительно для стилизации. В Android есть отличная система управления ресурсами, которая поддерживает стили и темы. Вы не хотите отказываться от этого.
- Можно использовать Hijckr для условного изменения стиля и поведения виджетов. Например, приложение, работающее на Android Wear с макетами, содержащими теги ‹RecyclerView /›, необходимо перенаправить на WearableRecyclerView. Это тот случай, который впервые привел меня в Hijckr.
Известные ограничения
- Созданные элементы: изменение глобальной маршрутизации применяется только до расширения файлов макета. Он не будет применяться задним числом к созданным элементам после расширения макета.
- Именованные элементы: для элементов XML с x: перемаршрутизация имени должна выполняться в направлении классов, унаследованных от исходной маршрутизации. например ‹Button x: Name =” foo ”/› необходимо направить в класс, который имеет Button в качестве базового класса. Для любых XML-элементов, у которых нет x: перенаправление имени не имеет этих ограничений. Например, ‹Button /› можно направить на что угодно (например, TextView).
Вопросов?
Спрашивай.
Ознакомьтесь с исходным кодом на GitHub.