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子條目的點擊事件萧求。
注意:
- 如果你加載的是圖片,并且使用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的分割線