Создайте прокручиваемый список из нескольких текстовых просмотров в строке - PullRequest
0 голосов
/ 01 мая 2020

Я занимаюсь разработкой приложения для сбора музыки c, и я борюсь со своей текущей целью: создать прокручиваемый список из 3 текстовых просмотров - номер трека, название трека и продолжительность трека - которые будут представлять песни в альбоме. Я хочу, чтобы макет списка состоял из 3 столбцов с фиксированной шириной, выровненных, как и следовало ожидать, без видимости текста заголовка для конкретной дорожки, например, растягивающегося над продолжительностью просмотра текста дорожки ниже.

Я рассмотрел следующие варианты:

  1. Использование одного RecyclerView с его макетом ViewHolder, состоящим из горизонтального LinearLayout из 3 текстовых представлений. Проблема здесь в том, что я не знаю, как сохранить выравнивание столбцов таким образом. Должен ли я установить фиксированную ширину для текстовых представлений с использованием определенных дпс? Как тогда я могу установить всю строку, чтобы заполнить всю ширину устройства?

  2. Используя 3 RecyclerViews для каждого столбца. Я попробовал эту идею на полпути, и столбцы хорошо выровнены, но прокрутка одного RV, конечно, не прокручивает другие, и чтобы это исправить - как я видел в другом вопросе здесь - мне нужно будет возиться с механизм прокрутки, и кажется, что он все еще может быть очень подвержен ошибкам с RV, которые все же могут выйти из строя c или приложение рухнет.

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

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

Спасибо!

Ответы [ 3 ]

1 голос
/ 01 мая 2020

Это альтернативное решение, вдохновленное ответом Фаршада Тахмасби , который я нашел здесь .

На этом снимке экрана вы можете увидеть результат. (Столбец длительности сейчас пуст).

    mTracksRecyclerView.setAdapter(new TrackListAdapter(getContext(), musicItem.getTracks()));
    GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 12);
    gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            int type = position % 3 ;
            if (type == 0) {
                // Position
                return 2;
            } else if (type == 1) {
                // Title
                return 8;

            } else {
                // Duration
                return 2;
            }
        }
    });
    mTracksRecyclerView.setLayoutManager(gridLayoutManager);
0 голосов
/ 01 мая 2020

Я попытался создать прокручиваемый список из 3 TextViews для строки.

Как вы уже упоминали, мы можем использовать RecyclerView в качестве прокручиваемого списка.

activity_main. xml

<ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</ConstraintLayout>

Чтобы элемент списка имел 3 TextViews подряд, я использовал GridLayout следующим образом.

list_item. xml

<GridLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:columnCount="3"
    android:rowCount="1" >

    <TextView
        android:id="@+id/trackNumber"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:background="@android:color/holo_red_light" />

    <TextView
        android:id="@+id/trackTitle"
        android:layout_columnWeight="6"
        android:layout_width="0dp"
        android:ellipsize="end"
        android:background="@android:color/holo_green_light" />

    <TextView
        android:id="@+id/trackDuration"
        android:layout_columnWeight="1"
        android:layout_width="0dp"
        android:background="@android:color/holo_blue_light" />

</GridLayout>

Для каждого TextView значение layout_columnWeight устанавливается для указания относительной доли горизонтального пространства, которое должно быть выделено для него. Каждое значение TextView layout_width устанавливается на 0dp, чтобы оно занимало всю ширину выделенного пространства.

Но вместо GridLayout мы можем использовать ConstraintLayout и достичь того же результата. Как упомянуто выше в вопросе, GridLayout помечен как устаревший. Лучше использовать ConstraintLayout.

list_item. xml

<ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <TextView
        android:id="@+id/trackNumber"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintHorizontal_weight="1"
        android:background="@android:color/holo_red_light"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@id/trackTitle"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/trackTitle"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintHorizontal_weight="6"
        android:ellipsize="end"
        android:background="@android:color/holo_green_light"
        app:layout_constraintStart_toEndOf="@id/trackNumber"
        app:layout_constraintEnd_toStartOf="@id/trackDuration"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/trackDuration"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintHorizontal_weight="1"
        android:background="@android:color/holo_blue_light"
        app:layout_constraintStart_toEndOf="@id/trackTitle"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</ConstraintLayout>

Для каждого TextView значение layout_constraintHorizontal_weight устанавливается для указания относительной доли горизонтального пространства, которое должно быть выделено для него. , Каждое значение layout_width TextView установлено на 0dp, чтобы оно занимало всю ширину выделенного пространства.

Это просто класс Kotlin для хранения информации о дорожке.

class TrackInfo(
    var trackNumber: Int,
    var trackTitle: String?,
    var durationMinutes: Short,
    var durationSeconds: Short
)

Это класс Adapter и класс ViewHolder для RecyclerView.

class TrackInfoAdapter(private val items: List<TrackInfo>, private val mContext: Context) :
    RecyclerView.Adapter<ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(
            LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false)
        )
    }

    override fun getItemCount() = items.size

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val trackInfo = items[position]
        holder.trackNumber.text = trackInfo.trackNumber.toString()
        holder.trackTitle.text = trackInfo.trackTitle
        // Use String.format() to add leading zero for single digit durationSeconds value
        val formattedDurationSeconds = "%02d".format(trackInfo.durationSeconds)
        holder.trackDuration.text = "${trackInfo.durationMinutes}:$formattedDurationSeconds"
    }

}

class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    val trackNumber = view.trackNumber
    val trackTitle = view.trackTitle
    val trackDuration = view.trackDuration
}

Это MainActivity.

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Prepare list of track information
        val trackInfoList = mutableListOf<TrackInfo>().apply {
            // track 1
            add(
                TrackInfo(1, "Lady GaGa - Poker Face",
                    4, 4)
            )

            // track 2
            add(
                TrackInfo(2, "T.I. featuring Rihanna - Live Your Life",
                    4, 1)
            )

            // track 3
            add(
                TrackInfo(3, "Kanye West - Stronger",
                    5, 11)
            )

            // track 4
            add(
                TrackInfo(4, "Leon Haywood - I Wanna Do Something Freaky To You",
                    6, 0)
            )

            // track 5
            add(
                TrackInfo(5, "Hilary Duff - Reach Out",
                    4, 16)
            )
        }

        recyclerView.layoutManager = LinearLayoutManager(baseContext)
        // Set track information list to Adapter of RecyclerView
        recyclerView.adapter = TrackInfoAdapter(trackInfoList, baseContext)
    }
}

Результат:

Here is a screenshot of the result

Я надеюсь, что это ответит на первую часть вашего вопроса.

Вы упомянули о «растягивании над продолжительностью текстового просмотра, когда есть определенный трек без заголовка».

Для этого дочерние элементы GridLayout могут быть настроены на охват нескольких ячеек с использованием атрибута android:layout_columnSpan.

Но для обработки нулевых случаев trackTitle и соответственно установки свойств, таких как layout_columnSpan в TextView, я думаю, что это будет Лучше написать собственный класс представления для элемента списка.

0 голосов
/ 01 мая 2020

лучшее решение для этого - использование RecyclerView.

1 - вы можете установить ширину TextViews для match_parent, если вы хотите, чтобы они занимали всю ширину экрана.

2 - вам нужен только один вид переработчика, который показывает список смотреть.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...