RecyclerView之簡單使用

1,添加依賴

在Project的build.gradle中添加

buildscript {
    ext.kotlin_version = '1.1.2-4'

    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

在app->build.gradle最上面添加

apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

在app->build.gradle->dependencies中添加

compile 'com.android.support:design:25.3.1'
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"

因為我使用的是Kotlin來進(jìn)行代碼編寫场勤,因此在這里要進(jìn)行Kotlin配置辖源。如果不使用Kotlin那么只需要配置design就可以了柱衔。

2驮瞧,RecyclerView的初步使用

2.1,首先我們用RecyclerView來實現(xiàn)一下ListView加載數(shù)據(jù)列表的頁面效果作煌,如圖所示:

2.1.1梗顺,整體XML布局文件:
<android.support.design.widget.CoordinatorLayout    
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto" 
      android:id="@+id/activity_kotlin1st" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:orientation="vertical"> 

      <android.support.v7.widget.RecyclerView 
            android:layout_width="match_parent" 
            android:layout_height="match_parent" 
            android:id="@+id/rc"/>
</android.support.design.widget.CoordinatorLayout>
2.1.2,RecyclerView的Adapter實現(xiàn):
class Kotlin1stAdapter(var context: Context, var items: List<String>):RecyclerView.Adapter<Kotlin1stAdapter.ViewHolder>(){
      override fun onBindViewHolder(holder: ViewHolder, position: Int) { 
          holder.tv.text = items[position] 
          holder.itemView.tag= position
     } 

      override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
         val view = LayoutInflater.from(context).inflate(R.layout.item_rc_1st, parent, false)
         return ViewHolder(view as TextView) 
     }

      override fun getItemCount(): Int=items.size 

      class ViewHolder(itemTv: TextView):RecyclerView.ViewHolder(itemTv){ 
            var tv: TextView = itemTv.findViewById(R.id.tv)as TextView 
      }
}
2.1.3车摄,Activity中代碼實現(xiàn):
class Kotlin1stActivity : AppCompatActivity() {
        private val itemList= listOf("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o") 
        private val rcAdapter=Kotlin1stAdapter(this, itemList) 

        override fun  onCreate(savedInstanceState: Bundle?) {
                super.onCreate(savedInstanceState)
                setContentView(R.layout.activity_kotlin1st) 
                initDatas()
        }
 
        fun initDatas(){
                 /** 
                    * LinearLayoutManager(Context context, int orientation, boolean reverseLayout) 
                    * orientation:方向 
                    * reverseLayout:ture 表示數(shù)據(jù)從底部開始一直向上 
                    */ 
                rc.layoutManager=LinearLayoutManager(this,LinearLayoutManager.VERTICAL, false)
                rc.adapter = rcAdapter  
        }
}

這樣就簡單的實現(xiàn)了上圖的效果,可以看出子條目間沒有分割線寺谤,那么分割線該怎么添加呢,通過下面這句代碼:
rc.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))

效果圖如下:


2.2吮播,LayoutManager的使用

LayoutManager是RecyclerView下的一個抽象類变屁,用來設(shè)置RecyclerView的顯示方式,它有三種實現(xiàn)類:

  • LinearLayoutManager 線性管理器意狠,支持橫向粟关、縱向
  • GridLayoutManager 網(wǎng)格布局管理器
  • StaggeredGridLayoutManager 瀑布流式布局管理器

上面我們用LinearLayoutManager 來顯示數(shù)據(jù),那么下面我們換另外兩種來看看效果

2.2.1环戈,使用GridLayoutManager 來顯示:
        // rc.layoutManager=LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
        /** 
          * GridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) 
          * orientation:方向 
          * spanCount:列數(shù) 
          * reverseLayout:ture 表示數(shù)據(jù)從底部開始一直向上 
          */
        rc.layoutManager= GridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false) as RecyclerView.LayoutManager?

效果圖如下:


將顯示方向設(shè)置為HORIZONTAL闷板,將第四個參數(shù)設(shè)置為true時:

        rc.layoutManager= GridLayoutManager(this, 3, GridLayoutManager.HORIZONTAL, true) as RecyclerView.LayoutManager?

效果如下:


2.2.2,使用StaggeredGridLayoutManager 來顯示:
          /** 
            * StaggeredGridLayoutManager(int spanCount, int orientation) 
            * orientation:方向 
            * spanCount:列數(shù) 
            */
           rc.layoutManager= StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL) as RecyclerView.LayoutManager?

效果圖如下(因為長寬設(shè)置一樣的院塞,因此看起來和GridLayoutManagerx效果一樣):


設(shè)置高度為隨機(jī)高度遮晚,在Adapter中進(jìn)行,代碼:

        var heights = ArrayList<Int>()
        init { 
                for (i in 0..items.size){ 
                        heights.add((100 + 300 * Math.random()).toInt()) 
                }
        }
        override fun onBindViewHolder(holder: ViewHolder, position: Int) { 
                val lp = holder.tv.layoutParams lp.height = heights[position] 
                holder.tv.layoutParams = lp 

                holder.tv.text = items[position] 
                holder.itemView.tag= position
        }

效果圖為:


2.3拦止,RecyclerView的子條目點擊事件

RecyclerView并沒有給我們提供子條目的點擊事件县遣,那么我們只有自己動手來實現(xiàn)點擊事件,還是在Adapter中進(jìn)行處理汹族,代碼為:

class Kotlin1stAdapter(var context: Context, var items: List<String>):RecyclerView.Adapter<Kotlin1stAdapter.ViewHolder>(){ 
        var heights = ArrayList<Int>() 
        init { 
                for (i in 0..items.size){ 
                      heights.add((100 + 300 * Math.random()).toInt()) 
                }
         } 

        override fun onBindViewHolder(holder: ViewHolder, position: Int) { 
                val lp = holder.tv.layoutParams 
                lp.height = heights[position] 
                holder.tv.layoutParams = lp 
                holder.tv.text = items[position] 
                holder.itemView.tag= position 
        } 

        override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
                val view = LayoutInflater.from(context).inflate(R.layout.item_rc_1st, parent, false)
                view.setOnClickListener { view -> listener?.onItemClick(view, view.tag as Int)}
                return ViewHolder(view as TextView)
         } 

        override fun getItemCount(): Int=items.size 

        class ViewHolder(itemTv: TextView):RecyclerView.ViewHolder(itemTv){ 
                var tv: TextView = itemTv.findViewById(R.id.tv)as TextView
        }

        private var listener: OnItemClickListener?=null 

        fun setOnItemClickListener(l: OnItemClickListener): Unit{ this.listener = l } 

        interface OnItemClickListener{ 
                fun onItemClick(view: View, pos: Int)
         }
}

在2.1.3代碼中添加:

               rcAdapter.setOnItemClickListener(object :Kotlin1stAdapter.OnItemClickListener{
                       override fun onItemClick(view: View, pos: Int) { 
                              Log.e("OnItemClickListener", "pos--> "+ pos)
                       }
               })

這樣就實現(xiàn)了RecyclerView子條目的點擊事件萧求。

注意:

  1. 如果你加載的是圖片,并且使用Glide來進(jìn)行圖片顯示顶瞒,那么上面的代碼會出現(xiàn)
    錯誤提示:You must not call setTag() on a view Glide is targeting
    錯誤原因:View使用setTag后導(dǎo)致Glide之前請求的標(biāo)記被清除夸政,強(qiáng)制轉(zhuǎn)換過程中不能將你給定的類型判斷為Request類型所致。
    Glide源碼中報錯代碼為:
public Request getRequest() {
    Object tag = getTag();
    Request request = null;
    if (tag != null) {
        if (tag instanceof Request) {
            request = (Request) tag;
        } else {
            throw new IllegalArgumentException("You must not call setTag() on a view Glide is targeting");
        }
    }
    return request;
}
 使用`holder.itemView.tag=position `后搁拙,在源碼中`Object tag = getTag() ` 得到tag并不是`Request`類型
 解決辦法:新建`ids.xml`文件秒梳,代碼:
<resources>
    <item name="glide_id" type="id"/>
</resources>

在Adapter中的onBindViewHolder方法中法绵,將設(shè)置tag語句:
holder.itemView.tag= position改為holder.itemView.setTag(R.id.glide_id, position)
在Adapter中的onCreateViewHolder方法中,將獲取tag語句:
view.tag改為 view.getTag(R.id.glide_id)
在此運行程序酪碘,問題解決

關(guān)于RecyclerView第一篇先寫到這里朋譬,第二篇寫RecyclerView的分割線

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市兴垦,隨后出現(xiàn)的幾起案子徙赢,更是在濱河造成了極大的恐慌,老刑警劉巖探越,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狡赐,死亡現(xiàn)場離奇詭異,居然都是意外死亡钦幔,警方通過查閱死者的電腦和手機(jī)枕屉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鲤氢,“玉大人搀擂,你說我怎么就攤上這事【碛瘢” “怎么了哨颂?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長相种。 經(jīng)常有香客問我威恼,道長,這世上最難降的妖魔是什么寝并? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任箫措,我火速辦了婚禮,結(jié)果婚禮上食茎,老公的妹妹穿的比我還像新娘蒂破。我一直安慰自己,他們只是感情好别渔,可當(dāng)我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布附迷。 她就那樣靜靜地躺著,像睡著了一般哎媚。 火紅的嫁衣襯著肌膚如雪喇伯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天拨与,我揣著相機(jī)與錄音稻据,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛捻悯,可吹牛的內(nèi)容都是我干的匆赃。 我是一名探鬼主播,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼今缚,長吁一口氣:“原來是場噩夢啊……” “哼算柳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起姓言,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤瞬项,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后何荚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體囱淋,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年餐塘,在試婚紗的時候發(fā)現(xiàn)自己被綠了妥衣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡戒傻,死狀恐怖称鳞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情稠鼻,我是刑警寧澤,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布狂票,位于F島的核電站候齿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏闺属。R本人自食惡果不足惜慌盯,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望掂器。 院中可真熱鬧亚皂,春花似錦、人聲如沸国瓮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乃摹。三九已至禁漓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間孵睬,已是汗流浹背播歼。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留掰读,地道東北人秘狞。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓叭莫,卻偏偏與公主長得像,于是被迫代替她去往敵國和親烁试。 傳聞我的和親對象是個殘疾皇子雇初,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,781評論 2 361

推薦閱讀更多精彩內(nèi)容