之前定義的刷新控件在使用的時候,基本等同於RecyclerView的使用,對於刷新操作只是增加了一個加載數據的回調罷了,因而本篇說是之前刷新控件的使用,大部分內容還是RecyclerView的使用。
舊機寶的“設備頁”打算分爲三種佈局,從上到下依次是一個查詢bar,一個輪播的banner,還有每行兩列的設備列表。
第一步:在佈局中使用自定義刷新控件
<wang.buxiang.wheel.widget.refresh.RefreshLayout
android:id="@+id/refreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
</wang.buxiang.wheel.widget.refresh.RefreshLayout>
第二步:繼承之前的自定義Adapter,實現數據適配
首頁共有三種佈局,搜索框、輪播橫幅、設備項,至於最後的一項“沒有更多數據”則是封裝的刷新控件自動添加的,並不需要我們關心。
enum class ViewType{
SEARCH,BANNER,DEVICE
}
對於搜索框可以就是一個圖片,而Banner則需要通過一個ViewPager來實現,之前說過viewpager的fragment專用adapter,這次則是用到更普適的PagerAdapter。首先是保存數據的變量們
private var phoneDevices=ArrayList<PhoneDevice>()
private var banners= ArrayList<Int>()
internal var bannerViewPager: ViewPager? = null
banner中的數據是保存在本地的,直接在init中添加數據。
init {
banners.add(R.drawable.ic_banner_how_to_use)
banners.add(R.drawable.ic_banner_need)
banners.add(R.drawable.ic_banner_feedback)
}
定義更新adapter數據的方法,主要是存在變動的“設備項”,下拉刷臉的回調會用到setData方法,重置數據。而上劃加載更多則用到addData方法,用於在現有數據基礎之上添加數據。notifyDataSetChanged()則是要求adapter更新數據。
fun setData(phoneDeviceList: ArrayList<PhoneDevice>) {
phoneDevices = phoneDeviceList
notifyDataSetChanged()
}
fun addData(phoneDeviceList: ArrayList<PhoneDevice>) {
phoneDevices .addAll(phoneDeviceList)
notifyDataSetChanged()
}
定義三個內部類,繼承ViewHolder,這是recyclerview特有的機制,用於提高性能。這三個用於hold每個item佈局的控件們。
internal inner class DeviceViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var img_icon: ImageView = itemView.findViewById(R.id.img_icon)
var tv_name: TextView = itemView.findViewById(R.id.tv_name)
var bt_init: Button = itemView.findViewById(R.id.bt_choose)
}
internal inner class SearchViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var tv_serach: TextView = itemView.findViewById(R.id.tv_search)
}
internal inner class BannerViewHoler(itemView: View) : RecyclerView.ViewHolder(itemView) {
var viewPager: ViewPager = itemView.findViewById(R.id.viewPager)
}
根據位置不同,返回不同的viewtype,這裏第一行是搜索框,第二行是banner,剩下的都是設備項。
override fun myGetItemViewType(position: Int): Int {
return when(position){
0-> ViewType.SEARCH.ordinal
1->ViewType.BANNER.ordinal
else ->ViewType.DEVICE.ordinal
}
}
根據viewtype的不同,用各自的佈局創建各自的viewholder並返回
override fun myOnCreateViewHolder(viewGroup: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when(viewType){
ViewType.SEARCH.ordinal-> SearchViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.item_function_search, null))
ViewType.BANNER.ordinal->BannerViewHoler(LayoutInflater.from(viewGroup.context).inflate(R.layout.item_function_banner, null))
else-> DeviceViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.item_device, null))
}
}
依據viewtype的不同,使用返回的不同的viewholder來填充數據。
override fun myOnBindViewHolder(viewHolder: RecyclerView.ViewHolder, position: Int, viewType: Int) {
when(viewType){
ViewType.SEARCH.ordinal->{
(viewHolder as SearchViewHolder).tv_serach.setOnClickListener {
// fragment.context?.startActivity(Intent(fragment.context, SearchActivity::class.java))
}
}
ViewType.BANNER.ordinal->{
}
else->{
val phoneDevice = phoneDevices[position-2]
(viewHolder as DeviceViewHolder).tv_name.text = phoneDevice.nickName
}
}
}
最後別忘了,返回當前adapter的總數據條目
override fun myGetItemCount(): Int {
return phoneDevices.size+2
}
設備項的數據條數,加上一條搜索框,加上一條banner,一共多加2條。
第三步:爲刷新控件設置adapter,並設置數據加載回調
新建剛纔自定義的adapter
val adapter=MyDeviceAdapter(this)
refreshLayout.setAdapter(adapter)
之前說過,recyclerview的顯示格式是由layoutmanager來實現的,經常不需要修改,這裏就需要進行修改了,根據之前的設計,整個頁面包括一行搜索框、一行banner,剩下的都是每行兩列的設備項數據,LinearManager只能實現單列布局顯然不符合要求。這裏使用GridLayoutManager來實現當前需求,我們要求數據以兩列的網格佈局進行排列,但是第一、二、最後一列要求每個數據對應的視圖佔據兩列,在兩列的網格中就是佔據一行的效果了,從而達到我們的目的。
val layoutManager=GridLayoutManager(context,2)
layoutManager.spanSizeLookup=object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
return when(position){
0,1,adapter.myGetItemCount()->2
else->1
}
}
}
refreshLayout.setLayoutManager(layoutManager)
最後要爲刷新控件加上數據加載的回調,並在回調中進行adapter中數據的設置或添加
refreshLayout.onLoadDataListener=object :OnLoadDataListener{
override fun refresh(refreshLayout: RefreshLayout) {
refreshLayout.finishLoad()
}
override fun loadMore(refreshLayout: RefreshLayout) {
var devicesList= ArrayList<PhoneDevice>()
devicesList.add(PhoneDevice().apply { nickName="哈哈" })
devicesList.add(PhoneDevice().apply { nickName="測試" })
devicesList.add(PhoneDevice().apply { nickName="機器" })
devicesList.add(PhoneDevice().apply { nickName="不錯" })
adapter.addData(devicesList)
}
}
運行,效果就出來了。