Я попытался создать прокручиваемый список из 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)
}
}
Результат:
Я надеюсь, что это ответит на первую часть вашего вопроса.
Вы упомянули о «растягивании над продолжительностью текстового просмотра, когда есть определенный трек без заголовка».
Для этого дочерние элементы GridLayout могут быть настроены на охват нескольких ячеек с использованием атрибута android:layout_columnSpan
.
Но для обработки нулевых случаев trackTitle и соответственно установки свойств, таких как layout_columnSpan в TextView, я думаю, что это будет Лучше написать собственный класс представления для элемента списка.