Kotlin+RecyclerView实现切换fragment

最近学习kotlin,拿了以前的一个小dome来练手,话不多说,给大家看下效果

左边是一个动态添加的RecyclerView,右边是一个fragment,点击左边的新闻title,可以切换右边的title以及内容

一起来看看用kotlin如何实现吧

首页布局如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">



    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent"/>
    <View
        android:background="#999999"
        android:layout_width="0.5dp"
        android:layout_height="match_parent">

    </View>
    <FrameLayout
        android:id="@+id/right_layout"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3">

    </FrameLayout>

</LinearLayout>

布局非常简单,相信不用我多说了,然后是

实体类

package com.example.tiantian_master
data  class News(var title:String, var content:String )

大家可以看到 kotlin的代码非常简洁,一个data就实现了toString,get,set等方法,

调用适配器

 
        recycler.layoutManager = LinearLayoutManager(this)
        val adapter = NewsAdapter(list)
        recycler.adapter =  adapter

找到recyclerView并设置layoutManager与他的适配器

使用kotlin无需再使用findViewbyid,可以通过view的id,拿来就能用,kotlin抛弃了new关键字,使代码更加简洁

加上假数据

 private fun initDate(){
        for (num in 1 ..10)
            list.add(News("新闻$num", "震惊$num"))
    }

 

适配器部分

 

class NewsAdapter(private val list: List<News>) :
    RecyclerView.Adapter<NewsAdapter.NewsViewHolder>() {
    
    class NewsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        val view = itemView
    }

新建NewsAdapter类,注意是Kotlin Class,并继承RecyclerView.Adapter,泛型使用内部类NewsViewHolder

(private val list: List<News>)是一个主构造函数,list值可以在当前类全局使用

 重写以下三个方法

onCreateViewHolder
getItemCount
onBindViewHolder

//如有返回值且只有一行代码可省略 :NewsViewHolder{}
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = NewsViewHolder(
            LayoutInflater.from(parent.context).inflate(
                R.layout.item_lefyrecyvler,//新闻标题item
                parent,
                false
            )
        )

    override fun getItemCount()=list.size //: Int可省略


    override fun onBindViewHolder(holder: NewsViewHolder, position: Int) {
//kotlin可直接用id获取view组件
        holder.view.title.text = list[position].title
    }

到此适配器就完成了,运行项目

是不是感觉缺了点什么,没错,点击事件,好吧继续写

 interface OnItemClickListener {
        fun OnItemClick(view: View, position: Int)
    }

在适配器中定义一个接口,接口中定义一个OnItemClick方法,设置两项参数,一个是View,一个是position

    private lateinit var onClick: OnItemClickListener
    fun setOnItemClick(onItemClickListener: OnItemClickListener) {
        this.onClick = onItemClickListener

    }

定义全局变量,实现set方法,和java没啥两样

大家可能会疑惑lateinit 有什么用呢

大家应该知道,在kotlin中声明一个可为空的变量的时候,必须在类型后加 ? 标识符,如下

    private var onClick: OnItemClickListener?=null

而lateinit关键字,他告诉编译器这个变量会被初始化,并且不会为null,但是在声明这里,并且还不知道什么时候会被初始化。

具体可以去https://www.jianshu.com/p/24fdd70fdbce?utm_source=oschina-app了解

接下来在  onBindViewHold 中实现点击事件

        holder.view.setOnClickListener { onClick.OnItemClick(holder.view, position) }

到此为止左边的title就已经完成了

再来看看右边fragment

首先是布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv_title"
        android:text="title"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center">

    </TextView>
    <TextView
        android:text="centent"
        android:id="@+id/tv_content"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </TextView>

</LinearLayout>

很简单,只有标题和内容

再创建一个RightFrgment继承Fragment

package com.example.tiantian_master

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.rightfragment.view.*

class RightFragment(val news: News) : Fragment() {
     override fun onCreateView(
         inflater: LayoutInflater,
         container: ViewGroup?,
         savedInstanceState: Bundle?
     ): View? {
         val view = inflater.inflate(R.layout.rightfragment,container,false)
         view.tv_title.text = news.title
         view.tv_content.text = news.content
         return view
     }

}

重新onCreateView方法,加载新闻,返回自定义的layout即可

Activity中点击事件的使用

adapter.setOnItemClick(object : NewsAdapter.OnItemClickListener {
            override fun OnItemClick(view: View, position: Int) {
                replaceFragment(RightFragment(list[position]))
            }
        })
 private  fun replaceFragment( fragment:Fragment){
        val transaction = supportFragmentManager.beginTransaction()
        transaction.replace(R.id.right_layout,fragment)
        transaction.commit()//提交
    }

replaceFragment用于切换fragment

到此为止,该项目所有功能都已经实现了最后附上完整的activity代码

package com.example.tiantian_master

import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.myapplication.adapter.NewsAdapter
import kotlinx.android.synthetic.main.activity_main.*


class MainActivity : AppCompatActivity(){
    var list  = ArrayList<News>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initDate()
        recycler.layoutManager = LinearLayoutManager(this)
        val adapter = NewsAdapter(list)
        recycler.adapter =  adapter
        adapter.setOnItemClick(object : NewsAdapter.OnItemClickListener {
            override fun OnItemClick(view: View, position: Int) {
                replaceFragment(RightFragment(list[position]))
            }
        })

    }

    private fun initDate(){
        for (num in 1 ..10)
            list.add(News("新闻$num", "震惊$num"))
    }
    private  fun replaceFragment( fragment:Fragment){
        val transaction = supportFragmentManager.beginTransaction()
        transaction.replace(R.id.right_layout,fragment)
        transaction.commit()
    }
}








我的邮箱 2503360639@qq.com

水平有限,如果有错请指出

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值