MoreType
new method to build data in RecyclerView with Kotlin!
Click icon download lastest sample
Github: github.com/Werb/MoreTy…
關鍵詞:【資料驅動檢視】
之前在寫公司的專案的時候,需要寫大量的介面,這就意味著每一個介面都要寫一個 Adapter,同時還要對不同的檢視根據 getItemViewType() 寫不同的 ViewHolder,在存在多種檢視的時候,一個 Adapter 中的程式碼就會很冗餘,而且耦合度很高,對後續的修改很不友好。
我們任意一個介面都是依靠伺服器返回的資料構建的,所以我就在想,能不能簡單的使用資料來驅動檢視,這就也是 MoreType 的核心所在【資料驅動檢視】。
我並不是第一個想到這個概念的人,我最早看到這個概念的實踐,是 drakeet 的 MultiType 。當時看完他的專案之後,有一種醍醐灌頂的暢快,這就是我所希望的【資料驅動檢視】。
大概在一個月前,開始接觸 Kotlin,Kotlin 是一個讓開發者用起來很爽的語言,不必深陷煩人的空指標異常,簡潔的程式碼風格,在初次嘗時候我就喜歡上了它,所以我決定用 Kotlin 來開發一個【資料驅動檢視】的第三方庫,從而就有了 MoreType 的產生【給你更多的可能】。
目前 MoreType 仍在開發,當前版本為 0.1.0-beta 版本,因為是基於 AS Preview 開發的,可能會有一些未知的 Bug
Release 版本將會在這個月底釋出.
Preview
Dependency
compile 'com.werb.moretype:moretype:0.1.0-beta'複製程式碼
or
implementation 'com.werb.moretype:moretype:0.1.0-beta'複製程式碼
Usage
Keyword: 【資料驅動檢視】
Step 1. 建立一個資料模型類,例如:
data class SingleText(val title: String, val desc: String, val url: String)複製程式碼
or
class SingleText {
var title: String? = null
var desc: String? = null
var url: String? = null
}複製程式碼
Step 2. 建立一個類 xxxViewType 繼承抽象類 MoreViewType<T : Any>()
例如:
import kotlinx.android.synthetic.main.item_view_single_type_one.view.*
class SingleTypeOneViewType: MoreViewType<SingleText>() {
override fun getViewLayout(): Int = R.layout.item_view_single_type_one
override fun getViewModel(): KClass<SingleText> = SingleText::class
override fun bindData(data: SingleText, holder: MoreViewHolder) {
holder.itemView.title.text = data.title
holder.itemView.desc.text = data.desc
holder.itemView.icon.setImageURI(data.url)
}
}複製程式碼
使用 kotlin-android-extensions
替代 findViewById()
- getViewLayout():返回檢視的 layout
- getViewModel():返回檢視所對應的資料模型 data::class
- bindData(): 繫結資料,處理點選等
Step 3. 在使用 RecyclerView
的地方,宣告 MoreAdapter()
物件,register
需要的 viewType
,同時和 RecyclerView
繫結
import kotlinx.android.synthetic.main.activity_single_register.*
class SingleRegisterActivity: AppCompatActivity() {
private val adapter = MoreAdapter()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_single_register)
list.layoutManager = LinearLayoutManager(this)
/* register viewType and attach to recyclerView */
adapter.register(TitleViewType())
.register(SingleTypeOneViewType())
.attachTo(list)
/* load any data List or model object */
adapter.loadData(DataServer.getSingleRegisterData())
}
}複製程式碼
使用 kotlin-android-extensions
替代 findViewById()
完成這三步,一個根據【資料驅動檢視】的列表就已經構建完成。
Feature
Multi Register: Register one2more ViewType
通常我們的資料和檢視是一對一的關係,比如瀑布流。MoreType 同時提供一種資料型別對應多種檢視的情況,例如私信介面。
adapter.register(TitleViewType())
.multiRegister(Message::class, object : MultiLink<Message> {
override fun link(data: Message): MoreViewType<Message>? {
if (data.me) {
return MessageOutViewType()
} else {
return MessageInViewType()
}
}
})
.attachTo(multi_register_list)複製程式碼
Multi Register 必須顯式宣告 Data::class
Animation: Provides five types of Animation
提供五種動畫支援: Alpha , Scale , SlideInBottom , SlideInLeft , SlideInRight
adapter.register(TitleViewType())
.register(AnimViewType())
/* assign Animation */
.renderWithAnimation(AlphaAnimation())
/* set Animation start position in list */
.startAnimPosition(1)
/* set is always show animation or show in first display */
.firstShowAnim(true)
.attachTo(anim_list)複製程式碼
同時支援自定義動畫, 建立一個類實現介面 MoreAnimation
and 重寫 getItemAnimators(view: View)
例如:
class SlideInLeftAnimation : MoreAnimation {
override fun getItemAnimators(view: View): Array<Animator>{
return arrayOf(ObjectAnimator.ofFloat(view, "translationX", -view.rootView.width.toFloat(), 0f))
}
}複製程式碼
ItemClick: Support onItemClick and onItemLongClick
兩種方式實現點選事件: In ViewType and In Activity
In ViewType 中處理點選事件 : 在viewType中使用 view.setOnClickListener {}
In Activity 中處理點選事件 :
- 在 viewType 中使用
holder.addOnClickListener(view: View)
orholder.addOnClickListener(viewId: Int)
繫結點選事件 - 在 Activity 中通過
viewType().setMoreClickListener()
處理點選事件
Refresh and loadMore
Refresh: 使用 SwipeRefreshLayout
就可以實現下拉重新整理
LoadMore: 通過構建 Footer.class
和 FootViewType
實現資料和檢視的繫結, 當 RecyclerView 滾動在底部時顯示 FootViewType
,在資料請求成功後移除 FootViewType
全域性 ViewType
在自定義 Application中註冊全域性 ViewType
class MyApp: Application() {
companion object {
@Volatile lateinit var myApp: MyApp
private set
}
override fun onCreate() {
super.onCreate()
myApp = this
// Sole Global Register, like footer , Cutting line
MoreType.soleRegister(FoorViewType())
}
}複製程式碼
通過 adapter.userSoleRegister()
呼叫使用全域性 ViewType