导言:
Kotlin:开发Android的新官方语言
http://www.runoob.com/kotlin/kotlin-tutorial.html
http://www.kotlincn.net/docs/reference/basic-syntax.html
? 检查是否null,var name : String?= null
: 类型声明,函数返回类型,类的继承
@ 匿名内部类
in 范围,如:0 in 30
object 相当于static,修饰的类都是静态类
open 可以被继承,被重写,在kotlin中它所有的类默认都是final的,也就是不能被继承
inline 内联函数,简化代码
var 变量,var name = "aaa"
val 常量,val name = "bbb"
实例化 var mSigninBean = SigninBean()
as 类型转换,
Car car = (Car) object;
var car = object as Car
is 相当于instance of,类型检查
field 相当于this
data class 实体类
it 相当于this
foo?.bar
==
if (foo!=null){
foo.bar()
}else{
null
}
foo?:bar
==
if (foo!=null){
foo
}else{
bar
}
foo as? Type
==
if (foo is Type){
foo as Type
}else{
null
}
foo!!---不推荐使用
==
if (foo!=null){
foo
}else{
nullpointerexcepton
}
foo?
==
if (foo!=null){
foo
}else{
不会有空指针异常
}
=---return
override fun layoutId() = R.layout.home_fragment
==
@override
protected int layoutId(){
return R.layout.home_fragment;
}
$---变量
val APP_ID = "15646a06818f61f7b8d7823ca833e1ce"
val id="$APP+ID&aaabbb"
by---代理模式,类委托,属性委托
private val mAdapter by lazy { HomeListAdapter() }
==
private HomeListAdapter mAdapter =new HomeListAdapter();
companion object---伴生对象在类中只能存在一个,类static成员
companion object {
const val ZIP_CODE = "zipCode"
}
const---public final static,否则private final static
companion object {
const val ZIP_CODE = "zipCode"
}
operator---允许自定义操作符的实现,目的就是自定义操作,如getValue和setValue
class Preference<T>(private val context: Context, private val name: String, private val default: T) {
private val prefs: SharedPreferences by lazy { context.getSharedPreferences("default", Context.MODE_PRIVATE) }
operator fun getValue(thisRef: Any?, property: KProperty<*>): T = findPreference(name, default)
@Suppress("UNCHECKED_CAST")
private fun findPreference(name: String, default: T): T = with(prefs) {
.....
res as T
}
}
let---内联函数,简化代码
person?.let { println(it.name)
with---内联函数,简化代码
with(rv_home) {
layoutManager = LinearLayoutManager(context)
adapter = mAdapter
//banner
banner = XBanner(context)
banner.minimumWidth = MATCH_PARENT
banner.layoutParams =
ViewGroup.LayoutParams(MATCH_PARENT, resources.getDimension(R.dimen.dp_120).toInt())
banner.loadImage(GlideImageLoader())
}
==
rv_home.setLayoutManager(new LinearLayoutManager(context));
rv_home.setAdapter(mAdapter);
//banner
banner = new XBanner(context);
banner.setMinimumWidth(MATCH_PARENT);
banner.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT,getResources.getDimension(R.dimen.dp_120).toInt()))
banner.loadImage(new GlideImageLoader());
apply---内联函数,简化代码
mAdapter.apply {
addHeaderView(banner)
setOnLoadMoreListener(this@HomeFragment::loadMore, rv_home)
setOnItemClickListener { adapter, _, position ->
val item = adapter.data[position] as ArticlesBean
val intent = Intent(context, DetailActivity::class.java)
intent.putExtra("url", item.link)
startActivity(intent)
}
}
==
mAdapter.addHeaderView(banner);
mAdapter.setOnLoadMoreListener(() -> loadMore(),rv_home);
mAdapter.setOnItemClickListener((adapter, view, position) -> {
ArticlesBean item= (ArticlesBean) adapter.getData().get(position);
Intent intent=new Intent(getContext(), DetailActivity.class);
intent.putExtra("url",item.link);
startActivity(intent);
});
run---内联函数,简化代码
viewModel.run {
getBanner()
getHomeList(page)
}
==
viewModel.getBanner();
viewModel.getHomeList(page);
let---内联函数,简化代码
intent.getStringExtra("url")?.let {
wv_detail.loadUrl(it)
}
==
wv_detail.loadUrl(intent.getStringExtra("url"));
get()和set()方法
val View.ctx: Context
get() = context
var TextView.textColor: Int
get() = currentTextColor
set(v) = setTextColor(v)
vararg---可变参数,如:设置温度值和文字颜色
private fun bindWeather(vararg views: Pair<Int, TextView>) = views.forEach {
it.second.text = "${it.first}º"
it.second.textColor = ContextCompat.getColor(this, (when (it.first) {
in -50..0 -> android.R.color.holo_red_dark
in 0..15 -> android.R.color.holo_orange_dark
else -> android.R.color.holo_green_dark
}))
}
CoroutineScope---轻量级的线程
launch 启动
join 持续等待,直到子协程执行完成
suspend 挂起线程
withContext 不会创建新的协程
cancel() 取消协程
observable---委托属性,这个委托会帮我们监测我们希望观察的属性的变化
private var backPressedTime by Delegates.observable(0L) { _, old, new ->
if (new - old < 2000) {
finish()
} else {
drawerLayout?.snack("再按返回鍵退出")
}
}
延迟初始化---Koltin中属性在声明的同时也要求要被初始化,否则会报错
1 lateinit var---只能用来修饰类属性,只能用来修饰对象,只能生命周期流程中进行获取或者初始化的变量
lateinit var job: Job
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
job = Job()
}
2: by lazy---只用于常量 val,用来修饰类属性和局部变量
override val toolbar by lazy { find<Toolbar>(R.id.toolbar) }
""" 换行和trimMargin() 删除空白
String text = "First Line\n" +
"Second Line\n" +
"Third Line";
==
val text = """
|First Line
|Second Line
|Third Line
""".trimMargin()
when==switch
when (mKind) {
"diesel" -> fuelType = Constant.FUELTYPE_DIESEL
"petrol" -> fuelType = Constant.FUELTYPE_PETROL
"natural" -> fuelType = Constant.FUELTYPE_NATURAL
"other" -> fuelType = Constant.FUELTYPE_OTHER
}
for循环
for (int i = 1; i <= 10 ; i++) { }
for (int i = 1; i <= 10 ; i+=2) { }
for (String item : list1) { }
for (Map.Entry<String, String> entry: map.entrySet()) {}
for (Car car : cars) {
System.out.println(car.speed);
}
for (Car car : cars) {
if(car.speed > 100) {
System.out.println(car.speed);
}
}
==
for (i in 1..10) { }
for (i in 1..10 step 2) {}
for (item in list1) {}
for ((key, value) in map) {}
cars.forEach {println(it.speed)}
cars.filter { it.speed > 100 }.forEach { println(it.speed)}
list和map
final List<Integer> listOfNumber = Arrays.asList(1, 2, 3, 4);
final Map<Integer, String> keyValue = new HashMap<Integer, String>();
map.put(1, "Amit");
map.put(2, "Ali");
map.put(3, "Mindorks");
==
val listOfNumber = listOf(1, 2, 3, 4)
val keyValue = mapOf(1 to "Amit",
2 to "Ali",
3 to "Mindorks")
方法
public String getHidePhoneNum(String phoneNum) {
.....
return phoneNum
}
==
//函数-fun,名称-getHidePhoneNum,参数-phoneNum: String,返回类型-String
fun getHidePhoneNum(phoneNum: String?): String? {
.....
return phoneNum
}
构造器
public class TestUtil {
public String name;
public int age;
public TestUtil(String name, int age) {
this.name = name;
this.age = age;
}
}
==
class TestUtil(var name: String, var age: Int)
实体类
public class Developer {
private String name;
public Developer(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Developer developer = (Developer) o;
return name != null ? name.equals(developer.name) : developer.name == null;
}
@Override
public int hashCode() {
return name != null ? name.hashCode() : 0;
}
@Override
public String toString() {
return "Developer{" +"name='" + name +'}';
}
}
==
data class Developer(val name: String)
工具类---静态属性和函数
public class TestUtil {
private static Toast mToast;
private static Context context = MyApp.getInstance();
public static void sameToast(String text) {
if (mToast == null) {
mToast = Toast.makeText(context.getApplicationContext(), text, Toast.LENGTH_LONG);
} else {
mToast.setText(text);
mToast.setDuration(Toast.LENGTH_LONG);
}
mToast.show();
}
}
==
object TestUtil {
private var mToast: Toast? = null
private val context: Context = MyApp.getInstance()
fun sameToast(text: String?) {
if (mToast == null) {
mToast = Toast.makeText(context.applicationContext, text, Toast.LENGTH_LONG)
} else {
mToast?.setText(text)
mToast?.duration = Toast.LENGTH_LONG
}
mToast?.show()
}
}
枚举类
enum class Color(val r: Int, val g: Int, val b: Int ){
// 定义枚举常量对象
RED(255, 0, 0), ORANGE(255, 165, 0),
YELLOW(255, 255, 0), GREEN(0, 255, 0),
BLUE(0, 0, 255), INDIGO(75, 0, 130),
VIOLET(238, 130, 238); //最后一个枚举对象需要分号结尾
// 在枚举类中定义函数
fun rgb() = (r * 256 + g) * 256 + b
}
接口
interface MyInterface {
val property: Int
fun bar()
fun foo() {
println("foo")//函数体是可选的
}
}
class Child : MyInterface {
override val property: Int = 29
//没有默认实现的方法必须重写
override fun bar () {
//foo函数体可以不重写
}
}
单例模式1
companion object {
fun newInstance() = HomeFragment()
}
单例模式2
@Synchronized
fun instance(): AppManager {
if (instance == null) {
instance = AppManager()
}
return instance!!
}
单例模式3
1: 初始化
private val homeRepository by lazy { InjectorUtil.getHomeRepository() }
2:
object InjectorUtil {
fun getHomeRepository() = HomeRepository.getInstance(HomeNetWork.getInstance())
}
3: 单例
class HomeRepository private constructor( private val netWork: HomeNetWork) : BaseModel() {
companion object {
@Volatile
private var INSTANCE: HomeRepository? = null
fun getInstance(netWork: HomeNetWork) =
INSTANCE ?: synchronized(this) {
INSTANCE ?: HomeRepository(netWork).also { INSTANCE = it }
}
}
}
4: 单例
class HomeNetWork {
companion object {
@Volatile
private var netWork: HomeNetWork? = null
fun getInstance() = netWork ?: synchronized(this) {
netWork ?: HomeNetWork().also { netWork = it }
}
}
}
MVVM:
//请求数据
var items = ObservableArrayList<ArticlesBean>();
launchUI {
launchFlow { homeRepository.getNaviJson() }
.flatMapConcat {
return@flatMapConcat if (it.isSuccess()) {
navData.addAll(it.data)
it.data.forEach { item -> navTitle.add(item.name) }
launchFlow { homeRepository.getProjectList(page, it.data[0].id) }
} else throw ResponseThrowable(it.errorCode, it.errorMsg)
}
.onStart { defUI.showDialog.postValue(null) }
.flowOn(Dispatchers.IO)
.onCompletion { defUI.dismissDialog.call() }
.catch {
val err = ExceptionHandle.handleException(it)
LogUtils.d("${err.code}: ${err.errMsg}")
}
.collect {
if (it.isSuccess()) items.addAll(it.data.datas)
}
}
//绑定数据
var itemBinding = ItemBinding.of<ArticlesBean>(BR.itemBean, R.layout.item_project_list).bindExtra(BR.listenner,itemOnClickListener)
//子项目点击事件
interface OnItemClickListener {
fun onItemClick(item: ArticlesBean)
}
private val itemOnClickListener = object : OnItemClickListener {
override fun onItemClick(item: ArticlesBean) {
defUI.msgEvent.postValue(Message(0, obj = item))
}
}
override fun handleEvent(msg: Message) {
when (msg.code) {
0 -> {
val bean = msg.obj as ArticlesBean
val intent = Intent().apply {
setClass(activity!!, DetailActivity::class.java)
putExtra("url", bean.link)
}
startActivity(intent)
}
}
}
正常请求数据---非MVVM:
//请求数据
var popularWeb = MutableLiveData<List<UsedWeb>>()
fun getPopularWeb() {
launchGo({
val result = homeRepository.getPopularWeb()
if (result.isSuccess()) {
popularWeb.value = result.data
}
})
}
//绑定数据
private val mAdapter by lazy { MeWebAdapter() }
viewModel.popularWeb.observe(viewLifecycleOwner, Observer {
mAdapter.setNewData(it)
})
with(rv_me_uesd_web) {
layoutManager = LinearLayoutManager(context)
adapter = mAdapter
}
//子项目点击事件
mAdapter.setOnItemClickListener { _, _, position ->
val intent = Intent().apply {
setClass(activity!!, DetailActivity::class.java)
putExtra("url", (mAdapter.data[position] as UsedWeb).link)
}
startActivity(intent)
}
常见使用举例:
1:抽象基类
abstract class BaseActivity : AppCompatActivity() {
/*
* var 变量
* : 数据类型,extend,implement
* ? 可为空
* */
protected var mContext: Context? = null
/*
* val 常量
* */
val xg = "http://www.xxxxx/"
/*
* override 继承
* fun 方法
*
* */
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(getContentViewResId())
mContext = this
initIntentData()
initView()
initData()
}
//抽象方法
abstract fun getContentViewResId(): Int
//可以被重写的方法
open fun initIntentData() {}
abstract fun initView()
abstract fun initData()
}
2:MainActivity主界面
class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedListener {
//各个fragment
private var mAreaFragment: AreaMainFragment? = null
private var mPictureFragment: PictureMainFragment? = null
private var mStationFragment: StationMainFragment? = null
private var mDigFragment: DigMainFragment? = null
private var mAboutFragment: AboutFragment? = null
//设置布局
override fun getContentViewResId(): Int = R.layout.activity_main
override fun initView() {
setToolBar("首页")
//导航按钮设置旋转特效
val toggle = ActionBarDrawerToggle(this, drawerMain, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
drawerMain.addDrawerListener(toggle)
toggle.syncState()
//直接使用导航菜单,并设置默认选中项
navigationMain.setCheckedItem(R.id.nav_menu_area)
navigationMain.setNavigationItemSelectedListener(this)
showArea()
}
private fun showArea() {
//supportFragmentManager==getSupportFragmentManager()
val fragmentTransaction = supportFragmentManager.beginTransaction()
//默认将地区显示出来
fragmentTransaction.add(R.id.fl_main_content, AreaMainFragment.newInstance())
fragmentTransaction.commit()
}
override fun initData() {
}
//将滑动菜单显示出来
override fun onOptionsItemSelected(item: MenuItem): Boolean {
//when==switch
when (item.itemId) {
android.R.id.home -> drawerMain.openDrawer(GravityCompat.START)
}
return true
}
//设置toolbar的标题
fun setToolBar(title: String) {
toolbar.setTitle(title)
setSupportActionBar(toolbar)
val supportActionBar = supportActionBar
if (supportActionBar != null) {
supportActionBar.setDisplayHomeAsUpEnabled(true)
supportActionBar.setDisplayShowHomeEnabled(true)
}
}
//滑动菜单监听事件
override fun onNavigationItemSelected(item: MenuItem): Boolean {
val fragmentTransaction = supportFragmentManager.beginTransaction()
hideAllFragments(fragmentTransaction)
//when==switch
when (item.itemId) {
R.id.nav_menu_area -> {
setToolBar("首页")
/*
mAreaFragment?.let {
fragmentTransaction.show(it)
} ?: AreaMainFragment.newInstance().let {
mAreaFragment = it
fragmentTransaction.add(mAreaFragment, "area")
fragmentTransaction.show(it)
}
等同于
if (mAreaFragment!=null){
fragmentTransaction.show(mAreaFragment)
}else{
mAreaFragment = AreaMainFragment.newInstance()
fragmentTransaction.add(mAreaFragment, "area")
fragmentTransaction.show(mAreaFragment)
}
*/
mAreaFragment?.let {
fragmentTransaction.show(it)
} ?: AreaMainFragment.newInstance().let {
mAreaFragment = it
fragmentTransaction.add(mAreaFragment, "area")
fragmentTransaction.show(it)
}
}
R.id.nav_menu_picture -> {
setToolBar("图片")
if (mPictureFragment == null) {
mPictureFragment = PictureMainFragment.newInstance()
fragmentTransaction.add(R.id.fl_main_content, mPictureFragment, "picture")
fragmentTransaction.show(mPictureFragment)
} else {
fragmentTransaction.show(mPictureFragment)
}
}
R.id.nav_menu_station -> {
setToolBar("名站")
mStationFragment?.let {
fragmentTransaction.show(it)
} ?: StationMainFragment.newInstance().let {
mStationFragment = it
fragmentTransaction.add(R.id.fl_main_content, mStationFragment, "station")
fragmentTransaction.show(it)
}
}
R.id.nav_menu_diagrams -> {
setToolBar("日本")
mDigFragment?.let {
fragmentTransaction.show(it)
} ?: DigMainFragment.newInstance().let {
mDigFragment = it
fragmentTransaction.add(R.id.fl_main_content, mDigFragment, "dig")
fragmentTransaction.show(it)
}
}
R.id.nav_menu_about -> {
setToolBar("关于")
mAboutFragment?.let {
fragmentTransaction.show(it)
} ?: AboutFragment.newInstance().let {
mAboutFragment = it
fragmentTransaction.add(R.id.fl_main_content, mAboutFragment, "about")
fragmentTransaction.show(it)
}
}
}
fragmentTransaction.commit()
//关闭滑动菜单
drawerMain.closeDrawers()
return true
}
//隐藏所有的Fragment
private fun hideAllFragments(transaction: FragmentTransaction) {
/*
* mAreaFragment?.let { transaction.hide(it) }
*
* if (mAreaFragment!=null){
* transaction.hide(mAreaFragment)
* }
* */
mAreaFragment?.let { transaction.hide(it) }
mPictureFragment?.let { transaction.hide(it) }
mStationFragment?.let { transaction.hide(it) }
mDigFragment?.let { transaction.hide(it) }
mAboutFragment?.let { transaction.hide(it) }
}
}
3:AreaMainFragment片段
class AreaMainFragment : BaseFragment() {
//companion object----单例静态方法,可以直接类名+方法名, AreaMainFragment.newInstance()
companion object {
fun newInstance(): AreaMainFragment {
//没有new,没有分号
val bundle = Bundle()
val fragment = AreaMainFragment()
fragment.arguments = bundle
return fragment
}
}
override fun getLayoutResId(): Int = R.layout.fragment_area_main
override fun initView() {
//tabLayout数据适配器
val tabAdapter = AreaTabAdapter(childFragmentManager, getTabData())
vpArea.adapter = tabAdapter
tabLayout.setupWithViewPager(vpArea)
tabLayout.tabMode = MODE_SCROLLABLE
}
override fun initData() {
}
//获取tab数据
private fun getTabData(): ArrayList<Fragment> {
val fragmentList = ArrayList<Fragment>()
val xxxFragment = CommonMainFragment.newInstance("http://..../")
fragmentList.add(zgndFragment)
return fragmentList
}
}
4:AreaTabAdapter适配器
/*
class AreaTabAdapter(var fm: FragmentManager, var fragmentList: ArrayList<Fragment>) : FragmentPagerAdapter(fm) {}
等同于
public class AreaTabAdapter extends FragmentPagerAdapter {
private List<Fragment> fragmentList;
public AreaTabAdapter(FragmentManager fm,ArrayList<Fragment> fragmentList) {
super(fm);
this.fragmentList =fragmentList;
}}
*/
class AreaTabAdapter(var fm: FragmentManager, var fragmentList: ArrayList<Fragment>) : FragmentPagerAdapter(fm) {
//数组
private val TAB_TITLES = arrayOf("中国内地", "台湾", "香港", "日本", "韩国", "马来西亚", "泰国", "欧美", "混血")
/*
override fun getItem(position: Int): Fragment = fragmentList[position]
等同于
@Override
public Fragment getItem(int position) {
return fragmentList[position];
}
*/
override fun getItem(position: Int): Fragment = fragmentList[position]
override fun getCount(): Int = TAB_TITLES.size
override fun getPageTitle(position: Int): CharSequence = TAB_TITLES[position]
}
5:DivListImgBean实体类,不过是有参数,无参数的不行
//无参构造参数的javabean类
data class DivListImgBean(var src: String, var text: String, var detailsUrl: String)
6:下拉刷新上拉加载
override fun lazyLoad() {
super.lazyLoad()
doNetwork(false)
}
//做网络操作
fun doNetwork(isLoadMore: Boolean) {
if (isLoadMore) {
mPageCount++
}
NetUtils.reqOutList(mUrl, mPageCount, object : ZResponse {
override fun <DivListImgBean> onSuccess(dataList: ArrayList<DivListImgBean>) {
if (isLoadMore) {
LogUtil.i("加载更多成功")
mAdapter.addData(dataList)
mAdapter.loadMoreComplete()
} else {
srlLayout.isRefreshing = false
mAdapter.replaceData(dataList)
}
}
override fun onError(error: String?) {
LogUtil.e(error)
if (isLoadMore) {
mAdapter.loadMoreFail()
}
}
})
}
//加载更多
override fun onLoadMoreRequested() {
doNetwork(true)
}
结束!