我正在开发音乐收藏应用程序,但我目前的目标很挣扎:设计一个可滚动显示的3种文本视图的列表-曲目编号,曲目标题和曲目持续时间-将代表专辑中的歌曲。我希望列表的布局由3列固定宽度的列组成,并按预期对齐,而没有特定轨道的标题文本视图,例如,延伸到下面轨道的持续时间文本视图上方。
我考虑了以下选项:
使用一个RecyclerView及其ViewHolder布局,该布局由3个textviews的水平LinearLayout组成。这里的问题是我不知道如何以这种方式保持列对齐。我应该使用确定的dps为textview设置固定宽度吗?然后,如何设置整行以填充设备的整个宽度?
每列使用3个RecyclerViews。我已经尝试了一半,并且各列对齐很好,但是滚动一个RV显然不会滚动其他的,并且要解决这个问题-正如我在这里另一个问题中所看到的-我需要弄乱滚动机制,似乎仍然很容易出现错误,因为RV仍然可能无法同步或应用崩溃。
我知道有GridView(我不熟悉,也不知道它是否可以解决我的问题),但是由于它现在被认为是旧版,所以我宁愿不要使用它。
首先,我想知道在解决这种问题的前提下,有什么方法被认为是“最佳实践”。
谢谢!
1-如果希望它们填充屏幕的宽度,则可以将TextView的宽度设置为match_parent。
2-您只需要一个显示视图列表的回收器视图。
[如果您可以给我看您想要达到的目标的图片
就像您提到的,我们可以使用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个TextView,我按如下方式使用了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
,以使其占用分配空间的全部宽度。这只是一个存储轨道信息的Kotlin类。
class TrackInfo( var trackNumber: Int, var trackTitle: String?, var durationMinutes: Short, var durationSeconds: Short )
这是RecyclerView的Adapter类和ViewHolder类。
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) } }
这里是一个screenshot结果的。我希望这能回答您问题的第一部分。
您已经提到过'当存在没有标题的特定音轨时,延伸到持续时间文本视图上方。
为此,可以使用
android:layout_columnSpan
属性将GridLayout的子级配置为跨越多个单元格。但是要处理trackTitle空情况并相应地设置诸如TextViews的layout_columnSpan之类的属性,我认为为列表项编写自定义视图类会更好。