Android: автоматически создавать переменные для всех идентификаторов в XML - PullRequest
17 голосов
/ 02 августа 2011

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

После настройки графики, макет, связывание переменных с элементами макета очень утомительно, например ImageButton myButton = (ImageButton)findViewById(R.id.myButton);

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

Чтобы немного смягчить это, было бы очень удобно, если бы все идентификаторы, которые я объявил в XML, были автоматически связаны с их собственными переменными, и все эти типы данных уже были включены в этот класс

Есть ли что-то, что уже делает это?

например, если я напишу

 <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/myButton" android:id="@+id/myButton"></ImageButton>

тогда я бы хотел, чтобы классы, включающие этот макет, уже имели

 import android.ImageButton;

 ImageButton myButton;

 myButton = (ImageButton)findViewById(R.id.myButton);

это настройка или функция по запросу? Я использую Eclipse IDE, и это было бы очень удобно

Ответы [ 4 ]

29 голосов
/ 15 февраля 2013

Я создал инструмент для автоматической генерации кода Java для связывания XML-макетов и программной логики.

По сути, он принимает макет XML и мгновенно генерирует для вас весь необходимый Java-код.Существует поддержка базовых переменных-членов, шаблонов ViewHolder, типов кода ArrayAdapter, CursorAdapter и RoboGuice.

Вы можете найти его здесь: Android Layout Finder |Гудит Android

15 голосов
/ 02 августа 2011

Попробуйте использовать Аннотации Android .Он предоставляет полезные аннотации для замены стандартного кода.

Например, см. @ViewById документация : просто объявите аннотированные поля

@ViewById
EditText myEditText;

@ViewById(R.id.myTextView)
TextView textView;

Он заменяет

EditText myEditText;

TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
    [...]
    myEditText = (EditText) findViewById(R.id.myEditText);
    textView = (TextView) findViewById(R.id.myTextView);
}
0 голосов
/ 30 июля 2018

ОБНОВЛЕНИЕ : Генератор кода привязки представления Android (AVB) , это именно то, что я собираюсь сказать: |


REGEX!

У меня была такая же проблема, и я попытался решить ее самостоятельно, поэтому я превратился в REGEX внутри поиска и замены дорогого Android Studio.Лично я использую ButterKnife для внедрения зависимостей с Java-аннотацией, но более важной частью является то, как автоматизировать процедуру превращения идентификаторов в XML-макете в Java-объекты.Это похоже на Android Layout Finder |Гудит Android (у сайта есть больше функций, но старый :() ответ, но с результатом аннотации.

  1. перейдите на xml и выберите все идентификаторы с этим регулярным выражением(\+id/.*). Для этого сначала нажмите Ctrl + F, чтобы открыть панель поиска, затем убедитесь, что установлен флажок Regex. Затем введите регулярное выражение (\+id/.*) внутри поля и нажмите Ctrl + Alt + Shift + Jчтобы выбрать все вхождения. Теперь Ctrl + C, чтобы скопировать их (вы знаете ярлык).

например, у меня был такой макет:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layoutDirection="rtl"
    tools:context=".jobs.return_from_entrance.ReturnFromEntranceActivity"
    tools:ignore="HardcodedText">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <GridLayout
            android:id="@+id/return_entrance_grid_layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:columnCount="2"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="شماره برگشت" />

            <TextView
                android:id="@+id/return_entrance_return_entrance_number_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="123123123"
                android:textColor="@android:color/black"
                android:textSize="18sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="@string/owner_of_cargo" />

            <TextView
                android:id="@+id/return_entrance_owner_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="الجی"
                android:textColor="@android:color/black"
                android:textSize="18sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="تاریخ و زمان" />

            <TextView
                android:id="@+id/return_entrance_time_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="12/12/12/ 12:12"
                android:textColor="@android:color/black"
                android:textSize="18sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="نوع حواله" />

            <TextView
                android:id="@+id/return_entrance_kind_of_order_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="حواله"
                android:textColor="@android:color/black"
                android:textSize="18sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="خریدار" />


            <TextView
                android:id="@+id/return_entrance_buyer_name_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="علی امیدی"
                android:textColor="@android:color/black"
                android:textSize="18sp" />


            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="مقصد" />

            <TextView
                android:id="@+id/return_entrance_destination_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="آزادی"
                android:textColor="@android:color/black"
                android:textSize="18sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="وزن ناخالص" />

            <TextView
                android:id="@+id/return_entrance_gross_weight_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="123"
                android:textColor="@android:color/black"
                android:textSize="18sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="شماره جواز" />

            <TextView
                android:id="@+id/return_entrance_permission_number_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="126545643"
                android:textColor="@android:color/black"
                android:textSize="18sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="شماره بارنامه" />

            <TextView
                android:id="@+id/return_entrance_waybill_number_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="654"
                android:textColor="@android:color/black"
                android:textSize="18sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="زمان ورود" />

            <TextView
                android:id="@+id/return_entrance_enter_time_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="21/12/12 22:22"
                android:textColor="@android:color/black"
                android:textSize="18sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="زمان خروج" />

            <TextView
                android:id="@+id/return_entrance_exit_time_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="21/12/12 22:22"
                android:textColor="@android:color/black"
                android:textSize="18sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="محوطه بارگیری" />

            <TextView
                android:id="@+id/return_entrance_load_location_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="حیاط"
                android:textColor="@android:color/black"
                android:textSize="18sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="نیاز به جرثقیل" />

            <TextView
                android:id="@+id/return_entrance_is_crane_needed_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="ندارد"
                android:textColor="@android:color/black"
                android:textSize="18sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="نیاز به لیفتراک" />

            <TextView
                android:id="@+id/return_entrance_is_forklift_needed_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="ندارد"
                android:textColor="@android:color/black"
                android:textSize="18sp" />

            <CheckBox
                android:id="@+id/return_entrance_internal_return_entrance_checkbox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="@dimen/margin_large"
                android:layout_marginStart="@dimen/margin_medium"
                android:layout_marginTop="@dimen/margin_large"
                android:text="خروج داخلی" />

            <View
                android:layout_width="0dp"
                android:layout_height="0dp" />

            <CheckBox
                android:id="@+id/return_entrance_warehouse_delivery_checkbox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="@dimen/margin_large"
                android:layout_marginStart="@dimen/margin_medium"
                android:layout_marginTop="@dimen/margin_large"
                android:text="تحویل در انبار" />

            <View
                android:layout_width="0dp"
                android:layout_height="0dp" />

            <Button
                android:id="@+id/return_entrance_location_delivery_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/margin_large"
                android:text="تحویل در محل" />

            <View
                android:layout_width="0dp"
                android:layout_height="0dp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="عکس راننده" />

            <ImageView
                android:id="@+id/return_entrance_driver_image_view"
                android:layout_width="120dp"
                android:layout_height="120dp"
                android:layout_gravity="center"
                android:layout_marginTop="@dimen/item_margin"
                android:src="@drawable/ic_account_circle_black_24dp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="@string/name_of_driver" />

            <TextView
                android:id="@+id/return_entrance_name_of_driver_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="علی امیدی"
                android:textColor="@android:color/black"
                android:textSize="18sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="@string/kind_of_car" />

            <TextView
                android:id="@+id/return_entrance_kind_of_car_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="وانت مزدا"
                android:textColor="@android:color/black"
                android:textSize="18sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="@string/plaque" />

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/margin_large"
                android:orientation="horizontal">

                <TextView
                    android:id="@+id/return_entrance_plaque_2digit_text_view"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/plaque_background"
                    android:padding="10dp"
                    android:text="11"
                    android:textColor="@android:color/black"
                    android:textSize="10pt"
                    android:textStyle="bold" />

                <TextView
                    android:id="@+id/return_entrance_plaque_6digit_text_view"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@drawable/plaque_background"
                    android:padding="10dp"
                    android:text="999ج77"
                    android:textColor="@android:color/black"
                    android:textSize="10pt"
                    android:textStyle="bold" />
            </LinearLayout>
        </GridLayout>

        <Button
            android:id="@+id/return_entrance_barcode_scan_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_margin="@dimen/margin_small"
            android:drawableStart="@drawable/ic_barcode"
            android:padding="@dimen/margin_medium"
            android:text="@string/scan_barcode"
            android:textSize="18sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/return_entrance_grid_layout" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/return_entrance_cargo_list_recycler_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/return_entrance_barcode_scan_button" />

        <GridLayout
            android:id="@+id/return_entrance_bottom_grid_layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:columnCount="2"
            android:layoutDirection="rtl"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/return_entrance_cargo_list_recycler_view">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="میزان موجودی کالای قابل تحویل" />

            <TextView
                android:id="@+id/return_entrance_deliverable_availability_text_view"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/text_margin"
                android:text="50"
                android:textColor="@android:color/black"
                android:textSize="18sp" />

        </GridLayout>

        <LinearLayout
            android:id="@+id/return_entrance_bottom_linear_2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:orientation="vertical"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/return_entrance_bottom_grid_layout">

            <Button
                android:id="@+id/return_entrance_cost_report_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/margin_medium"
                android:text="گزارش هزینه" />

            <Button
                android:id="@+id/return_entrance_confirm_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/margin_medium"
                android:text="تایید برگشت" />

        </LinearLayout>

    </android.support.constraint.ConstraintLayout>
</android.support.v4.widget.NestedScrollView>

много текстовых просмотров взаполнить, да?

перейдите в класс java и вставьте скопированные идентификаторы (Ctrl + V).таким образом, у нас есть куча идентификаторов, которые мы хотим превратить в объекты Java.в нашем примере мои идентификаторы были бы такими:

+id/return_entrance_grid_layout"
+id/return_entrance_return_entrance_number_text_view"
+id/return_entrance_owner_text_view"
+id/return_entrance_time_text_view"
...

Пришло время найти и заменить!поэтому сначала мы нажимаем Ctrl + R, чтобы открыть панель поиска и замены.(убедитесь, что флажок REGEX установлен) теперь я собираюсь найти и заменить, чтобы получить идеальный результат:

Найти: \+id/(.*)" Заменить на: @BindView(R.id.$1), поэтому у нас будет это:

@BindView(R.id.return_entrance_grid_layout)
@BindView(R.id.return_entrance_return_entrance_number_text_view)
@BindView(R.id.return_entrance_owner_text_view)
@BindView(R.id.return_entrance_time_text_view)
...

Теперь пришло время определить каждый тип переменной и присвоить им имена.у моего имени xml есть шаблон WHERE_DESCRIPTION_WHAT, ( что-то вроде этого ).поэтому для имени переменной я хочу удалить часть WHERE.а затем определите объект тип .Итак, поехали:

Найти: (@BindView\(R\.id\.return_entrance_(.*)_text_view\)) Заменить на: $1 TextView $2TextView; Результат будет:

@BindView(R.id.return_entrance_grid_layout)
@BindView(R.id.return_entrance_return_entrance_number_text_view) TextView return_entrance_numberTextView;
@BindView(R.id.return_entrance_owner_text_view) TextView ownerTextView;
@BindView(R.id.return_entrance_time_text_view) TextView timeTextView;
@BindView(R.id.return_entrance_kind_of_order_text_view) TextView kind_of_orderTextView;
...

(просто нажмите Ctrl + Alt + L для переформатирования кода)Имена неопрятны :(. поэтому мы делаем это для camelCase!:

Найти: TextView \b(.*)_(.*) Заменить на: TextView $1\u$2, и результат будет:

@BindView(R.id.return_entrance_owner_text_view)
TextView ownerTextView;
@BindView(R.id.return_entrance_time_text_view)
TextView timeTextView;
@BindView(R.id.return_entrance_kind_of_order_text_view)
TextView kind_ofOrderTextView;
@BindView(R.id.return_entrance_buyer_name_text_view)
TextView buyerNameTextView;
@BindView(R.id.return_entrance_destination_text_view)
TextView destinationTextView;

Если вы повторите последнюю часть, любое имя, которое имеет большечем одно подчеркивание, каждый _ будет заменен на верхний регистр следующего символа.так что в этом примере, если я снова найду Find: TextView \b(.*)_(.*) Replace With: TextView $1\u$2, мой TextView kind_ofOrderTextView; будет TextView kindOfOrderTextView;

Это может показаться немного сложным, но когда вы к этому привыкнете,это становится таким быстрым и таким полезным!например, представьте, что в MVP у вас есть Model с теми же String именами TextViews, так что вы можете сделать это, чтобы установить все их тексты из Model с подобным подходом..

0 голосов
/ 02 августа 2011

Это запрос функции.Это очень хорошо, и я думаю, что это было бы очень полезно;с другой стороны, есть случаи, когда это не сработало бы очень хорошо, например, если вы динамически раздувает представления и не знаете, во время компиляции, какой вид конкретного действия будет раздуваться.Однако я склонен думать, что этот случай будет скорее исключением, чем правилом.

Самый простой способ сделать это - написать скрипт, который сканирует файлы макета XML в поисках компонентов с идентификаторами и создает.Java-файлы с правильными определениями.Тогда ваша деятельность может происходить из этих автоматически сгенерированных классов.Примерно так:

При обработке вашим сценарием создается класс:

class FooBarLayoutActivityBase extends Activity ... {
  protected ImageButton myButton;

  FooBarLayoutActivityBase() {
    myButton = (ImageButton)findViewById(R.id.myButton);
  }
}

Затем вы можете просто наследовать от этого базового класса для использования компонентов...

Подход сценария прост и не требует, чтобы вы углублялись в код цепочки инструментов - но вы также можете сделать это прямо в плагине ADT.

...