Skip to content

Commit 1335df4

Browse files
Optimize code
1 parent 6b1c669 commit 1335df4

File tree

12 files changed

+188
-41
lines changed

12 files changed

+188
-41
lines changed

docs/kotlin/delegate.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
## Kotlin 委托用法
2+
3+
先康康最终效果,
4+
5+
### 准备工作
6+
7+
#### 修改基类
8+
9+
只需简单的几步就可以把本库的功能集成到基类,并且不会影响到已有的代码,只是给基类增加了新的方法。
10+
11+
修改步骤如下:
12+
13+
1. 增加 `LoadingState by LoadingStateImpl(), OnReloadListener` 代码,这是给基类实现 `LoadingState``OnReloadListener` 接口,并且把 `LoadingState` 接口委托给 `LoadingStateImpl`
14+
2. 在基类中添加 `open val isDecorated = true` 属性,提供一个可重写的配置变量。
15+
3. 在 Activity 的 `setContentView()` 方法后执行 `decorateContentView(this, isDecorated)`。在 Fragment 的 `onCreateView()` 返回值执行 `view.decorate(this, isDecorated)`
16+
17+
Activity 基类的修改示例:
18+
19+
```kotlin
20+
abstract class BaseActivity(private val layoutRes: Int) : AppCompatActivity(),
21+
LoadingState by LoadingStateImpl(), OnReloadListener {
22+
23+
open val isDecorated = true
24+
25+
override fun onCreate(savedInstanceState: Bundle?) {
26+
super.onCreate(savedInstanceState)
27+
setContentView(layoutRes)
28+
decorateContentView(this, isDecorated)
29+
}
30+
}
31+
```
32+
33+
Fragment 基类的修改示例:
34+
35+
```kotlin
36+
abstract class BaseFragment(private val layoutRes: Int) : Fragment(),
37+
LoadingState by LoadingStateImpl(), OnReloadListener {
38+
39+
open val isDecorated = true
40+
41+
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
42+
val root = inflater.inflate(layoutRes, container, false)
43+
return root.decorate(this, isDecorated)
44+
}
45+
}
46+
```
47+
48+
这样改造基类后会得到以下的增强:
49+
50+
- 在不影响已有代码的情况下,增加了 [LoadingState](https://github.com/DylanCaiCoding/LoadingStateView/blob/master/loadingstateview-ktx/src/main/java/com/dylanc/loadingstateview/LoadingState.kt)`OnReloadListener` 提供的常用方法。
51+
- 如果担心万一会遇到什么兼容问题,那么在页面重写 `override val isDecorated = false` 属性就会把新增的功能禁用,即使调用了方法也不会生效。
52+
53+
#### 注册默认的标题栏和缺省页
54+
55+
通常项目都有各自的标题栏封装,比如 `<include/>` 的标题栏布局或者自定义的标题栏控件,我们能基于此实现 `ToolbarViewDelegate`
56+
57+
```kotlin
58+
LoadingStateView.setViewDelegatePool {
59+
register(ToolbarViewDelegate(), LoadingViewDelegate(), ErrorViewDelegate())
60+
}
61+
```
File renamed without changes.

loadingstateview-ktx/src/main/java/com/dylanc/loadingstateview/ToolbarViewDelegate.kt renamed to loadingstateview-ktx/src/main/java/com/dylanc/loadingstateview/BaseToolbarViewDelegate.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import android.view.LayoutInflater
2020
import android.view.View
2121
import android.view.ViewGroup
2222

23-
abstract class ToolbarViewDelegate : LoadingStateView.ViewDelegate(ViewType.TITLE) {
23+
abstract class BaseToolbarViewDelegate : LoadingStateView.ViewDelegate(ViewType.TITLE) {
2424
internal lateinit var config: ToolbarConfig
2525

2626
override fun onCreateView(inflater: LayoutInflater, parent: ViewGroup) =

loadingstateview-ktx/src/main/java/com/dylanc/loadingstateview/LoadingState.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package com.dylanc.loadingstateview
1818

1919
import android.app.Activity
2020
import android.view.View
21-
import android.view.ViewGroup
2221
import androidx.annotation.StringRes
2322
import androidx.fragment.app.Fragment
2423

@@ -62,5 +61,5 @@ interface LoadingState {
6261

6362
fun ToolbarViewDelegate(
6463
title: String? = null, navBtnType: NavBtnType = NavBtnType.ICON, block: (ToolbarConfig.() -> Unit)? = null
65-
): ToolbarViewDelegate
64+
): BaseToolbarViewDelegate
6665
}

loadingstateview-ktx/src/main/java/com/dylanc/loadingstateview/LoadingStateImpl.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,15 @@ class LoadingStateImpl : LoadingState {
9393
}
9494

9595
override fun updateToolbar(block: ToolbarConfig.() -> Unit) {
96-
updateView<ToolbarViewDelegate>(ViewType.TITLE) { bind(config.apply(block)) }
96+
updateView<BaseToolbarViewDelegate>(ViewType.TITLE) { bind(config.apply(block)) }
9797
}
9898

9999
override fun <T : LoadingStateView.ViewDelegate> updateView(viewType: Any, block: T.() -> Unit) {
100100
loadingStateView?.getViewDelegate<T>(viewType)?.apply(block)
101101
}
102102

103103
override fun ToolbarViewDelegate(title: String?, navBtnType: NavBtnType, block: (ToolbarConfig.() -> Unit)?) =
104-
requireNotNull(loadingStateView?.getViewDelegate<ToolbarViewDelegate>(ViewType.TITLE)) {
104+
requireNotNull(loadingStateView?.getViewDelegate<BaseToolbarViewDelegate>(ViewType.TITLE)) {
105105
"ToolbarViewDelegate must be registered before."
106106
}.apply {
107107
config = ToolbarConfig(title, navBtnType).apply { block?.invoke(this) }

loadingstateview-ktx/src/main/java/com/dylanc/loadingstateview/ToolbarConfig.kt

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,36 +31,47 @@ enum class NavBtnType {
3131
class ToolbarConfig(
3232
var title: String? = null,
3333
var navBtnType: NavBtnType = NavBtnType.ICON,
34-
@DrawableRes var navIcon: Int? = null,
35-
var navText: String? = null,
36-
var onNavClickListener: View.OnClickListener = View.OnClickListener {
37-
val context = it.context
38-
if (context is Activity) context.finish()
39-
},
40-
@DrawableRes var rightIcon: Int? = null,
41-
var rightText: String? = null,
42-
var onRightClickListener: View.OnClickListener? = null,
43-
val extras: HashMap<String, Any?> = HashMap()
44-
)
34+
val extras: HashMap<String, Any?> = HashMap(),
35+
) {
36+
@DrawableRes
37+
var navIcon: Int? = null
38+
private set
39+
var navText: String? = null
40+
private set
41+
var onNavClickListener = View.OnClickListener {
42+
if (it.context is Activity) {
43+
(it.context as Activity).finish()
44+
}
45+
}
46+
private set
4547

46-
fun ToolbarConfig.navIcon(@DrawableRes icon: Int, listener: View.OnClickListener) {
47-
navIcon = icon
48-
onNavClickListener = listener
49-
}
48+
@DrawableRes
49+
var rightIcon: Int? = null
50+
private set
51+
var rightText: String? = null
52+
private set
53+
var onRightClickListener: View.OnClickListener? = null
54+
private set
5055

51-
fun ToolbarConfig.navText(text: String, listener: View.OnClickListener) {
52-
navText = text
53-
onNavClickListener = listener
54-
}
56+
fun navIcon(@DrawableRes icon: Int, listener: View.OnClickListener) {
57+
navIcon = icon
58+
onNavClickListener = listener
59+
}
5560

56-
fun ToolbarConfig.rightIcon(@DrawableRes icon: Int, listener: View.OnClickListener) {
57-
rightIcon = icon
58-
onRightClickListener = listener
59-
}
61+
fun navText(text: String, listener: View.OnClickListener) {
62+
navText = text
63+
onNavClickListener = listener
64+
}
65+
66+
fun rightIcon(@DrawableRes icon: Int, listener: View.OnClickListener) {
67+
rightIcon = icon
68+
onRightClickListener = listener
69+
}
6070

61-
fun ToolbarConfig.rightText(text: String, listener: View.OnClickListener) {
62-
rightText = text
63-
onRightClickListener = listener
71+
fun rightText(text: String, listener: View.OnClickListener) {
72+
rightText = text
73+
onRightClickListener = listener
74+
}
6475
}
6576

6677
fun <T> toolbarExtras() = object : ReadWriteProperty<ToolbarConfig, T?> {

loadingstateview/src/main/java/com/dylanc/loadingstateview/LoadingStateView.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.dylanc.loadingstateview
1818

1919
import android.app.Activity
20+
import android.content.Context
2021
import android.view.LayoutInflater
2122
import android.view.View
2223
import android.view.ViewGroup
@@ -109,7 +110,7 @@ class LoadingStateView @JvmOverloads constructor(
109110
}
110111

111112
private fun DecorViewDelegate.createDecorView() =
112-
onCreateDecorView(LayoutInflater.from(contentView.context)).also { decorView ->
113+
onCreateDecorView(contentView.context, LayoutInflater.from(contentView.context)).also { decorView ->
113114
contentView.layoutParams?.let {
114115
decorView.layoutParams = if (it is ConstraintLayout.LayoutParams) ConstraintLayout.LayoutParams(it) else it
115116
}
@@ -201,7 +202,7 @@ class LoadingStateView @JvmOverloads constructor(
201202
}
202203

203204
abstract class DecorViewDelegate {
204-
abstract fun onCreateDecorView(inflater: LayoutInflater): View
205+
abstract fun onCreateDecorView(context: Context, inflater: LayoutInflater): View
205206
abstract fun getContentParent(decorView: View): ViewGroup
206207
}
207208

@@ -213,7 +214,7 @@ class LoadingStateView @JvmOverloads constructor(
213214
getView(it.viewType)
214215
})
215216

216-
override fun onCreateDecorView(inflater: LayoutInflater) =
217+
override fun onCreateDecorView(context: Context, inflater: LayoutInflater) =
217218
LinearLayout(inflater.context).apply {
218219
orientation = LinearLayout.VERTICAL
219220
contentParent = FrameLayout(context)

sample-kotlin/src/main/java/com/dylanc/loadingstateview/sample/kotlin/App.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ import android.app.Application
44
import com.dylanc.loadingstateview.LoadingStateView
55
import com.dylanc.loadingstateview.sample.kotlin.delegate.ErrorViewDelegate
66
import com.dylanc.loadingstateview.sample.kotlin.delegate.LoadingViewDelegate
7-
import com.dylanc.loadingstateview.sample.kotlin.delegate.DefaultToolbarViewDelegate
7+
import com.dylanc.loadingstateview.sample.kotlin.delegate.ToolbarViewDelegate
88

99
class App : Application() {
1010

1111
override fun onCreate() {
1212
super.onCreate()
1313
LoadingStateView.setViewDelegatePool {
14-
register(DefaultToolbarViewDelegate(), LoadingViewDelegate(), ErrorViewDelegate())
14+
register(ToolbarViewDelegate(), LoadingViewDelegate(), ErrorViewDelegate())
1515
}
1616
}
1717
}

sample-kotlin/src/main/java/com/dylanc/loadingstateview/sample/kotlin/delegate/LoadingViewDelegate.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,17 @@
1616

1717
package com.dylanc.loadingstateview.sample.kotlin.delegate
1818

19-
import com.dylanc.loadingstateview.LoadingStateView.ViewDelegate
20-
import android.view.ViewGroup
2119
import android.view.LayoutInflater
2220
import android.view.View
21+
import android.view.ViewGroup
2322
import com.dylanc.loadingstateview.LoadingStateView
2423
import com.dylanc.loadingstateview.ViewType
2524
import com.dylanc.loadingstateview.sample.kotlin.R
2625

2726
/**
2827
* @author Dylan Cai
2928
*/
30-
class LoadingViewDelegate : ViewDelegate(ViewType.LOADING) {
29+
class LoadingViewDelegate : LoadingStateView.ViewDelegate(ViewType.LOADING) {
3130

3231
override fun onCreateView(inflater: LayoutInflater, parent: ViewGroup): View =
3332
inflater.inflate(R.layout.layout_loading, parent, false)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (c) 2019. Dylan Cai
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.dylanc.loadingstateview.sample.kotlin.delegate
17+
18+
import android.app.Activity
19+
import android.content.Context
20+
import android.view.LayoutInflater
21+
import android.view.View
22+
import android.view.ViewGroup
23+
import androidx.appcompat.widget.Toolbar
24+
import com.dylanc.loadingstateview.LoadingStateView
25+
import com.dylanc.loadingstateview.sample.kotlin.R
26+
27+
/**
28+
* @author Dylan Cai
29+
*/
30+
class ScrollingDecorViewDelegate(private val title: String) : LoadingStateView.DecorViewDelegate() {
31+
32+
override fun onCreateDecorView(context: Context, inflater: LayoutInflater): View {
33+
val view = inflater.inflate(R.layout.layout_scrolling_toolbar, null)
34+
val toolbar: Toolbar = view.findViewById(R.id.toolbar)
35+
toolbar.title = title
36+
toolbar.setNavigationOnClickListener {
37+
if (context is Activity) context.finish()
38+
}
39+
return view
40+
}
41+
42+
override fun getContentParent(decorView: View): ViewGroup {
43+
return decorView.findViewById(R.id.content_parent)
44+
}
45+
}

0 commit comments

Comments
 (0)