kotlinTouchHelperDemo
其實在一個月前就想寫個kotlin的Demo,想在kotlin成為Android的主流開發語言之前學習學習它.
但是中間一直沒有時間,正好這幾天Google I/O大會,Kotlin都上熱搜了,我利用下班后的時間將寫的kotlin例子來和大家分享下,讓大家感受感受這門神奇的語言.
kotlin
來,先貼上官方對于這門語言的介紹以及官方為何放棄Java而最終選擇kotlin
- Kotlin 介紹
- Kotlin是一個基于JVM 實現的靜態語言. Kotlin是IntelliJ公司創造并在持續維護這門語言.
- 優點
- 幫你減少實現同一個功能的代碼量.
- 讓你的代碼更容易閱讀,同時易于理解.
- 移除了你可能會犯錯誤的功能.
- 基于 JVM 和 Javascript,你可以在很多地方運行.
- Kotlin 和 Java 可以相互調用 .
- 為何放棄Java
- 兼容性問題 (Java 7 只支持 API 19 及以上,以及AndroidStudio對于Java 8的新特性支持遲遲沒有完善)
- Java 存在問題
a. 空引用 : 不論你費多大的功夫,你都無法避免它.因為 Java 的類型系統就是不安全的 .
b. 原始類型 : 我們在開發的時候總是會為了保持兼容性而卡在范型原始類型的問題上,我們都知道要努力避免 raw type 的警告,但是它們畢竟是在語言層面上的存在,這必定會造成誤解和不安全因素.
c. 協變數組 : 你可以創建一個 string 類型的數組和一個 object 型的數組,然后把 string 數組分配給 object 數組.這樣的代碼可以通過編譯,但是一旦你嘗試在運行時分配一個數給那個數組的時候,他就會在運行時拋出異常.
d. Java 8 存在高階方法 : 但是他們是通過 SAM 類型 實現的.SAM 是一個單個抽象方法,每個函數類型都需要一個對應的接口.如果你想要創建一個并不存在的 lambda 的時候或者不存著對應的函數類型的時候,
你要自己去創建函數類型作為接口.
e. 泛型中的通配符 : 詭異的泛型總是難以操作,難以閱讀,書寫,以及理解. 對編譯器而言,異常檢查也變得很困難.
- 為何選擇Kotlin
- 對于上面Java存在的問題 很好的解決了.
- 添加新特性
a. Lambda 表達式 (Java8 才有)
b. 數據類
c. 函數字面量和內聯函數
d. 函數擴展
e. 空安全
f. 智能轉換
g. 字符串模板
h. 類委托
i. 類型推斷
j. 聲明點變量
k. 區間表達式
...
簡單介紹完了kotlin,說下小編對于這門新語言的感受吧 -- 嗨到不行!
kotlin 在Android Studio 中的使用。
在最新版的AS3.0中將可以直接使用Kotlin作為開發語言,但是3.0之前版本則需要通過安裝kotlin的插件來進行配置并使用kotlin。
下面我將通過一個功能實現,來帶大家看下kotlin的代碼.
列表拖拽重新排序 + 滑動刪除實現原理
簡述原理:主要通過使用recyclerview 提供的ItemTouchHelper 來實現效果。
-
app/build.gradle 配置 (此處我用的recyclerview版本是25.3.1,可以選擇其他版本)
compile 'com.android.support:recyclerview-v7:25.3.1'
-
RecyclerView.Adapter中使用ItemTouchHelper詳解:
-
ItemTouchHelper.Callback 來實現用戶手勢的控制以及數據的操作
- getMovementFlags : 通過調用 getMovementFlags,告訴RecyclerView可以實現的手勢類型
- onMove : 拖拽時回調的方法,返回值決定是否可以長按拖拽
- onSwiped : 左右滑動到滿足刪除時的回調方法,可以此處執行刪除數據
- isLongPressDragEnabled : 是否可以長摁拖拽
- isItemViewSwipeEnabled : 是否可以滑動刪除
- onSelectedChanged :狀態改變回調方法,可以在此處用于更換圖片背景。
- clearView :拖動完成回調方法,此處用于更換圖片背景
上面只是簡單的對于函數的介紹,詳細的操作在下面的代碼中可以了解到。//kotlin 如果內部類需要訪問外部類數據 則要聲明為inner inner class ItemDragHelperCallback : ItemTouchHelper.Callback() { /** * 獲取可以拖動的方向標志 * */ override fun getMovementFlags(recyclerView: RecyclerView?, viewHolder: RecyclerView.ViewHolder?): Int { //此處返回可以拖動的方向值 var swipe = 0 var move = 0 //此處為 假設recyclerview 不為空 recyclerView?.let { if (recyclerView.layoutManager is GridLayoutManager) { //如果是網格型 則可以左右上下都可以拖動 move = ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT } else if (recyclerView.layoutManager is LinearLayoutManager) { //支持上下拖動 move = ItemTouchHelper.UP or ItemTouchHelper.DOWN //左右滑動刪除 swipe = ItemTouchHelper.START or ItemTouchHelper.END } } return ItemTouchHelper.Callback.makeMovementFlags(move, swipe) } override fun onMove(recyclerView: RecyclerView?, viewHolder: RecyclerView.ViewHolder?, target: RecyclerView.ViewHolder?): Boolean { //此處的返回值 決定是否可以拖動 if (viewHolder != null && target != null) { //此處不讓標題來進行拖動效果 也就是拖動時 標題不會動 if (viewHolder.itemViewType == TYPE_TITLE || target.itemViewType == TYPE_TITLE) { return false } val fromPos = viewHolder.adapterPosition val toPos = target.adapterPosition //此處為mData不為空時 mData?.let { val from = mData[fromPos] mData.removeAt(fromPos) mData.add(toPos, from) //執行交換動畫 notifyItemMoved(fromPos, toPos) return true } } //默認不讓拖動 return false } override fun onSwiped(viewHolder: RecyclerView.ViewHolder?, direction: Int) { //用于執行滑動刪除 } //不重寫默認是返回true的 如果返回false的話 需要使用ItemTouchHelper的實例方法 //使用 startDrag 來執行拖拽 //使用 startSwipe 來執行滑動刪除 override fun isLongPressDragEnabled(): Boolean { return true } //是否支持滑動功能 override fun isItemViewSwipeEnabled(): Boolean { return true } /** * 此處用于狀態變化時 更換圖片狀態 * */ override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) { super.onSelectedChanged(viewHolder, actionState) if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) { //顯示遮罩 viewHolder?.let { if (viewHolder is ItemViewHolder) { viewHolder.mShadow!!.visibility = View.VISIBLE } } } } /** * 此處當拖拽完成 * */ override fun clearView(recyclerView: RecyclerView?, viewHolder: RecyclerView.ViewHolder?) { super.clearView(recyclerView, viewHolder) //隱藏遮罩 viewHolder?.let { if (viewHolder is ItemViewHolder) { viewHolder.mShadow!!.visibility = View.GONE } } } }
- getMovementFlags : 通過調用 getMovementFlags,告訴RecyclerView可以實現的手勢類型
ItemTouchHelper 當需要自定義條件才執行拖拽或者滑動刪除,則可以使用startDrag、startSwipe來主動調用開始拖拽與滑動,并isLongPressDragEnabled與 isItemViewSwipeEnabled返回false。
//開始執行滑動 ItemTouchHelper.startSwipe(RecyclerView.ViewHolder) //開始執行拖拽 ItemTouchHelper.startDrag(RecyclerView.ViewHolder)
- ItemTouchHelper.attachToRecyclerView 當一切設置好了,則調用此方法設置到RecyclerView中。
//將recyclerView依附到觸摸輔助類 open fun attachiToRecyclerView(recyclerView: RecyclerView) { if (mItemTouchHelper != null && recyclerView != null) { mItemTouchHelper.attachToRecyclerView(recyclerView) } }
-
效果圖
給各位客官奉上Github地址:
https://github.com/Nichooool/kotlinTouchHelperDemo
↓↓↓↓↓↓↓↓如果覺得可以的話,請點擊下面的喜歡。或者打賞哦,我不會驕傲的。↓↓↓↓↓↓↓↓