摘要:我一直坚信,快速学习与掌握一门语言的最好方式就是实践,边开发项目边学习。实现它们间的联动。方便以后本地数据请求的加入目前还没有引入本地数据库,后续有时间将引入。分别为与接口,对应的实现就是与。
前一段时间开发比较轻松,所以就研究了一下google主推的kotlin语言。我一直坚信,快速学习与掌握一门语言的最好方式就是实践,边开发项目边学习。这样才能快速的将学习的知识运用到实践中,从而发现问题,总结经验。如果你也想学习kotlin或者也正在学习kotlin,那么我们不妨可以携手共济,在实践中提升自己,快速掌握kotlin。
下面我要介绍的项目是完全使用kotlin编写的一个关于新闻的App,由于是实践介绍,我这里主要是介绍一下项目中运用到的知识点,方便后续想要一起学习的同学们快速入门与运用。
界面这是一个关于新闻的App,我这里主要包括三个界面,分别为新闻主界面、新闻详情界面与新闻订阅界面。下面简要介绍下每个界面运用到的知识点。
主界面主界面为了展示不同的分类新闻,这里使用了TabLayout+ViewPager+Fragment来实现,因此主要是逻辑就是NewsCategoryFrament中的接口请求与数据处理。接口请求主要运用的是Retrofit+RxJava+RxAndroid。来看下界面图:
我这里只是简单的介绍项目,如果想要进一步了解kotlin的实现可以查看后面的源码地址详情界面
由于使用的是国外的News Api所以,对于详情的展示这里使用的是一个WebView,全部通过原生的WebView来展示。后续查看源码会发现该处的代码比较简单。
订阅界面订阅界面主要是对主界面的分类News进行添加订阅与取消订阅操作。界面结构使用的是两个滑动的RecyclerView。实现它们间item的联动。
网络请求上面主要介绍了界面相关的知识,下面来说下项目中使用的有关网络方面的知识。主要包括接口请求与图片加载
接口请求封装前面已经介绍过了,项目使用的是Retrofit+RxJava+RxAndroid来进行接口的请求,为了在项目中进行更好的调用,这里对接口请求进行了封装。主要code如下:
fundoGet(params: MutableMap , tClass: Class ): Observable { return initParams(params, tClass)!!.observeOn(Schedulers.io()).flatMap { tempString -> if (tClass == NewsArticleListModel::class.java) { getNewsApi().getArticles(tempString).subscribeOn(Schedulers.io()) } else { getNewsApi().getSources(tempString).subscribeOn(Schedulers.io()) } }.flatMap { newsResponse -> if (newsResponse is NewsArticleListModel && newsResponse.status.equals("ok") || (newsResponse is NewsSourcesListModel && newsResponse.status.equals("ok"))) { val json = getGson()?.toJson(newsResponse!!) if (json.isNullOrEmpty()) return@flatMap null!! val data = getGson()?.fromJson(json, tClass) Observable.just(data) } else { Observable.error { Exception() } } }.observeOn(AndroidSchedulers.mainThread()) .doOnError { t -> Log.d("TAG", "throwable: " + t) } }
由于数据可以来自与网络与本地,所以这里将来源屏蔽,请求抽象成接口。方便以后本地数据请求的加入(目前还没有引入本地数据库,后续有时间将引入)。分别为RequestCommand与Provider接口,对应的实现就是NewsReqeustCommand与NewsProvider。因此最终的调用如下:
fun setupRequest(refresh: Boolean) { val params = mutableMapOf( NewsConfig.REQUEST_SOURCE to id, NewsConfig.REQUEST_SORT_BY to NewsConfig.SortBy.TOP.sort ) requestCommand = NewsRequestCommand(params, NewsArticleListModel::class.java, object : DefaultDisposableObserver () { override fun onNext(t: NewsArticleListModel) { if (refresh) swipeRefreshLayout.isRefreshing = false dataList.clear() dataList.addAll(t.articles) recyclerView.adapter.notifyDataSetChanged() } override fun onError(e: Throwable) { super.onError(e) if (refresh) swipeRefreshLayout.isRefreshing = false } }) requestCommand?.execute() }
自己最近没有时间,手上的项目将要大改版。如果客官们有兴趣的话可以在Github上Start/Fork提交PR图片加载封装
图片加载使用的是facebook的fresco,为了全局使用统一的图片加载,这里使用kotlin的Extension Functions特性,对图片加载进行封装。
fun SimpleDraweeView.displayImage(url: String?, width: Int = 200, listener: BaseControllerListener? = null) { if (url == null) return this.hierarchy.setPlaceholderImage(R.drawable.news_default_bg) val imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url)) .setResizeOptions(ResizeOptions(width, width)) .build() val controller = Fresco.newDraweeControllerBuilder() .setImageRequest(imageRequest) .setAutoPlayAnimations(true) .setControllerListener(listener) .setOldController(this.controller) .build() this.controller = controller }
所以最终的调用是这样的:
itemView.image.displayImage(url = urlToImage)
就是这么简单,当然参数可以动态选择Interface
在kotlin中的interface与java中的interface有一个巨大的区别。我们都知道在java中interface中是不能够对方法进行实现,但在kotlin中的interface可以对方法进行具体实现。所以可以借助这一特性来实现一个统一的ToolBarManager,方便界面的导航设置。具体如下:
interface ToolBarManager { val toolBar: Toolbar var toolBarTitle: String set(value) { toolBar.title = value } get() = toolBar.title.toString() fun initToolBar() { toolBar.inflateMenu(R.menu.menu) toolBar.setOnMenuItemClickListener { when (it.itemId) { R.id.subscribe -> toolBar.context.startActivity() } true } } fun enableHomeAsUp(back: () -> Unit) { toolBar.navigationIcon = DrawerArrowDrawable(toolBar.context) toolBar.setNavigationOnClickListener { back() } }
所以后续界面导航的实现,可以通过实现ToolBarManager接口即可。
Delegated Properties我们都知道在开发过程中会遇到单例模式的编写,基本的kotlin编写如下:
class App : Application() { companion object { private var instance: Application? = null fun instance() = instance!! } override fun onCreate() { super.onCreate() instance = this } }
对于kotlin也提供了standard Delegates的实现,其中可以通过lazy来进行单例模式的懒加载。
companion object { val instance by lazy { NewsApp() } }
或者是lateinit
class App : Application() { companion object { lateinit var instance: App private set } override fun onCreate() { super.onCreate() instance = this } }
最后也可以通过自定义Delegated来实现,通过使用ReadWriteProperty
object DelegatesExt { funnotNullSingleValue(): ReadWriteProperty = NotNullSingleValueVar() } class NotNullSingleValueVar : ReadWriteProperty { private var value: T? = null override fun getValue(thisRef: Any?, property: KProperty<*>): T { return value ?: throw IllegalStateException("${property.name} not initialized") } override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { this.value = if (this.value == null) value else throw IllegalStateException("${property.name} not initialized") } }
当对其进行设置值与获取值时,会调用相应的getValue与setValue方法,最终调用如下:
companion object { var instance: NewsApp by DelegatesExt.notNullSingleValue() }
当然,项目中还对Preference进行了相似的操作。Anko
其实使用kotlin进行Android开发也有相应的工具库。可以快速提升我们的开发效率,其中Anko就是一个不错的选择。它可以通过Anko DSL代码书写代替XML来进行UI布局。这是一个非常有效的特性,当然它也有许多有用的functions,可以大大提升我们的开发效率。例如:
1.find()代替findViewById()
2.longToast()代替原生Toast()
3.startActivity(vararg params: Pair
4.Anko SQLite简化原生的SQLite的使用
5.Dialogs的简化使用
好了,大概就是这么多了。希望能够帮助想学与正在学习kotlin的客官们,少走弯路,快速成长。如有不足之处欢迎交流!
项目地址
个人博客
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/13872.html
摘要:发布本周正式发布,包含了一系列的特性提升与问题修复,同时也在不断致力于将打造地更为轻巧与高性能。当然,姜振勇老师还会介绍的多种服务,包括大数据网络和安全,展现弹性安全和高可扩展性的全方位能力。 showImg(http://upload-images.jianshu.io/upload_images/1647496-2ce7598e6987d9af.jpg?imageMogr2/aut...
摘要:通过广泛使用且采用系统的库,避免了跨站请求伪造其中,用户能够被诱骗在你的站点上执行某些操作。小结通过使用自动加载程序所有主流框架的标配,避免了远程和本地文件包含。另外,对于伸缩性,重要的是数据库。 PHP 现在名声很糟糕,因为它曾经是可怕的。本文试着回答一些常见的关于 PHP 的断言,目的是向非技术人员解释,PHP 并不像...
摘要:会议主要是加深开发者对的了解,从而帮助开发者做好的兼容工作。因此本篇我会选择性说明一些在上你需要兼容的一些事情。那么现在有哪些会用到这种呢举一个大家熟悉的。另外目前可以通过在清单文件设置是否启用。因此强烈建议将这个工作排上兼容行程。showImg(https://user-gold-cdn.xitu.io/2019/5/27/16af6c9ce913040d); 5 月 20 号参加了 An...
摘要:本文是一篇属于的文章,只是代表了作者的个人观点,笔者看到有两人发了都是关于最佳实践的,就把二者集成了下,并且加入了一些个人的看法,基本的知识点分布方式参考了我的知识体系架构。尽量使用那些较小的,往往只是完成单个功能的库,将来比较好替换。 本文是一篇属于Opinionated的文章,只是代表了作者的个人观点,笔者看到Medium有两人发了都是关于最佳实践的Checklist,就把二者集...
摘要:官方定义项目介绍长期目标是使用开发一个完整的应用,目前搭建了最小量的脚手架。测试程序和都提供了强大的测试套件,能够很好的和集成,进行集成测试和单元测试。编写一些基本的集成测试,检查接口是否正常。 showImg(https://segmentfault.com/img/remote/1460000008751790); kotlin是由IntelliJ IDEA的开发商Jetbrain...
阅读 1414·2021-10-09 09:44
阅读 1833·2021-09-22 15:43
阅读 7390·2021-09-22 15:07
阅读 933·2021-09-03 10:28
阅读 1914·2021-08-19 10:57
阅读 903·2020-01-08 12:18
阅读 2864·2019-08-29 15:09
阅读 1404·2019-08-29 14:05