1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 【Android-Kotlin】匿名内部类与Lambda 表达式(附RecycleView监听)

【Android-Kotlin】匿名内部类与Lambda 表达式(附RecycleView监听)

时间:2022-11-26 02:19:54

相关推荐

【Android-Kotlin】匿名内部类与Lambda 表达式(附RecycleView监听)

一:匿名内部类

一个Test类,里面

1)1个属性

2)1个方法

a.该方法传递的参数是一个接口对象,目的是在这个方法中可以通过这个对象来调用接口方法接口对象的接口TestInterFace内部有一个方法test(供其他的对象/类调用)Main函数中,先创建一个Test的对象,并实现这个方法,那我们知道参数内部是一个接口对象,但是呢,这个对象的作用只在这里有用,仅仅起到一个中转站的作用,那我们就可以免去命名,使用匿名内部类({

直接复写功能就好了

})

class Test {var v = "成员属性"fun setInterFace(test: TestInterFace) {test.test()//写法规范,实现时直接复写fun test()就好}}/*** 定义接口*/interface TestInterFace {fun test()}fun main(args: Array<String>) {var test = Test()/*** 采用对象表达式来创建接口对象,即匿名内部类的实例。*/test.setInterFace(object : TestInterFace {override fun test() {println("对象表达式创建匿名内部类的实例")}})}

二.Lambda基础这位作者的返回值写的也很清楚

() -> Unit//表示无参数无返回值的Lambda表达式类型

(T) -> Unit//表示接收一个T类型参数,无返回值的Lambda表达式类型

(T) -> R//表示接收一个T类型参数,返回一个R类型值的Lambda表达式类型

(T, P) -> R//表示接收一个T类型和P类型的参数,返回一个R类型值的Lambda表达式类型

(T, (P,Q) -> S) ->

R//表示接收一个T类型参数和一个接收P、Q类型两个参数并返回一个S类型的值的Lambda表达式类型参数,返回一个R类型值的Lambda表达式类型

三.lambda表达式/匿名函数 1参1返回样例

当然也可以println这个参数测试

1.这段是RecyleView中的一个方法,listener不知道是啥类型,那就写一个lambeda表达式定义函数类型变量

(1参)->Unit,既然是无返回值,那怎么做到类型赋值呢,就类似set方法,函数类型this赋值

2.我们观察发现这个函数对象是没有名字的

//kotlin方法//直接定义函数类型的变量 传入参数,所需的数据类型,无返回值var listener:((itembean:ITEMBEAN)->Unit)?=null//写个方法定义函数fun setMyListener(listener:(itemBean:ITEMBEAN)->Unit){this.listener=listener}

四.Lambda进阶使用

如果需要参数(没有参数可以写()),就在小括号里写明参数类型,参数名可以省略,然后小括号后面加上->{},

->后面如果没有返回值就写Unit(见我们的样例3)

然后在大括号{}里面写上具体的方法实现

作为参数传递给高阶函数的时候,只需要写大括号{}方法体

五.来点夜里猛,lambda表达式结合点击传参【RecycleView点击事件】

刚开始adapter调用,进行lanmbda一参赋值

这边进行初始化,并且设定了listener这个函数型变量

我们点击后,先打印了4444,其次我们listener是赋值了一参的函数,并且这个函数体->println也会一起执行,那就打印了111111,

最后打印33333

六.补充说明

1. java设置点击事件(RecycleView)

1)《第一行代码》中介绍了RV没有setonItemClickListener(),我们可以自己根据需求对子项进行监听即抛去子项点击监听,点击事件右具体的View注册

a. onCreateViewHolder中定义的holder对象,可以setonClickListener监听其内部的任意属性(例如文字或图片)

b. 监听内部复写onClick方法即可

package com.example.recyclerviewtest;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;import java.util.List;public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder>{private List<Fruit> mFruitList;static class ViewHolder extends RecyclerView.ViewHolder {View fruitView;ImageView fruitImage;TextView fruitName;public ViewHolder(View view) {super(view);fruitView = view;fruitImage = (ImageView) view.findViewById(R.id.fruit_image);fruitName = (TextView) view.findViewById(R.id.fruit_name);}}public FruitAdapter(List<Fruit> fruitList) {mFruitList = fruitList;}@Overridepublic ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item, parent, false);final ViewHolder holder = new ViewHolder(view);holder.fruitView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {int position = holder.getAdapterPosition();Fruit fruit = mFruitList.get(position);Toast.makeText(v.getContext(), "you clicked view " + fruit.getName(), Toast.LENGTH_SHORT).show();}});holder.fruitImage.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {int position = holder.getAdapterPosition();Fruit fruit = mFruitList.get(position);Toast.makeText(v.getContext(), "you clicked image " + fruit.getName(), Toast.LENGTH_SHORT).show();}});return holder;}@Overridepublic void onBindViewHolder(ViewHolder holder, int position) {Fruit fruit = mFruitList.get(position);holder.fruitImage.setImageResource(fruit.getImageId());holder.fruitName.setText(fruit.getName());}@Overridepublic int getItemCount() {return mFruitList.size();}}

2.Faraway当中holder只有一个view属性监听方式

1)实现

a. 来到BaseListFragment 里面有个getSpecialAdapter(),我们发现,所有显示条目的fragment,其adapter都是这个的子类

b.进入BaseListAdapter中,进入onBindView可以直接获取每个条目的View,(这里的holder只有一个属性view)那就给这里的itemView进行监听设置,setonClickListener()方法,我们发现其内部实际要传一个匿名类

**public void setOnClickListener(@Nullable OnClickListener l) 我们点开这个匿名内部类,发现他还是个只有一个待实现方法的接口,于是我们可以直接打开这个最深层接口,实现条目点击事件**

3.代码展示

详细说明 条目点击事件

java传递数据做法(定义一个接口,用于和主界面的调用,但耦合高)

1)定义LIstener接口,内部一个方法实现data数据的监听,并制定泛型是传入的泛型,

2)定义setMyListener供主界面交互(拿数据)

3)在itemview的监听中,调用click(data)方法设定数据

kotlin方法(目的是存入,拿到数据,具体见五)

a.定义listener对象是一个传入ITEMBEAN的无返回类型函数对象,

b.同样一个setMylistener取数据

c.监听,比较严格+空校验

c1)?.let

listener?.let { it(data) } 这里的it就是指当前的listener

c2)?.invokelistener?.invoke(data) 就是调用看1参函数进行赋值

d.内部it就代表了listener,传入data(c2好理解)

//所有下拉刷新和上拉加载更多列表界面adapter基类 再添加一个泛型abstract class BaseListAdapter<ITEMBEAN,ITEMVIEW:View> : RecyclerView.Adapter<BaseListAdapter.BaseListHolder>(){//直接复制会报错,因为原HomeHolde这里引用变成HomeAdapter.HomeHolder//add 1.更新数据的操作 刷新操作建立List集合 接收数据private var list=ArrayList<ITEMBEAN>()//用里面的list匿名内部类//在集合中先清空 再添加fun updateList(list: List<ITEMBEAN>?){//传入一个对应集合 到时候侧试一下传原lei还是内部类/*封装后可空判断if (list==null) return */list?.let {this.list.clear()this.list.addAll(list)//牛逼notifyDataSetChanged()//刷新一下}}//上拉加载更多 在集合中添加即可fun loadMore(list: List<ITEMBEAN>?){list?.let {this.list.addAll(list)notifyDataSetChanged()}}//调用HomeItemView进行home页面的填充 创建了条目view//1.需要一个HomeHolderclass BaseListHolder(itemView: View): RecyclerView.ViewHolder(itemView){}//2.复写三个次级构造方法//2.1 条目初始化进行数据绑定override fun onBindViewHolder(holder: BaseListAdapter.BaseListHolder, position: Int) {//如果是最后一条就不刷新viewif(position==list.size)return//拿到条目数据val data=list.get(position)//拿到条目Viewval itemView=holder.itemView as ITEMVIEW//条目刷新//和之前一样 用泛型不知道该类型有没有这个方法 setDate// itemView.setDate(data)//定义一个方法refreshItemView(itemView,data)//条目点击事件//设置点击事件 点开发现()是一个接口,并且只有一个方法 直接打开就行itemView.setOnClickListener {// listener.let(data) 空异常listener?.let {it(data)}//或者/*listener?.invoke(data)* *///java 做法,定义一个接口,回调给主界面/* 3.回调 java式传参if (listener!=null)listener?.onClick(data)*/}}//kotlin方法//直接定义函数类型的变量 传入参数,所需的数据类型,无返回值var listener:((itembean:ITEMBEAN)->Unit)?=null//写个方法定义函数fun setMyListener(listener:(itemBean:ITEMBEAN)->Unit){this.listener=listener}/*2.定义listener接口对象 SOClick中利用其接口实现监听data的click方法var listener:Listener<ITEMBEAN>? = null//1.javaj接口 click和ITEMBean耦合高interface Listener<ITEMBEAN>{//定义接口 监听条目datafun onClick(data:ITEMBEAN)}2.传递listener 赋值fun setMyListener(listener:Listener<ITEMBEAN>){this.listener=listener}*///2.2返回条目数量-指的是产生fragment条目override fun getItemCount(): Int {/*在抓取类中限定size 最后的+1的空间放一个进度条,实现上拉加载更多的条目* 进度条可以提取一个单独的view显示*/return list.size+1 //用1.add建立的列表就可以调用list了//最后一条显示进度条}//2.3 拿到homeViewoverride fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseListHolder {if(viewType==1){//最后一条return BaseListHolder(LoadMoreView(parent?.context))}else{//其他条目return BaseListHolder(getItemView(parent.context))}}//2.4根据位置返回type值 绝对界面或刷新框override fun getItemViewType(position: Int): Int {if(position==list.size)return 1elsereturn 0}// 通过Holder将view保存下来 要将当前类变为抽象类abstract fun refreshItemView(itemView: ITEMVIEW,data:ITEMBEAN)//获取条目View(泛型)abstract fun getItemView(context: Context?): ITEMVIEW}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。