Kotlin for Android - 实战记录<一>
2017-06-23 16:47
330 查看
· 扩展属性,在所有的Context及Context的子类中都可以直接 使用
· 在项目任何位置都能轻松拿到app实例,不需要强转。
总共写了四个方法,因为在Activity,View,Fragment中都可以通过context直接拿到,当没有context的时候可以通过反射拿到。
有了以上代码,在Activity,View,Fragment直接
其他任意类中也可以通过
· 在任意类中,没有context时,获取SharedPreference
· 在Activity中 setContentView(R.layout.activity_xx)之后,可以直接使用布局文件中的id作为控件使用,不需要再findViewById了,比ButterKnife还要好用。
但是在Fragment中,就没有那么轻松了,如果在onCreateView中直接使用布局文件中的id,在运行时会报错。
解决办法1:使用view.控件id,这样可以解决问题,需要导入
并且每次使用都需要用
解决办法2:与方法1基本一致,需要导入
然后使用with关键字,可以省去每次都用
解决办法3:直接在onViewCreated中去初始化事件,则不会报错。
· 在项目中常常需要根据editText中的内容变化来做一些事情,在java中我们直接
先看java代码:
即使我们对TextWatcher进行简单封装,调用的时候也还是有不少代码,不简洁。而且还需要新建类。
在kotlin中,我们可以通过添加一个扩展函数,让一切变得简单而舒服。
有了上面这段扩展函数,在需要监听editText的内容变化时,只需要一行代码就搞定。
是不是简洁了很多。
· 在项目中,我们常常要用到很多Dialog,Dialog中往往有很多重复的代码,我们可以通过创建一个Dialog模板,来简化Dialog的创建。
先看一个简单的java代码弹出自定义Dialog。
以上代码定义了一个自定义布局的dialog,然后对dialog中的控件,进行一些事件操作。也许你的Dialog初始化操作有更多可复用的代码,需要复用的设置直接写在扩展函数里面,可复用操作越少灵活性相对就会高一点,以下是一个简单的dialog的扩展函数。
有了以上三段简短的代码,我们在activity和fragment中都可以使用更少的代码去显示一个自定义布局的Dialog,接下来我们看看,如何使用这个Dialog模板,完成上面java代码的工作。
省略了一些通用设置,看着比较清晰,而且不用findViewById了。
文章内容如有错误欢迎指正,对本文内容有任何疑问欢迎加群讨论:283272067
app属性,且是自定义的Application不需要再强转
/*扩展属性*/ var Context.app: KotlinApplication get() { return applicationContext as KotlinApplication } set(value) { app = value }
· 在项目任何位置都能轻松拿到app实例,不需要强转。
总共写了四个方法,因为在Activity,View,Fragment中都可以通过context直接拿到,当没有context的时候可以通过反射拿到。
fun Activity.getApp(): KotlinApplication = app fun View.getApp(): KotlinApplication = context.app fun Fragment.getApp(): KotlinApplication = context.app fun Any.getAppNoContext(): KotlinApplication { try { val application = Class.forName("android.app.AppGlobals").getMethod("getInitialApplication").invoke(null) as Application return application as KotlinApplication } catch (e: Exception) { return KotlinApplication() } }
有了以上代码,在Activity,View,Fragment直接
getApp()就能够拿到自定义的application实例。
其他任意类中也可以通过
getAppNoContext()直接拿到自定义的application实例。
· 在任意类中,没有context时,获取SharedPreference
fun Any.getSpNoContext(): SharedPreferences { return getAppNoContext().getSharedPreferences("default", Context.MODE_PRIVATE) }
· 在Activity中 setContentView(R.layout.activity_xx)之后,可以直接使用布局文件中的id作为控件使用,不需要再findViewById了,比ButterKnife还要好用。
但是在Fragment中,就没有那么轻松了,如果在onCreateView中直接使用布局文件中的id,在运行时会报错。
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { val view = inflaterView(inflater, R.layout.fragment_xx, null) //在此处直接使用fragment_xx 里面的id来用,运行时会报错。 return view }
解决办法1:使用view.控件id,这样可以解决问题,需要导入
import kotlinx.android.synthetic.main.fragment_xx.view.*
并且每次使用都需要用
view.
解决办法2:与方法1基本一致,需要导入
import kotlinx.android.synthetic.main.fragment_xx.view.*
然后使用with关键字,可以省去每次都用
view.的麻烦。
with(view) { tv_title.text = "hello,kotlin fragment" tv_title2.text = "hello,kotlin fragment" tv_title3.text = "hello,kotlin fragment" }
解决办法3:直接在onViewCreated中去初始化事件,则不会报错。
· 在项目中常常需要根据editText中的内容变化来做一些事情,在java中我们直接
addTextChangeListener,在kollin中我们可以写一个简单的扩展函数来让监听editText内容变化着一操作变的更加简单。
先看java代码:
et_test.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { Log.d(TAG, "s:" + s); } @Override public void afterTextChanged(Editable s) { } });
即使我们对TextWatcher进行简单封装,调用的时候也还是有不少代码,不简洁。而且还需要新建类。
在kotlin中,我们可以通过添加一个扩展函数,让一切变得简单而舒服。
fun EditText.setTextChangeListener(body: (key: String) -> Unit) { addTextChangedListener(object : TextWatcher { override fun afterTextChanged(s: Editable?) { } override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { body(s.toString()) } }) }
有了上面这段扩展函数,在需要监听editText的内容变化时,只需要一行代码就搞定。
et_key.setTextChangeListener { Log.d(TAG, "s:" + it); }
是不是简洁了很多。
· 在项目中,我们常常要用到很多Dialog,Dialog中往往有很多重复的代码,我们可以通过创建一个Dialog模板,来简化Dialog的创建。
先看一个简单的java代码弹出自定义Dialog。
private void showConfigDialog() { final AlertDialog dialog = new AlertDialog.Builder(getMContext()).create(); dialog.show(); dialog.setContentView(R.layout.dialog_log_config); Window window = dialog.getWindow(); WindowManager.LayoutParams lp = window.getAttributes(); lp.x = 0; lp.y = -300; //不加这句Dialog中EditText无法编辑 window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); dialog.setCanceledOnTouchOutside(false); final EditText et_param = (EditText) dialog.findViewById(R.id.et_param); final EditText et_url = (EditText) dialog.findViewById(R.id.et_url); Button btn_confirm = (Button) dialog.findViewById(R.id.btn_confirm); btn_confirm.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { System.out.println(et_param.getText().toString()); System.out.println(et_url.getText().toString()); dialog.dismiss(); } }); }
以上代码定义了一个自定义布局的dialog,然后对dialog中的控件,进行一些事件操作。也许你的Dialog初始化操作有更多可复用的代码,需要复用的设置直接写在扩展函数里面,可复用操作越少灵活性相对就会高一点,以下是一个简单的dialog的扩展函数。
// AlertDialog的模板 fun Activity.showLayoutDialog(init: AlertDialog.() -> Unit): AlertDialog { val view = AlertDialog.Builder(this).create() view.show() view.init() val window = view.window window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM) return view } var AlertDialog.removeY: Int get() { val window = window val lp = window.attributes return lp.y } set(value) { val window = window val lp = window.attributes lp.y = value } fun Fragment.showLayoutDialog(init: AlertDialog.() -> Unit): AlertDialog { return activity.showLayoutDialog { init() } }
有了以上三段简短的代码,我们在activity和fragment中都可以使用更少的代码去显示一个自定义布局的Dialog,接下来我们看看,如何使用这个Dialog模板,完成上面java代码的工作。
private fun showConfigDialog() { val dialog = showLayoutDialog { setContentView(R.layout.dialog_log_config) setCanceledOnTouchOutside(false) removeY = -300 } with(dialog) { btn_confirm.setOnClickListener { System.out.println(et_param.text.toString()); System.out.println(et_url.text.toString()); dismiss() } } }
省略了一些通用设置,看着比较清晰,而且不用findViewById了。
文章内容如有错误欢迎指正,对本文内容有任何疑问欢迎加群讨论:283272067
相关文章推荐
- Android <Android应用开发实战> 资源类型<一>
- Android屏幕适配记录<一>
- Android开发工具——ADB(Android Debug Bridge) <一>概览
- 【Android开发学习45】使用google语音识别引擎(Google Speech API)<一>
- AD+EXCHANGE邮件服务器的迁移实战<一>
- 【Android开发学习45】使用google语音识别引擎(Google Speech API)<一>
- Android 编程基础<一>
- Android <Android应用开发实战> 资源类型<二>
- AD+EXCHANGE邮件服务器的迁移实战<一>
- Android: Git/Gerrit/Repo 的使用 <一>
- cocos2d-x基础<一> Android环境配置和HelloWorld的运行
- android录音开发问题<记录1>:AudioRecord录制的音频文件如何用MediaPlayer类读取
- Android GPS架构分析<一>
- AD+EXCHANGE邮件服务器的迁移实战<一>
- 20100611 学习记录:Sections must only appear once per config file. See the help topic <location> for exceptions.
- AD+EXCHANGE邮件服务器的迁移实战<一> 推荐
- Android <Android应用开发实战> 学习总结杂项
- (转)Android开发工具——ADB(Android Debug Bridge) <一>概览
- Android学习笔记:<一>Android 四大组件
- AD+EXCHANGE邮件服务器的迁移实战<一>