Как отобразить 40+ кнопок программно

Я создаю небольшое приложение для точек продаж для друга. Ей нужно приложение на планшете с 40 кнопками добавления (и 40 кнопками удаления). Каждая кнопка представляет продукт и имеет свою метку. На левой стороне экрана должно быть 20 вертикальных кнопок, а на правой стороне также должно быть 20 вертикальных кнопок. Все кнопки должны помещаться на одном экране.

Я попытался использовать два recyclerview рядом друг с другом - с фиксированным размером экрана - с одним и тем же адаптером и пользовательскими представлениями внутри каждого recyclerview, но это вызвало много задержек, и в моем эмуляторе я получил предупреждения о том, что кадры были пропущены. Думаю, это из-за большого количества просмотров внутри recyclerview (80+ кнопок).

Затем я попробовал 1 recyclerview с двумя продуктами на 1 горизонтальной строке, но это, похоже, не улучшило производительность и усложнило мое приложение (потому что мне нужно установить два продукта на строку). Я также пытался использовать ListView, потому что я думал, что у него меньше накладных расходов, но он продолжал отставать, и я / хореограф: пропустил 44 кадра! Приложение может выполнять слишком много работы в своем основном потоке.

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

Есть ли способ создать представление с 80 кнопками, которое менее требовательно к системе? В идеале я бы ввел 1 список продуктов в 1 представление.

Пример 1 продукта:

<?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="wrap_content"
    android:orientation="horizontal"
    android:paddingHorizontal="10dip"
    android:paddingTop="1dp"
    android:paddingBottom="4dp">

    <Button
        android:id="@+id/add_button"
        android:layout_width="200dp"
        android:layout_height="44dp"
        android:minHeight="1dip"
        android:text="BUT L"
        android:textSize="22sp" />

    <TextView
        android:id="@+id/amount"
        android:layout_width="80dp"
        android:layout_height="44dp"
        android:paddingHorizontal="20dip"
        android:layout_gravity="center"
        android:textAlignment="center"
        android:text="0"
        android:textSize="22sp" />

    <Button
        android:id="@+id/delete_button"
        android:layout_width="60dp"
        android:layout_height="44dp"
        android:minWidth="1dip"
        android:minHeight="1dip"
        android:text="-"
        android:textSize="22sp" />

</LinearLayout>

person FrederikVR    schedule 08.12.2020    source источник
comment
Возможно, вы пробовали интерактивные метки вместо кнопок? Возможно, это менее интенсивно рисовать, чем кнопки. Также было бы полезно опубликовать короткий фрагмент кода, который воспроизводит проблему, так как это облегчит ее воспроизведение, и вы, скорее всего, получите ответ быстрее.   -  person David Kroukamp    schedule 08.12.2020


Ответы (1)


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

RecyclerView - правильный способ сделать это - они разработаны, чтобы быть эффективными! Старый подход ListView создавал бы ваши 40 записей с их собственными Button представлениями - RecyclerViews создавал только несколько (достаточно, чтобы заполнить экран и пару с каждой стороны, чтобы они могли заглянуть при прокрутке).

Затем они перерабатывают их, беря ViewHolder, который прокручивается за пределы экрана, и заполняя его данными для элемента, который вот-вот появится в поле зрения (это и есть метод onBindViewHolder, заполнение этих данных ). Таким образом, у вас есть только несколько ViewHolders с их макетами представления, и не имеет значения, представляет ли ваш список 40 элементов или 40 000!


На самом деле вы должны профилировать производительность на реальном устройстве, но у вас не должно быть никаких проблем с базовым макетом RecyclerView, это вряд ли что-то с точки зрения пользовательского интерфейса. Если вы хотите, вы можете опубликовать свой код Adapter и ViewHolder, и люди могут сказать вам, делаете ли вы что-то очень медленное или интенсивное по памяти в реальной логике обработки.

Также убедитесь, что вы просматриваете элементы пользовательского интерфейса один раз для каждого ViewHolder, который вы создаете, и сохраняете их как свойства, которые вы можете установить в onBindViewHolder. Если вы используете findViewById в onBindViewHolder (который, как вы помните, запускается каждый раз, когда элемент готовится к прокрутке в поле зрения), это много дублирующей работы. Вероятно, в этом случае не будет сбоев, но все же лучше избегать этого, если можете!

person cactustictacs    schedule 08.12.2020