kotlin 被宣布成为Google Android开发的官方语言之一的时间已经过去一段时间了,作者将kotlin打造的mvvm的架构完美兼容到之前的项目中,并且使用的非常爽。中间踩过一些坑,也折腾了一段的时间,现在来讲讲是怎么操作的。
准备工作
1、Android Studio2.3.3
2、添加kotlin插件 : setting->plugin->search kotlin
, install
3、添加依赖
build.gradle
ext.kotlin_version = '1.1.2-5'
·classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
app.gradle
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
----- 添加databinding 支持(放在android下)
dataBinding {
enabled = true
}
----- 解决databinding 和kotlin的冲突 支持(放在根下)
kapt {
generateStubs = true
}
----依赖
compile 'org.jetbrains.kotlin:kotlin-stdlib:1.1.2-5'
kapt 'com.android.databinding:compiler:2.3.3'//解决databinding 和kotlin的冲突 支持
// retfofit
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.8.0'
//添加rxjava 依赖 根据自己的版本处理
我使用的是1.0+版本
4、分包
···
-base
-view
-modle
-viewmodle
-serviceapi
···
打造BaseView
BaseActivity.kt
abstract class BaseAct<B : android.databinding.ViewDataBinding, V : BaseViewModle<B>> : AppCompatActivity() {
protected lateinit var b: B
protected lateinit var viewModle: V
override fun onCreate(savedInstanceState: android.os.Bundle?) {
super.onCreate(savedInstanceState)
b = android.databinding.DataBindingUtil.setContentView<B>(this, getLayoutResource())
viewModle = TUtil.getT(this, 1)!!;
viewModle.init(this, b, this.baseContext)
}
inline fun <reified T : Activity> Activity.gotoActivity() {
val intent = Intent(this, T::class.java)
this.startActivity(intent)
}
/**
* 是否支持滑动返回
* @return
*/
protected fun supportSlideBack(): Boolean {
return true
}
private var mSwipeWindowHelper: SwipeWindowHelper? = null
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
if (!supportSlideBack()) {
return super.dispatchTouchEvent(ev)
}
if (mSwipeWindowHelper == null) {
mSwipeWindowHelper = SwipeWindowHelper(window)
}
try {
return mSwipeWindowHelper!!.processTouchEvent(ev) || super.dispatchTouchEvent(ev)
} catch (_e: Exception) {
_e.printStackTrace()
}
return false
}
/**
* menu 点击事件
*/
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home// 点击返回图标事件
-> onBackPressed()
else -> menuItemSelected(item)
}
return super.onOptionsItemSelected(item)
}
fun menuItemSelected(item: MenuItem) {
}
protected abstract fun getLayoutResource(): Int
override fun onResume() {
super<AppCompatActivity>.onResume()
android.util.Log.v(tag(), tag() + "::onResume()")
viewModle.onResume()
}
private fun tag(): String? {
return this.localClassName
}
override fun onPause() {
super<AppCompatActivity>.onPause()
viewModle.onPause()
android.util.Log.v(tag(), tag() + "::onPause()")
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
viewModle.onActivityResult(requestCode, resultCode, data)
}
override fun onDestroy() {
android.util.Log.v(tag(), tag() + "::onDestory()")
super<AppCompatActivity>.onDestroy()
viewModle.onDestory()
}
}
BaseFragment.kt
abstract class BaseFrag<B : ViewDataBinding, V : BaseViewModle<B>> : Fragment(), java.io.Serializable {
override fun onCreateView(inflater: android.view.LayoutInflater?, container: android.view.ViewGroup?, savedInstanceState: android.os.Bundle?): android.view.View? {
return inflater!!.inflate(getLayoutResource(), container, false)
}
protected abstract fun getLayoutResource(): Int
protected lateinit var viewModle: V
protected lateinit var b: B
override fun onViewCreated(view: android.view.View?, savedInstanceState: android.os.Bundle?) {
super.onViewCreated(view, savedInstanceState)
b = android.databinding.DataBindingUtil.bind<B>(view)
viewModle = TUtil.getT(this, 1)!!;
viewModle.init(activity as AppCompatActivity, b, context)
initView()
}
abstract fun initView()
inline fun <reified T : Activity> Activity.gotoActivity() {
val intent = Intent(this, T::class.java)
activity.startActivity(intent)
}
private fun tag(): String? {
return this.javaClass.simpleName
}
protected fun toast(text: String) {
android.widget.Toast.makeText(context, text, android.widget.Toast.LENGTH_SHORT).show()
}
override fun onResume() {
super.onResume()
viewModle.onResume()
}
override fun onDestroy() {
super.onDestroy()
viewModle.onDestory()
}
override fun onPause() {
super.onPause()
viewModle.onPause()
}
}
BaseViewModle.kt
abstract class BaseViewModle<B : ViewDataBinding> : ViewModleRecycle {
protected lateinit var b: B
protected lateinit var act: AppCompatActivity
protected lateinit var context: Context
companion object {
}
protected fun toast(text: String) {
Toast.makeText(context, text, Toast.LENGTH_SHORT).show()
}
fun initToolBar(toolbar: Toolbar, title: String) {
toolbar.setTitle(title)
toolbar.setTitleTextColor(context.resources.getColor(R.color.colorAccent))
act.setSupportActionBar(toolbar)
act.supportActionBar!!.setDisplayHomeAsUpEnabled(false)
}
fun init(act: AppCompatActivity, b: B, c: Context) {
this.b = b
this.act = act
context = c
initUI()
initNet()
}
inline fun <reified T : Activity> Activity.gotoActivity() {
var intent = Intent(this, T::class.java)
act.startActivity(intent)
}
abstract fun initUI()
abstract fun initNet()
fun clear() {
}
override fun onResume() {
}
override fun onPause() {
}
override fun onDestory() {
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
}
}
搞定!!!
使用
- 干货的来源api
view
class GirlsFragment : BaseFrag<FragmentGirlsBinding, GrilsViewModle>() {
override fun initView() {
initToolBar(b!!.toobar, "妹纸")
}
companion object {
fun newInstance(): GirlsFragment {
val fragment = GirlsFragment()
return fragment
}
}
override fun getLayoutResource(): Int {
return R.layout.fragment_girls
}
}
viewmodle
/**
* Created by apanda on 2017/6/13.
*/
class GrilsViewModle : BaseViewModle<FragmentGirlsBinding>(), BaseBindingItemPresenter<Result> {
public override fun onItemClick(position: Int, itemData: Result) {
toast("itemClicked")
}
private var adapter: SingleTypeBindingAdapter? = null
override fun initUI() {
adapter = SingleTypeBindingAdapter(context, null, R.layout.item_girls)
adapter!!.setItemPresenter(this)
b!!.recylerview.adapter = adapter
b!!.recylerview.layoutManager = GridLayoutManager(context, 2)
}
override fun initNet() {
val api = Service.Factory.create()
api.getData("福利", 20, 1)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe({ result ->
adapter!!.refresh(result.results)
}, { _ ->
})
}
}
api
interface Service {
@GET("api/data/{type}/{pageSize}/{pageNumber}")
fun getData(@Path("type") type: String,
@Path("pageSize") pageSize: Int,
@Path("pageNumber") pageNumber: Int): Observable<BasePojo<List<Result>>>
companion object Factory {
fun create(): Service {
val logging = HttpLoggingInterceptor()
logging.level = HttpLoggingInterceptor.Level.BASIC
val client = OkHttpClient.Builder()
.addInterceptor(logging)
.build()
val retrofit = Retrofit
.Builder()
.client(client)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("http://gank.io/")
.build()
return retrofit.create(Service::class.java)
}
}
}
下篇文章将会使用该框架实现 钉钉在聊天框 粘贴html地址,实现内容预览的功能。
另外自己使用的框架中还实现了一个上下拉刷新加载的BaseViewLoadingDataModle
,有需要的童鞋,可以跟我交流。
项目地址: http://git.oschina.net/apandas/kotlinframe
Copyright (c) 2017 Copyright Holder All Rights Reserved.
原创文章,转载需说明出处,版权归作者所有。