kotlin中mainactivity无法直接调用xml中的控件_使用Kotlin开发出自己的框架一

以前一直使用自己开发的Android(java版本)框架,使用起来非常方便,如

class 

这是我改成kotlin后的版本,使用起来非常方便,只要指定泛型就行了,不用再手动去new Fragment。但这样做也有不足,因为是通过反射来获取类名的,而java的泛型还是有很多不足的。反射代码如下:

open 

我们希望统一的代码写在统一的基类里面,所以就必须写在BaseActivityWithFragment里面,但是这时就无法通过V来获取真实的类型,必须通过其他方式(以上方式)转折获取。当然有时还会遇到再上一级父类想使用泛型的情况,那就更加无能为力了(这就是Java系的弊病,Kotlin在这一方面保留了这个毛病)。而我一直就突破,想改进,终于通过前面学习后了解到了Koin(主要优点是不用反射)。这次我想尝试一下能不能不用反射,又能最简单的完成以上的功能的全新框架。

因为以前的框架为了简单使用了Databinding,确实方便了许多,当然,我也想只通过泛型配置一下就可以反射生成ViewDatabing,最终也实现了,当前问题也是一样反射会有各种性能问题。这一次编写框架我仍然是顺手添加了Databinding,后来发现有很多问题,一点优势没体现出来, 因为有kotlin-android-extensions。所以后来我就去掉了这个功能。

1、简要说明

我希望将程序分为动静两部分。举例说明分页加载弹出进度条的功能,我们可以按命令模式提取几个大步骤:

1、显示加载进度

2、加载数据

3、加载完成显示数据,关闭进度对话框

4、错误处理

我们就可以将这些基本步骤写在父类中(这是静的部分),而加载数据必须是动的(每个页面必须不同)、显示数据也一定是动的。为了更简单的动的部分,我们可不可以只用处理加载数据(可以是网络,也可以是数据库)最原始的部分,而显示以RecycleView为例我们应该只要用户处理一下ViewHolder就结束为好。这也就是我要编写框架的初衷,当然以Java为语言的版本我都做过多次尝试,包括前言所说的反射,已经完成了一套非常实用的框架。我还编写过使用c#编写的动态生成基础页面的可以直接运行的小程序,大大提高了开发效率,最主要的是保证了不会出错,当然出现错误也可以只用修改一处。那么,怎样封装怎么简化就是我要考虑的问题。当然最先要考虑怎样实现,而每一个框架都是迭代的过程,我也会将整个代码迭代重构的过程详细记录以供大家参考。同时会将源码提供大学一起学习,有问题可以和我沟通交流。

2、参照源码

参照源码github地址: kudago-kotlin

Kotlin, MVVM, AndroidX, Paging, Network (Coroutines+Retrofit2+OkHttp3+Gson), Glide, Maps

这个源码大家可以自己学习,也可以按我以前写的《Kotlin学习之开源代码分析、重构》两篇文章中提到的方法进行学习。

kudago使用的是dagger而不是koin,还使用了realm-gradle-plugin(我还没涉入,连名称都不知),所以我只是使用里面的数据源,以及分页加载部分,提取公用类库。我也是按照前面写的方法只迁移了主界面,分页数据加载,显示等功能。由于这一部分以前写过,所以提取框架是在迁移后的基础上进行的。

3、框架代码

框架代码github地址: KivyV1.0.3

3.1 新建项目

这个前面也提到过,不过要新建xframework类库将一些通用的东西都放在类库里。

补充说明一点,考虑到要使用沉浸式状态栏 ImmersionBar ,所以尽可能的使用Fragment来显示(这是我这样使用而非 ImmersionBar 强烈建议)。

android 4.4以上沉浸式状态栏和沉浸式导航栏管理,适配横竖屏切换、刘海屏、软键盘弹出等问题,可以修改状态栏字体颜色和导航栏图标颜色,以及不可修改字体颜色手机的适配,适用于Activity、Fragment、DialogFragment、Dialog,PopupWindow,一句代码轻松实现,以及对bar的其他设置,详见README。简书请参考: http://www. jianshu.com/p/2a884e211 a62

通过分析kudago代码后,对分页显示比以前的Fragment多了一个DiffUtil类,我的目标是只要是分页加载,也就只要编写这五个类就可以了其他的代码尽量少写。

五个类分别为:DiffUtil,Adapter,Fragment,ViewHolder,ViewModel等。所以我也就必须要编写这五个类的基类,能写在基类的就一定要定在基类里。

3.1.1 xframework的包结构

1、exception存放自定义的异常

2、ext存放要使用到的一些扩展方法

3、tools现在存放了XLiveDataBus以及XImmersionBar相关的类

4、utils存放一些常用的Utils,暂时放的日夜模式相关的代码

5、mvvm存放了mvvm相关的代码

6、ui提供了一些ui相关的基础类,主要是BaseActivity和BaseFragment相关的类,前面也说过尽可能将相关的代码写在Fragment中

3.2 UI

3.2.1 BaseActivity

BaseActivity主要是样式主题切换,导出时关掉当前activity等功能。

open  

3.2.2 BaseFragment

BaseFragment除了使用 ImmersionBar相关代码外,只是增加了一个钩子函数,没有其他用途。主要是统一使用BaseFragment后如果要增删功能时方便。

abstract 

3.2.3 BaseActivityWithFragment

这个类比较简单,只是将Fragment嵌入到Activity中,现在的主要问题前面就说过创建Fragment的问题。在不是非常熟悉的情况下,我先考虑new的方式,以后可以考虑其他方式。

xml代码:

<?xml version="1.0" encoding="utf-8"?>

其中注释的代码是通过反射生成Fragment的方式,现在想的是通用不能不用反射,而是考虑使用koin。

3.2.4 BaseFragmentBingToolBar

这里要说明一下命令规则,这中间增加了Bing本来是准备使用databiding的,然后去掉了,这个名称没有修改过来大家可以忽略,以后也会进行修改过来。因此此类主要功能是处理ToolBar的。

abstract 

3.2.5 BasePagingRecycleFragment

这是我们的重头戏,所有分页显示代码都在这里。先看源码:

布局xml相对比较简单:

<?xml version="1.0" encoding="utf-8"?>
abstract 

通过泛型T,A,VM引入实体类型,Adapter和ViewModel,具体实现也就比较简单了。

3.3 MVVM

现在开始逐一讲解一下前面说的adapter和viewmodel,还有一些辅助类。mvvm根据具体的用途分文件夹。

3.3.1 IRecycleViewCallback

这个可能名字有点问题,不过主要是针对RecycleView的Item的单击和长按事件的回调方法。

/**

3.3.2 viewmodel

此包名下,有两个ViewModel,主要是因为现在以分页为主,必须预留公用类,供不分页的viewmodel使用。

abstract 

分页的BasePagingViewModel就比较麻烦,这个主要是参照kudago进行编写,暂时可以理解为非要这么用,更多详细只能参照以后重构。

abstract 

这里的PAGE_SIZE本来是常量,不过我进行修改了有的地方可能会一次加载20条,kudago就是20。

这里使用到IPagingRepository和PagingDataSource。

3.3.3 IPagingRepository

interface 

这是个接口,暂时只是传入分页和页码,同时对page还有两种类型Int和String要指定。这里的函数名getEvents有机会也要修改一下。

3.3.4 PagingDataSource

abstract  

父类PageKeyedDataSource要指定id类型,要加载两次数据,初始数据以及加载下一页数据,为了通用我增加了getNext抽象函数,可以继承后具体实现。

同时指定返回类型PagingResult放在data目录下

data 

3.3.5 BasePagingAdapter

分页的Adapter要继承自PagedListAdapter,查看要指定的泛型和接收的参数,也必须通过BasePagingAdapter传递出去。

这里使用到viewholder,下面将看一下viewholder

3.3.6 viewholder

统一实现数据绑定IViewHolderBind

interface 

ViewHolder的实现比较简单

事件也通过init放进来了。

到此为止,基本上能使用到的功能都一一介绍过。

3.4 实现代码

kivyv103的app代码按照以前惯例仍然是分为data、di、ui、utils等目录。

3.4.1 数据部分

3.4.1 domain

这个相对简单,针对 kudago少了外面一层的Events(这个对应的类是xframework中的PagingResult)

data 

3.4.2 repository

EventRepository是继承IPagingRepository接口

class 

IService相关的就不详细说明了。

分页数据源代码:

class 

这里只是将前面注释的代码直接显示在getNext方法里。

3.4.3 ui

3.4.3.1 MainActivity

前面说过要尽可能使用Fragment来实现具体业务,所以要使用BaseActivityWithFragment类,尽可能不使用反射就只能通过inject注入。

class 

3.4.3.2 MainFragment 相关

五个相关类

1、EventsDiffUtil

用于比较两个Event

class 

2、MainViewHolder

因为kotlin-android-extensions,所以databinding也就没有太多优势。

class 

3、MainAdapter

暂时也不动态创建MainViewHolder,直接new了

class 

现在的adapter只处理一种类型,多种类型的看重构吧。

4、MainViewModel

这个非常简单,生成对应的EventPagingDataSource就可以了

class 

5、MainFragment

继承BasePagingRecycleFragment后,只要override一些创建方法就结束了。后面可以考虑不手动new,而是通过koin进行。暂时还是直接new。

class 

3.5 di

现在的所有问题基本上都统一到了di部分。

同理初始化Application代码不可少。

class 

3.5.1 remote_datasource

这里的代码配置过多次,唯一要注意的是JSON的问题

val 

remote_datasource

val 

3.5.2 正常的modules

都是一些前面讲过的常规配置,主要是保证代码能运行,功能能完成。更多的优化只能在优化部分。

val 

4、总结

真正调试代码也不可能像以上那样一帆风顺,以上的罗列都是经过不断尝试的结果。主要是一种思路,怎样迁移别人的源码同时内化为自己代码的过程。

5、问题

adapter 能不能注入,viewholder能不能注入等。问题不断,优化不断。

源码:

github: KivyV1.0.3 框架可运行代码release版本。

e3c333ef59ba7e31a9f31cc63f3a972e.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值