kotlin + 列表拖拽重新排序、滑動進行刪除

kotlinTouchHelperDemo

其實在一個月前就想寫個kotlin的Demo享完,想在kotlin成為Android的主流開發(fā)語言之前學習學習它.
但是中間一直沒有時間灼芭,正好這幾天Google I/O大會,Kotlin都上熱搜了般又,我利用下班后的時間將寫的kotlin例子來和大家分享下彼绷,讓大家感受感受這門神奇的語言.

kotlin

來巍佑,先貼上官方對于這門語言的介紹以及官方為何放棄Java而最終選擇kotlin

  1. Kotlin 介紹
  • Kotlin是一個基于JVM 實現(xiàn)的靜態(tài)語言. Kotlin是IntelliJ公司創(chuàng)造并在持續(xù)維護這門語言.
  1. 優(yōu)點
  • 幫你減少實現(xiàn)同一個功能的代碼量.
  • 讓你的代碼更容易閱讀,同時易于理解.
  • 移除了你可能會犯錯誤的功能.
  • 基于 JVM 和 Javascript寄悯,你可以在很多地方運行.
  • Kotlin 和 Java 可以相互調用 .
  1. 為何放棄Java
  • 兼容性問題 (Java 7 只支持 API 19 及以上萤衰,以及AndroidStudio對于Java 8的新特性支持遲遲沒有完善)
  • Java 存在問題
    a. 空引用 : 不論你費多大的功夫,你都無法避免它.因為 Java 的類型系統(tǒng)就是不安全的 .
    b. 原始類型 : 我們在開發(fā)的時候總是會為了保持兼容性而卡在范型原始類型的問題上猜旬,我們都知道要努力避免 raw type 的警告腻菇,但是它們畢竟是在語言層面上的存在,這必定會造成誤解和不安全因素.
    c. 協(xié)變數(shù)組 : 你可以創(chuàng)建一個 string 類型的數(shù)組和一個 object 型的數(shù)組昔馋,然后把 string 數(shù)組分配給 object 數(shù)組.這樣的代碼可以通過編譯,但是一旦你嘗試在運行時分配一個數(shù)給那個數(shù)組的時候糖耸,他就會在運行時拋出異常.
    d. Java 8 存在高階方法 : 但是他們是通過 SAM 類型 實現(xiàn)的.SAM 是一個單個抽象方法秘遏,每個函數(shù)類型都需要一個對應的接口.如果你想要創(chuàng)建一個并不存在的 lambda 的時候或者不存著對應的函數(shù)類型的時候,
    你要自己去創(chuàng)建函數(shù)類型作為接口.
    e. 泛型中的通配符 : 詭異的泛型總是難以操作嘉竟,難以閱讀邦危,書寫,以及理解. 對編譯器而言舍扰,異常檢查也變得很困難.
  1. 為何選擇Kotlin
  • 對于上面Java存在的問題 很好的解決了.
  • 添加新特性
    a. Lambda 表達式 (Java8 才有)
    b. 數(shù)據(jù)類
    c. 函數(shù)字面量和內聯(lián)函數(shù)
    d. 函數(shù)擴展
    e. 空安全
    f. 智能轉換
    g. 字符串模板
    h. 類委托
    i. 類型推斷
    j. 聲明點變量
    k. 區(qū)間表達式
    ...

簡單介紹完了kotlin倦蚪,說下小編對于這門新語言的感受吧 -- 嗨到不行!

kotlin 在Android Studio 中的使用。

在最新版的AS3.0中將可以直接使用Kotlin作為開發(fā)語言边苹,但是3.0之前版本則需要通過安裝kotlin的插件來進行配置并使用kotlin陵且。

查找插件.png
配置環(huán)境.png

下面我將通過一個功能實現(xiàn),來帶大家看下kotlin的代碼.

列表拖拽重新排序 + 滑動刪除實現(xiàn)原理

簡述原理:主要通過使用recyclerview 提供的ItemTouchHelper 來實現(xiàn)效果个束。

  1. app/build.gradle 配置 (此處我用的recyclerview版本是25.3.1慕购,可以選擇其他版本)

    compile 'com.android.support:recyclerview-v7:25.3.1'
    
  2. RecyclerView.Adapter中使用ItemTouchHelper詳解:

    • ItemTouchHelper.Callback 來實現(xiàn)用戶手勢的控制以及數(shù)據(jù)的操作

      1. getMovementFlags : 通過調用 getMovementFlags,告訴RecyclerView可以實現(xiàn)的手勢類型
      2. onMove : 拖拽時回調的方法茬底,返回值決定是否可以長按拖拽
      3. onSwiped : 左右滑動到滿足刪除時的回調方法沪悲,可以此處執(zhí)行刪除數(shù)據(jù)
      4. isLongPressDragEnabled : 是否可以長摁拖拽
      5. isItemViewSwipeEnabled : 是否可以滑動刪除
      6. onSelectedChanged :狀態(tài)改變回調方法,可以在此處用于更換圖片背景阱表。
      7. clearView :拖動完成回調方法殿如,此處用于更換圖片背景



      上面只是簡單的對于函數(shù)的介紹,詳細的操作在下面的代碼中可以了解到最爬。

      //kotlin 如果內部類需要訪問外部類數(shù)據(jù) 則要聲明為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)
                        //執(zhí)行交換動畫
                        notifyItemMoved(fromPos, toPos)
                        return true
                    }
                }
                //默認不讓拖動
                return false
            }
      
            override fun onSwiped(viewHolder: RecyclerView.ViewHolder?, direction: Int) {
                //用于執(zhí)行滑動刪除
            }
      
            //不重寫默認是返回true的 如果返回false的話 需要使用ItemTouchHelper的實例方法
            //使用 startDrag 來執(zhí)行拖拽
            //使用 startSwipe 來執(zhí)行滑動刪除
            override fun isLongPressDragEnabled(): Boolean {
                return true
            }
      
            //是否支持滑動功能
            override fun isItemViewSwipeEnabled(): Boolean {
                return true
            }
      
            /**
             * 此處用于狀態(tài)變化時 更換圖片狀態(tài)
             * */
            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
                    }
                }
            }
      
        }
      
    • ItemTouchHelper 當需要自定義條件才執(zhí)行拖拽或者滑動刪除涉馁,則可以使用startDrag、startSwipe來主動調用開始拖拽與滑動爱致,并isLongPressDragEnabled與 isItemViewSwipeEnabled返回false谨胞。

    //開始執(zhí)行滑動
    ItemTouchHelper.startSwipe(RecyclerView.ViewHolder)
    //開始執(zhí)行拖拽
    ItemTouchHelper.startDrag(RecyclerView.ViewHolder)
    
    • ItemTouchHelper.attachToRecyclerView 當一切設置好了,則調用此方法設置到RecyclerView中蒜鸡。
     //將recyclerView依附到觸摸輔助類
     open fun attachiToRecyclerView(recyclerView: RecyclerView) {
         if (mItemTouchHelper != null && recyclerView != null) {
             mItemTouchHelper.attachToRecyclerView(recyclerView)
         }
     }
    

效果圖

拖拽重新排序.gif
滑動刪除.gif

給各位客官奉上Github地址:
https://github.com/Nichooool/kotlinTouchHelperDemo
↓↓↓↓↓↓↓↓如果覺得可以的話胯努,請點擊下面的喜歡牢裳。或者打賞哦叶沛,我不會驕傲的蒲讯。↓↓↓↓↓↓↓↓

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末灰署,一起剝皮案震驚了整個濱河市判帮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌溉箕,老刑警劉巖晦墙,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異肴茄,居然都是意外死亡晌畅,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門寡痰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抗楔,“玉大人,你說我怎么就攤上這事拦坠×铮” “怎么了?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵贞滨,是天一觀的道長入热。 經常有香客問我,道長晓铆,這世上最難降的妖魔是什么才顿? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮尤蒿,結果婚禮上郑气,老公的妹妹穿的比我還像新娘。我一直安慰自己腰池,他們只是感情好尾组,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著示弓,像睡著了一般讳侨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奏属,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天跨跨,我揣著相機與錄音,去河邊找鬼。 笑死勇婴,一個胖子當著我的面吹牛忱嘹,可吹牛的內容都是我干的。 我是一名探鬼主播耕渴,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼拘悦,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了橱脸?” 一聲冷哼從身側響起础米,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎添诉,沒想到半個月后屁桑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡栏赴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年蘑斧,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片艾帐。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖盆偿,靈堂內的尸體忽然破棺而出柒爸,到底是詐尸還是另有隱情,我是刑警寧澤捎稚,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站求橄,受9級特大地震影響今野,放射性物質發(fā)生泄漏。R本人自食惡果不足惜罐农,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一条霜、第九天 我趴在偏房一處隱蔽的房頂上張望宰睡。 院中可真熱鬧,春花似錦拆内、人聲如沸宠默。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至肄方,卻和暖如春蹬癌,著一層夾襖步出監(jiān)牢的瞬間权她,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工逝薪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留隅要,地道東北人。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓董济,卻偏偏與公主長得像步清,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子虏肾,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內容