当前位置:   article > 正文

RecycleView实现首页复杂布局效果(横向和竖向)_recycleview 横向

recycleview 横向

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

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
    }


}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

这里都是适配器的正常步骤,主要讲解下下面这段代码
when (position) {
0 -> {
holder.text5.visibility = View.VISIBLE
holder.imagemap.visibility = View.VISIBLE
}
else -> {
holder.text5.visibility = View.GONE
holder.imagemap.visibility = View.GONE
}

    }
  • 1

这是通过判断数据的数组下标,如果是第一个数据,就让2个控件为显示状态,相当于标识这是第一个数据(达到置顶效果),以后的数据不显示这2个控件。

4.写一个数据类

data class MultiItem(
    //用于标识传入的数据是横向RecycleView还是竖向RecycleView的
    var itemType: Int,
    //横向 rv
    var listData: List<DateMessage>? = null,
    //竖向
    var data: DateMessage? = null
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172

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
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97

这里主要说下 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)
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

你没有看错,当你把前面的准备好了,其实主代码不多。
这里解释下,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),

最后祝大家周末快乐!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/174702?site
推荐阅读
相关标签
  

闽ICP备14008679号