User.java
package com.example.app.entity;
public class User {
private String username;
private String password;
private String code;
public User() {
}
public User(String username, String password, String code) {
this.username = username;
this.password = password;
this.code = code;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
User.kt
class User {
//kotlin中默认有get set方法
var username: String? = null
// ?表示可以赋值为null
var password: String? = null
var code: String? = null
//空构造函数
constructor() {
}
//带参数的构造函数
constructor(username: String?, password: String?, code: String?) {
this.username = username
this.password = password
this.code = code
}
}
MainActivity.java
package com.example.app;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.example.app.entity.User;
import com.example.app.widget.CodeView;
import com.example.core.utils.CacheUtils;
import com.example.core.utils.Utils;
import com.example.lesson.LessonActivity;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity
implements View.OnClickListener {
private final String usernameKey = "username";
private final String passwordKey = "password";
private EditText et_username;
private EditText et_password;
private EditText et_code;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_username = findViewById(R.id.et_username);
et_password = findViewById(R.id.et_password);
et_code = findViewById(R.id.et_code);
et_username.setText(CacheUtils.get(usernameKey));
et_password.setText(CacheUtils.get(passwordKey));
final Button btn_login = findViewById(R.id.btn_login);
final CodeView img_code = findViewById(R.id.code_view);
btn_login.setOnClickListener(this);
img_code.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v instanceof CodeView) {
CodeView codeView = (CodeView) v;
codeView.updateCode();
} else if (v instanceof Button) {
login();
}
}
private void login() {
final String username = et_username.getText().toString();
final String password = et_password.getText().toString();
final String code = et_code.getText().toString();
final User user = new User(username, password, code);
if (verify(user)) {
CacheUtils.save(usernameKey, username);
CacheUtils.save(passwordKey, password);
startActivity(new Intent(this, LessonActivity.class));
}
}
private boolean verify(User user) {
if (user.getUsername() != null && user.getUsername().length() < 4) {
Utils.toast("用户名不合法");
return false;
}
if (user.getPassword() != null && user.getPassword().length() < 4) {
Utils.toast("密码不合法");
return false;
}
return true;
}
}
MainActivity.kt
package com.example.app.activity
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
import com.kotlin.app.R
import com.example.app.entity.User
import com.example.app.widget.CodeView
import com.example.core.utils.CacheUtils
import com.example.core.utils.toast
import com.example.lesson.LessonActivity
//:可以代表集成,如果有实现的接口,后面用逗号分隔
class MainActivity : AppCompatActivity(), View.OnClickListener {
private val usernameKey = "username"
private val passwordKey = "password"
//类型后面问好,代表可以为null,kotlin定义变量必须有初始值
//private var et_username:EditText? = null
//lateinit 表示延时初始化,可以先不给初始值
private lateinit var et_username: EditText
private lateinit var et_password: EditText
//Kotlin中代码结尾不用写封号
private lateinit var et_code: EditText
private lateinit var btn_login: Button
private lateinit var img_code: CodeView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//初始化view
initView()
//点击事件
clickEvent()
}
private fun initView() {
et_username = findViewById<EditText>(R.id.et_username)
et_password = findViewById<EditText>(R.id.et_password)
et_code = findViewById<EditText>(R.id.et_code)
btn_login = findViewById<Button>(R.id.btn_login)
img_code = findViewById<CodeView>(R.id.code_view)
}
private fun clickEvent() {
//?. 表示 btn_login如果不为null,调用点击事件
//!!:不会校验null值,无论是否为null,都会调用
btn_login?.setOnClickListener(this)
img_code?.setOnClickListener(this)
}
override fun onClick(v: View) {
//Kotlin中 类型判断用is
if(v is CodeView){
v.updateCode()
}else if(v is Button){
login()
}
}
private fun login() {
//Java 中的final 表示不可变引用 getText kotlin中直接.text
val username:String = et_username.text.toString()
val password:String= et_password.text.toString()
val code:String= et_code.text.toString()
//Kotlin 中创建对象不用new
val user: User = User(username,password,code)
if(verify(user)){
CacheUtils.save(usernameKey, username)
CacheUtils.save(passwordKey, password)
//Kotlin中 LessonActivity.class 要写成LessonActivity::class.java
//Kotlin中获取class 用LessonActivity::class 要转化成java中class-->LessonActivity::class.java
startActivity(Intent(this, LessonActivity::class.java))
}
}
private fun verify(user: User): Boolean {
if(user.username!=null && user.username!!.length<4){
toast("用户名不合法")
return false
}
if (user.password != null && user.password!!.length < 4) {
toast("密码不合法")
return false
}
return true
}
}
Java中的数组
private String[] codeList = new String[]{"kotlin", "android", "java", "http", "https", "okhttp", "retrofit", "tcp/ip"};
Kotlin中的数组
//Kotlin 中数组用 arrayOf
private val codeList =arrayOf("kotlin", "android", "java", "http", "https", "okhttp", "retrofit", "tcp/ip")
Java中构造函数:
public CodeView(Context context) {
this(context, null);
}
public CodeView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
Kotlin中构造函数:
//:this(context,null) 调用双参构造
constructor(context: Context) : this(context, null)
//:super(context,attrs) 调用父类构造函数
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
}
Kotlin中写静态函数或者静态成员的三种方式:
顶层函数
在java中写一个工具类是这样的
public class Utils {
private static final DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
public static float dp2px(float dp) {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics);
}
public static void toast(String string) {
toast(string, Toast.LENGTH_SHORT);
}
public static void toast(String string, int duration) {
Toast.makeText(BaseApplication.currentApplication(), string, duration).show();
}
}
用Kotlin的顶层函数是这样的
Utils.kt
@file:JvmName("MyUtils")
package com.example.core.utils
import android.content.res.Resources
import android.util.DisplayMetrics
import android.util.TypedValue
import android.widget.Toast
import com.example.core.BaseApplication
//Kotlin中写静态函数,有三种方法
//第一种方法:顶层函数(Kotlin中的属性和方法可以直接写在文件中,就是类的外层)
private val displayMetrics: DisplayMetrics = Resources.getSystem().getDisplayMetrics()
fun dp2px(dp: Float): Float {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics)
}
fun toast(string: String) {
toast(string, Toast.LENGTH_SHORT)
}
fun toast(string: String, duration: Int) {
Toast.makeText(BaseApplication.currentApplication(), string, duration).show()
}
在kotlin中直接通过包名调用
在java代码中是这样调用的
//在Java代码中调用Kotlin的顶层函数,如果没有使用注解:@file:JvmName("MyUtils"),需要在工具类后面加上Kt字符
//也可以通过注解自定义
MyUtils.dp2px(20f);
object类
在java中的一个工具类是这样的
package com.example.core.utils;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import com.example.core.BaseApplication;
import com.example.core.R;
public class CacheUtils {
@SuppressLint("StaticFieldLeak")
private static Context context = BaseApplication.currentApplication();
private static SharedPreferences SP = context.getSharedPreferences(context.getString(R.string.app_name), Context.MODE_PRIVATE);
public static void save(String key, String value) {
SP.edit().putString(key, value).apply();
}
public static String get(String key) {
return SP.getString(key, null);
}
}
kotlin中可以这样写:
package com.example.core.utils
import android.content.Context
import android.content.SharedPreferences
import com.example.core.BaseApplication
import com.example.core.R
//在Kotlin中,如果一个类被object 修饰。就表示这个类中的所有的成员变量
//和成员函数都是静态的。也就是一个单列类
object CacheUtils {
val context: Context = BaseApplication.currentApplication()
val SP: SharedPreferences =
context.getSharedPreferences(context.getString(R.string.app_name), Context.MODE_PRIVATE)
//Unit代表没有
fun save(key: String?, value: String?): Unit {
SP.edit().putString(key, value)
}
//String? 返回值后面加上一个问号,代表返回值可能为null
@JvmStatic
fun get(key: String?): String? {
return SP.getString(key, null)
}
}
在kotlin中直接调用
CacheUtils.save(key, username)
在Java代码中调用kotlin中object修饰的类,如果不用@JvmStatic注解必须用.INSTANCE
CacheUtils.get("Kotlin学习");或者 CacheUtils.INSTANCE.get("Kotlin学习");
companion object 伴生对象
在java中一个类是这样的
package com.example.core;
import android.app.Application;
import android.content.Context;
import androidx.annotation.NonNull;
public class BaseApplication extends Application {
private static Context currentApplication;
@NonNull
public static Context currentApplication() {
return currentApplication;
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
currentApplication = this;
}
}
Kotlin中就是这样的:
package com.example.core
import android.app.Application
import android.content.Context
class BaseApplication : Application() {
//object 修饰的对象中的变量和函数都是静态的,
//我们只想让类中的一部分函数和变量是静态的就用伴生对象
companion object {
lateinit var currentApplication: Context
@JvmStatic
fun currentApplication(): Context {
return currentApplication
}
}
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
currentApplication = this
}
}
在kotlin中直接类名就可以调用:
BaseApplication.currentApplication()
在java中调用这个kotlin代码
//在Java中调用伴生对象 如果不用@JvmStatic注解必须用.Companion
//BaseApplication.Companion.currentApplication();
BaseApplication.currentApplication();
java中的接口定义与Kotlin中的接口定义
java中的接口
public interface EntityCallback<T> {
void onSuccess(@NonNull T entity);
void onFailure(@Nullable String message);
}
kotlin中的接口
//Kotlin中接口
interface EntityCallback<T>{
fun onSuccess(entity:T)
fun onFailure(message:String?)
}
Java中抽象类与kotlin中的抽象类
java中的抽象类
public abstract class BaseViewHolder extends RecyclerView.ViewHolder {
public BaseViewHolder(@NonNull View itemView) {
super(itemView);
}
@SuppressLint("UseSparseArrays")
private final Map<Integer, View> viewHashMap = new HashMap<>();
@SuppressWarnings("unchecked")
protected <T extends View> T getView(@IdRes int id) {
View view = viewHashMap.get(id);
if (view == null) {
view = itemView.findViewById(id);
viewHashMap.put(id, view);
}
return (T) view;
}
protected void setText(@IdRes int id, @Nullable String text) {
((TextView) getView(id)).setText(text);
}
}
Kotlin中的抽象类
abstract class BaseViewHolder: RecyclerView.ViewHolder{
//构造函数
constructor(itemView: View):super(itemView)
private val viewHashMap:HashMap<Int,View> = HashMap<Int,View>()
fun<T:View> getView(id:Int):T{
var view:View? = viewHashMap.get(id)
if(view==null){
view = itemView.findViewById(id)
viewHashMap.put(id, view)
}
//kotlin 中类型转换用as
return view as T
}
protected fun setText(@IdRes id: Int, text: String?) {
(getView<View>(id) as TextView).text = text
}
}
Java中的枚举与Kotlin中的枚举
Java中枚举 enum
public enum StateMessage {
}
Kotlin中枚举 enum class
enum class StateMessage {
}
Java、Kotlin中的接口回调
Java中的接口回调
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
entityCallback.onFailure("网络异常");
}
@Override
public void onResponse(Call call, Response response) {
final int code = response.code();
if (code >= 200 && code < 300) {
final ResponseBody body = response.body();
String json = null;
try {
json = body.string();
} catch (IOException e) {
e.printStackTrace();
}
entityCallback.onSuccess((T) convert(json, type));
} else if (code >= 400 && code < 500) {
entityCallback.onFailure("客户端错误");
} else if (code > 500 && code < 600) {
entityCallback.onFailure("服务器错误");
} else {
entityCallback.onFailure("未知错误");
}
}
});
Kotlin中的接口回调
//Kotlin中回调函数 用object:
call.enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
entityCallback.onFailure("网络异常")
}
override fun onResponse(call: Call, response: Response) {
val code: Int = response.code()
when (code) {
in 200..299 -> {
val body: ResponseBody? = response.body()
var json: String? = null
json = body?.string()
entityCallback.onSuccess(convert(json, type) as T)
}
in 400..499 -> { entityCallback.onFailure("客户端错误") }
in 500..599 -> { entityCallback.onFailure("服务器错误") }
else -> entityCallback.onFailure("未知错误")
}
}
})