classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin_version}"
classpath "org.jetbrains.kotlin:kotlin-android-extensions:${versions.kotlin_version}"
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
dependencies {
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:${versions.kotlin_version}"
compile "com.android.support:appcompat-v7:${rootProject.ext.support}"
testCompile 'junit:junit:4.12'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
// kapt "com.android.databinding:compiler:${versions.databinding}"
compile "com.squareup.retrofit2:retrofit:${versions.retrofit2}"
compile "com.squareup.retrofit2:adapter-guava:${versions.retrofit2}"
compile "com.squareup.retrofit2:converter-gson:${versions.retrofit2}"
compile "com.squareup.retrofit2:adapter-rxjava:${versions.retrofit2}"
compile "com.squareup.retrofit2:converter-moshi:${versions.retrofit2}"
// 大神写的这个库可以支持到rxjava2.X
//tab 一起使用
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
compile "io.reactivex.rxjava2:rxandroid:${versions.rxandroid}"
// Because RxAndroid releases are few and far between, it is recommended you also
// explicitly depend on RxJava's latest version for bug fixes and new features.
compile "io.reactivex.rxjava2:rxjava:${versions.reactivex}"
}
做了一个简单的baseActivity,用于绑定页面,简单的管理页面。
/**
* Created by guoxw on 2017/5/24.
* @auther guoxw
* @date 2017/5/24
* @desciption
*/
abstract class BaseActivity : AppCompatActivity() {
val BTAG: String = BaseActivity::class.java.name
/**
* 静态成员
*/
companion object {
//管理运行的所有activity
var mActivities: ArrayList = ArrayList()
//单例
var activity: BaseActivity? = null
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestWindowFeature(Window.FEATURE_NO_TITLE)
setContentView(getLayoutId())
initData()
initView()
initListener()
synchronized(mActivities) {
mActivities.add(this)
}
}
//绑定页面
abstract fun getLayoutId(): Int
//初始化页面
abstract fun initView()
//初始化data
abstract fun initData()
//监听
abstract fun initListener()
/**
* 打开页面
*
* @param activity 需要打开的页面
* @param bundle 传的值
*/
fun openActivity(activity: Class<*>, bundle: Bundle?) {
val intent: Intent = Intent()
if (bundle != null) {
intent.putExtra("data", bundle)
}
intent.setClass(this, activity)
startActivity(intent)
overridePendingTransition(R.anim.screen_zoom_in, R.anim.screen_zoom_out)
}
/**
* 关闭所有Activity
*/
fun finishAll() {
//复制一份mActivities
var copy: List = ArrayList()
synchronized(mActivities) {
copy = ArrayList(mActivities)
}
//结束所有
copy.forEach { it.finish() }
//杀死当前进程
android.os.Process.killProcess(android.os.Process.myPid())
}
/**
* 关闭所有Activity,除了参数传递的Activity
*
*/
fun finishAll(except: AppCompatActivity) {
var copy: List = ArrayList()
synchronized(mActivities) {
copy = ArrayList(mActivities)
}
copy.asSequence()
.filter { it !== except }
.forEach { it.finish() }
}
/**
* 退出应用
*/
fun exitApp() {
finishAll()
android.os.Process.killProcess(android.os.Process.myPid())
}
}
一个简单的Splash页,继承了BaseActivity。打开页面调用的就是baseActivity里的打开页面的方法。
在kotlin中页面绑定十分简单,在xml中定义好控件的id后,在Activity里就能直接使用呢,不用一大堆的findbyId了
而且配合lambda表达式监听事件等变得格外简洁
import android.os.Handler
import com.guoxw.gankio.R
import com.guoxw.gankio.ui.activities.base.BaseActivity
import kotlinx.android.synthetic.main.activity_splash.*
class SplashActivity : BaseActivity() {
var canJump: Boolean = true
override fun getLayoutId(): Int = R.layout.activity_splash
override fun initView() {
img_splash.setImageResource(R.mipmap.haden)
}
override fun initData() {
//延迟两秒跳转到MainActivity
Handler().postDelayed({
if (canJump) {
openActivity(MainActivity::class.java, null)
finish()
}
}, 2000)
}
override fun initListener() {
tv_splash_jump.setOnClickListener {
//主动跳过
if (canJump) {
canJump = false
openActivity(MainActivity::class.java, null)
finish()
}
}
}
}
我这使用的是GankIO的API
没错,你没看错,kotlin类的定义就是那么简单。当然我这里面的泛型使用还是有点问题,kotlin还有in和out的区分,我这没做区分。
/**
* Created by guoxw on 2017/5/25.
* @auther guoxw
* @date 2017/5/25
* @desciption
*/
class GankResponse<T>(val error: Boolean, val results: T) {
override fun toString(): String {
return "GankResponse(error=$error, result=$results)"
}
}
数据实体类,Parcelable有kotlin的插件,直接生成代码就行了。
data class GankData(
//id
var _id: String,
//创建时间
var createAt: String,
var desc: String,
var images: Array<String>?,
var publishedAt: String,
var source: String,
var type: String,
var url: String,
var used: Boolean,
var who: String
) : Parcelable {
fun hasImages(): Boolean = images != null
fun createTime(): String = createAt.substring(0, 10)
companion object {
@JvmField val CREATOR: Parcelable.Creator<GankData> = object : Parcelable.Creator<GankData> {
override fun createFromParcel(source: Parcel): GankData = GankData(source)
override fun newArray(size: Int): Array<GankData?> = arrayOfNulls(size)
}
}
constructor(source: Parcel) : this(
source.readString(),
source.readString(),
source.readString(),
source.createStringArray(),
source.readString(),
source.readString(),
source.readString(),
source.readString(),
1 == source.readInt(),
source.readString()
)
override fun describeContents() = 0
override fun writeToParcel(dest: Parcel, flags: Int) {
dest.writeString(_id)
dest.writeString(createAt)
dest.writeString(desc)
dest.writeStringArray(images)
dest.writeString(publishedAt)
dest.writeString(source)
dest.writeString(type)
dest.writeString(url)
dest.writeInt((if (used) 1 else 0))
dest.writeString(who)
}
override fun toString(): String {
return "GankData(_id='$_id', createAt='$createAt', desc='$desc', images=${Arrays.toString(images)}, publishedAt='$publishedAt', source='$source', type='$type', url='$url', used=$used, who='$who')"
}
}
/**
* Created by guoxw on 2017/5/22.
* @auther guoxw
* @date 2017/5/22
* @desciption
*/
interface GankIOApi {
/**
* 分类请求数据
*
* @param type
* 数据类型: 福利 | Android | iOS | 休息视频 | 拓展资源 | 前端 | all
* @param number
* 请求个数: 数字,大于0
* @param page
* 第几页:数字,大于0
*/
fun getGankIOData(type: String, number: Number, page: Int): Flowable>>
}
/**
* Created by gxw on 17-5-24.
* @auther gxw
* @date 17-5-24
* @desciption
*/
interface GankIOService {
/**
* 分类数据: http://gank.io/api/data/数据类型/请求个数/第几页
*
* @param type
* 数据类型: 福利 | Android | iOS | 休息视频 | 拓展资源 | 前端 | all
* @param number
* 请求个数: 数字,大于0
* @param page
* 第几页:数字,大于0
*
* 测试成功
*/
@GET("data/{type}/{number}/{page}")
fun getGankIOData(@Path("type") type: String, @Path("number") number: Number, @Path("page") page: Int): Flowable>>
}
/**
* Created by gxw on 17-5-24.
* @auther gxw
* @date 17-5-24
* @desciption
*/
object GankIOResetApi : GankIOApi {
/**
* 分类请求数据
*
* @param type
* 数据类型: 福利 | Android | iOS | 休息视频 | 拓展资源 | 前端 | all
* @param number
* 请求个数: 数字,大于0
* @param page
* 第几页:数字,大于0
*/
override fun getGankIOData(type: String, number: Number, page: Int): Flowable>>
= ApiClient.retrofit.create(GankIOService::class.java).getGankIOData(type, number, page)
}
val gankIOApi: GankIOResetApi = GankIOResetApi
gankIOApi.getGankIOData("福利", 10, 1)
.observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io())
.subscribe({
res ->
Log.i("MainActivity", res.toString())
if (!res.error) {
Log.i("MainActivity", "result size:".plus(res.results.size))
} else {
}
}, { e -> Log.e("MainActivity", "error:".plus(e.message)) }, {
})
}
有点懒,就先写到这吧