赞
踩
1.设计思想
其实当你看到一个布局或界面时,你首先要想怎么实现,用什么控件,当时我第一个想到的就是listview,但listview没有办法实现横向滑动,所以决定用RecycleView,最开始想的是用2个RecycleView(一个横向和一个竖向)。其实这里有一个问题,当滑动竖向RecycleView时,横向RecycleView是不会跟着一起动的,这从用户的角度来看体验肯定不好(开发者可以以用户的角度去开发,这样产品会有更多的用户体验)
最后的设计是,外面有一个顶层竖向RecycleView,横向RecycleView是其中一个Item。
1.准备横向RecycleView的布局
<?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">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/hrecycleview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"/>
</LinearLayout>
2.准备横向RecycleView的Item的布局
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="169dp"> <TextView android:id="@+id/text5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/imagemap" android:layout_marginLeft="4dp" android:layout_marginTop="16dp" android:text="精选栏目" /> <ImageView android:id="@+id/imagemap" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="16dp" android:layout_marginTop="16dp" android:src="@drawable/shape" /> <ImageView android:id="@+id/imageview" android:layout_width="239dp" android:layout_height="143dp" android:layout_marginLeft="16dp" android:layout_marginTop="46dp" android:src="#ad226bff" /> <TextView android:id="@+id/text1" android:layout_width="215dp" android:layout_height="36dp" android:layout_alignTop="@id/imageview" android:layout_marginLeft="12dp" android:layout_alignStart="@id/imageview" android:layout_marginTop="54dp" android:text="RecycleView实现首页复杂布局效果(横向和竖向)…" android:textColor="#ffffffff"/> <TextView android:id="@+id/text2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/text1" android:layout_marginTop="16dp" android:layout_alignStart="@id/text1" android:layout_marginLeft="2dp" android:text="05-04 15:20 | 9999阅" android:textColor="#ffffffff"/> <View android:layout_width="3dp" android:layout_height="wrap_content" android:layout_toRightOf="@id/imageview"/> </RelativeLayout>
3.设置横向RecycleView的适配器
class SecondAdapter(val datalist1: List<DateMessage>) : RecyclerView.Adapter<SecondAdapter.MyViewHolder>() { class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) { val text1 = view.findViewById<TextView>(R.id.text1) val text2 = view.findViewById<TextView>(R.id.text2) val text5 = view.findViewById<TextView>(R.id.text5) val imagemap = view.findViewById<ImageView>(R.id.imagemap) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.item2, parent, false) return MyViewHolder(view) } override fun onBindViewHolder(holder: MyViewHolder, position: Int) { when (position) { 0 -> { holder.text5.visibility = View.VISIBLE holder.imagemap.visibility = View.VISIBLE } else -> { holder.text5.visibility = View.GONE holder.imagemap.visibility = View.GONE } } val data = datalist1[position] holder.apply { text1.text = data.title text2.text = data.desc } } override fun getItemCount(): Int { return datalist1.size } }
这里都是适配器的正常步骤,主要讲解下下面这段代码
when (position) {
0 -> {
holder.text5.visibility = View.VISIBLE
holder.imagemap.visibility = View.VISIBLE
}
else -> {
holder.text5.visibility = View.GONE
holder.imagemap.visibility = View.GONE
}
}
这是通过判断数据的数组下标,如果是第一个数据,就让2个控件为显示状态,相当于标识这是第一个数据(达到置顶效果),以后的数据不显示这2个控件。
4.写一个数据类
data class MultiItem(
//用于标识传入的数据是横向RecycleView还是竖向RecycleView的
var itemType: Int,
//横向 rv
var listData: List<DateMessage>? = null,
//竖向
var data: DateMessage? = null
)
5.总布局
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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" tools:context=".MainActivity"> <ImageView android:id="@+id/image1" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginLeft="16dp" android:layout_marginTop="8dp" android:src="@mipmap/map1" tools:ignore="MissingConstraints" /> <EditText android:id="@+id/edittext1" android:layout_width="259dp" android:layout_height="30dp" app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="7dp" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginLeft="60dp" android:background="@null" tools:ignore="MissingConstraints" /> <ImageView android:layout_width="16dp" android:layout_height="16dp" app:layout_constraintTop_toTopOf="@id/edittext1" app:layout_constraintLeft_toLeftOf="@id/edittext1" android:layout_marginTop="7dp" android:layout_marginLeft="8dp" android:src="@mipmap/map2"/> <TextView android:id="@+id/text2" android:layout_width="116dp" android:layout_height="17dp" app:layout_constraintTop_toTopOf="@id/edittext1" app:layout_constraintLeft_toLeftOf="@id/edittext1" android:layout_marginTop="7dp" android:layout_marginLeft="30dp" android:text="点击搜索精彩内容" android:textSize="14sp"/> <ImageView android:layout_width="24dp" android:layout_height="24dp" android:src="@mipmap/map3" app:layout_constraintTop_toTopOf="parent" app:layout_constraintEnd_toEndOf="parent" android:layout_marginTop="10dp" android:layout_marginEnd="16dp" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/mainRecycleView" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintTop_toBottomOf="@id/edittext1" android:layout_marginTop="54dp" app:layout_constraintBottom_toTopOf="@id/view" tools:ignore="MissingConstraints" /> <View android:id="@+id/view" android:layout_width="match_parent" android:layout_height="1dp" app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="48dp" /> <ImageView android:id="@+id/image2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/bottommap1" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" android:layout_marginLeft="25dp" android:layout_marginBottom="21dp" tools:ignore="MissingConstraints" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="@id/image2" app:layout_constraintTop_toBottomOf="@id/image2" android:text="首页" android:textSize="11sp" tools:ignore="MissingConstraints" /> <ImageView android:id="@+id/image3" android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@mipmap/boottommap2" tools:ignore="MissingConstraints" app:layout_constraintLeft_toRightOf="@id/image2" android:layout_marginLeft="49dp" app:layout_constraintTop_toTopOf="@id/image2" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="@id/image3" app:layout_constraintTop_toBottomOf="@id/image3" android:text="今日头条" android:textSize="11sp" tools:ignore="MissingConstraints" /> <ImageView android:id="@+id/image4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/bottommap3" app:layout_constraintLeft_toRightOf="@id/image3" android:layout_marginLeft="49dp" app:layout_constraintTop_toTopOf="@id/image3" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="@id/image4" app:layout_constraintTop_toBottomOf="@id/image4" android:text="选择" android:textSize="11sp"/> <ImageView android:id="@+id/image5" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintLeft_toRightOf="@id/image4" android:layout_marginLeft="49dp" app:layout_constraintTop_toTopOf="@id/image4" android:src="@mipmap/bottommap4" tools:ignore="MissingConstraints" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="@id/image5" app:layout_constraintTop_toBottomOf="@id/image5" android:text="行情分析" android:textSize="11sp" tools:ignore="MissingConstraints" /> <ImageView android:id="@+id/image6" android:layout_width="wrap_content" android:layout_height="wrap_content" tools:ignore="MissingConstraints" android:src="@mipmap/bottommap5" app:layout_constraintLeft_toRightOf="@id/image5" android:layout_marginLeft="49dp" app:layout_constraintTop_toTopOf="@id/image5"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="@id/image6" app:layout_constraintTop_toBottomOf="@id/image6" android:text="好友会" android:textSize="11sp" tools:ignore="MissingConstraints" /> </androidx.constraintlayout.widget.ConstraintLayout>
6.顶层RecycleView的适配器
class HeadRefactorAdapter(private val dataList: ArrayList<MultiItem>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { companion object { private const val BANNER = 1 private const val HORIZONTAL = 2 private const val VERTICAL = 3 } class HorizontalViewHolder(view: View) : RecyclerView.ViewHolder(view) { private val rvContentList = view.findViewById<RecyclerView>(R.id.hrecycleview) fun bind(data: List<DateMessage>?) { if (data.isNullOrEmpty()) { return } rvContentList.apply { layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) adapter = SecondAdapter(data) } } } class VerticalViewHolder(view: View) : RecyclerView.ViewHolder(view) { private val text1: TextView = view.findViewById(R.id.text1) private val text2: TextView = view.findViewById(R.id.text2) private val text3: TextView = view.findViewById(R.id.text3) private val image: ImageView = view.findViewById(R.id.image) fun bind(listData: DateMessage?) { if (listData == null) { return } if (adapterPosition == 0) { text2.visibility = View.VISIBLE } else { text2.visibility = View.GONE } text1.text = listData.title text3.text = listData.desc image.setImageResource(listData.image) } } override fun getItemViewType(position: Int): Int { return when (dataList[position].itemType) { 2 -> HORIZONTAL else -> VERTICAL } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { val layoutInflater = LayoutInflater.from(parent.context) return when (viewType) { HORIZONTAL -> HorizontalViewHolder( layoutInflater.inflate( R.layout.hrecycleview, parent, false ) ) VERTICAL -> VerticalViewHolder( layoutInflater.inflate( R.layout.item1, parent, false ) ) else -> {} } } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { when (holder) { is HorizontalViewHolder -> { holder.bind(dataList[position].listData) } is VerticalViewHolder -> { holder.bind(dataList[position].data) } } } override fun getItemCount(): Int { return dataList.size } }
这里主要说下 getItemViewType方法,根据传入数据的itemType可以判断出是横向还是竖向的RecycleVIew的数据
override fun getItemViewType(position: Int): Int {
return when (dataList[position].itemType) {
2 -> HORIZONTAL
else -> VERTICAL
}
}
最后在 onCreateViewHolder方法中根据viewType来解析不同的布局,这里如果对 LayoutInflater有疑惑可以看我的另一篇博客LayoutInflater详解
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
return when (viewType) {
HORIZONTAL -> HorizontalViewHolder(
layoutInflater.inflate(
R.layout.hrecycleview,
parent,
false
)
)
VERTICAL -> VerticalViewHolder(
layoutInflater.inflate(
R.layout.item1,
parent,
false
)
)
else -> {}
}
}
最后通过onBindViewHolder判断ViewHolder的类型进行数据展示
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is HorizontalViewHolder -> {
holder.bind(dataList[position].listData)
}
is VerticalViewHolder -> {
holder.bind(dataList[position].data)
}
}
}
7.MainActivity的代码
class MainActivity : AppCompatActivity() { //RecycleView 数据 private val mDataList = ArrayList<MultiItem>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) //add hor mDataList.add(MultiItem(1, listData = listOf( DateMessage(title = "1RecycleView实现首页复杂布局效果(横向和竖向)…", desc = "05-04 15:20 | 9999阅", image = R.drawable.ic_launcher_background), DateMessage(title = "2RecycleView实现首页复杂布局效果(横向和竖向)…", desc = "05-04 15:20 | 9999阅", image = R.drawable.ic_launcher_background), DateMessage(title = "11RecycleView实现首页复杂布局效果(横向和竖向)…", desc = "05-04 15:20 | 9999阅", image = R.drawable.ic_launcher_background), ))) //add ver repeat(10){ mDataList.add(MultiItem(1, data = DateMessage(title = "${it}RecycleView实现首页复杂布局效果(横向和竖向)…", desc = "05-04 15:20 | 9999阅", image = R.drawable.ic_launcher_background))) } val recyclerview = findViewById<RecyclerView>(R.id.mainRecycleView) recyclerview.layoutManager = LinearLayoutManager(this) recyclerview.adapter = HeadRefactorAdapter(mDataList) }
你没有看错,当你把前面的准备好了,其实主代码不多。
这里解释下,MultiItem的第一个参数就是item,用来区分数据
mDataList.add(MultiItem(1, listData = listOf(
DateMessage(title = “1RecycleView实现首页复杂布局效果(横向和竖向)…”, desc = “05-04 15:20 | 9999阅”, image = R.drawable.ic_launcher_background),
DateMessage(title = “2RecycleView实现首页复杂布局效果(横向和竖向)…”, desc = “05-04 15:20 | 9999阅”, image = R.drawable.ic_launcher_background),
DateMessage(title = “11RecycleView实现首页复杂布局效果(横向和竖向)…”, desc = “05-04 15:20 | 9999阅”, image = R.drawable.ic_launcher_background),
最后祝大家周末快乐!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。