├── .gitignore
├── LICENSE
├── README.md
├── build.gradle
├── demo
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── angcyo
│ │ └── dslitem
│ │ └── demo
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── angcyo
│ │ │ └── dslitem
│ │ │ └── demo
│ │ │ ├── MainActivity.kt
│ │ │ └── dslitem
│ │ │ └── SingleImageItem.kt
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable-xhdpi
│ │ └── png.png
│ │ ├── drawable
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ ├── activity_main.xml
│ │ └── item_single_image.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── angcyo
│ └── dslitem
│ └── demo
│ └── ExampleUnitTest.kt
├── dslitem
├── .gitignore
├── README.md
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── angcyo
│ │ ├── drawable
│ │ ├── DslAttrBadgeDrawable.kt
│ │ └── DslBadgeDrawable.kt
│ │ ├── extend
│ │ ├── IToText.kt
│ │ └── IToValue.kt
│ │ ├── item
│ │ ├── AnimEx.kt
│ │ ├── DslBaseEditItem.kt
│ │ ├── DslBaseInfoItem.kt
│ │ ├── DslBaseLabelItem.kt
│ │ ├── DslBottomButtonItem.kt
│ │ ├── DslBottomItem.kt
│ │ ├── DslButtonItem.kt
│ │ ├── DslGridItem.kt
│ │ ├── DslLabelEditItem.kt
│ │ ├── DslLabelTextItem.kt
│ │ ├── DslNestedRecyclerItem.kt
│ │ ├── DslSwitchInfoItem.kt
│ │ ├── DslTextInfoItem.kt
│ │ ├── DslTextItem.kt
│ │ ├── LibEx.kt
│ │ ├── RAnimatorListener.kt
│ │ ├── base
│ │ │ ├── LibInitProvider.kt
│ │ │ ├── RAnimationListener.kt
│ │ │ └── SingleTextWatcher.kt
│ │ └── style
│ │ │ ├── ButtonStyleConfig.kt
│ │ │ ├── EditStyleConfig.kt
│ │ │ ├── IAutoInitItem.kt
│ │ │ ├── IBadgeItem.kt
│ │ │ ├── IBodyItem.kt
│ │ │ ├── IButtonItem.kt
│ │ │ ├── ICheckGroupItem.kt
│ │ │ ├── ICheckItem.kt
│ │ │ ├── IDesItem.kt
│ │ │ ├── IEditItem.kt
│ │ │ ├── ILabelItem.kt
│ │ │ ├── INestedRecyclerItem.kt
│ │ │ ├── ISwitchItem.kt
│ │ │ ├── ITextInfoItem.kt
│ │ │ ├── ITextItem.kt
│ │ │ ├── ImageStyleConfig.kt
│ │ │ ├── TextStyleConfig.kt
│ │ │ └── ViewStyleConfig.kt
│ │ └── widget
│ │ ├── BadgeTextView.kt
│ │ ├── CharLengthFilter.kt
│ │ ├── DslGravity.kt
│ │ ├── DslSelector.kt
│ │ ├── IBadgeView.kt
│ │ ├── ITouchDelegate.kt
│ │ ├── ITouchHold.kt
│ │ ├── SwitchButton.kt
│ │ ├── TouchActionDelegate.kt
│ │ ├── TouchListener.kt
│ │ ├── ViewGroupEx.kt
│ │ └── recycler
│ │ ├── DslRecyclerView.kt
│ │ ├── GridLayoutManagerWrap.kt
│ │ ├── LinearLayoutManagerWrap.kt
│ │ ├── RecyclerEx.kt
│ │ ├── ScrollHelper.kt
│ │ ├── ScrollPositionConfig.kt
│ │ └── StaggeredGridLayoutManagerWrap.kt
│ └── res
│ ├── drawable-anydpi
│ ├── lib_audio_cover_tip.xml
│ ├── lib_audio_tip.xml
│ ├── lib_check_checked.xml
│ ├── lib_check_normal.xml
│ ├── lib_icon_edit_tip.xml
│ ├── lib_image_remove.xml
│ ├── lib_image_tip.xml
│ ├── lib_video_cover_tip.xml
│ └── lib_video_tip.xml
│ ├── drawable-v21
│ ├── lib_bg2_selector.xml
│ ├── lib_bg_selector.xml
│ └── lib_ripple_shape.xml
│ ├── drawable
│ ├── lib_bottom_line_selector.xml
│ ├── lib_check_selector.xml
│ ├── lib_dark_bottom_line_shape.xml
│ ├── lib_duration_bg_shape.xml
│ ├── lib_image_remove_circle_selector.xml
│ ├── lib_remove_circle_shape.xml
│ ├── lib_theme_bottom_line_shape.xml
│ ├── lib_theme_circle_shape.xml
│ └── lib_theme_press_circle_shape.xml
│ ├── layout
│ ├── dsl_bottom_button_item.xml
│ ├── dsl_bottom_item.xml
│ ├── dsl_button_item.xml
│ ├── dsl_edit_item.xml
│ ├── dsl_extent_switch_item.xml
│ ├── dsl_extent_text_item.xml
│ ├── dsl_grid_item.xml
│ ├── dsl_info_item.xml
│ ├── dsl_label_edit_item.xml
│ ├── dsl_label_item.xml
│ ├── dsl_label_text_item.xml
│ ├── dsl_nested_recycler_item.xml
│ ├── dsl_text_item.xml
│ ├── layout_check.xml
│ └── lib_tab_item_layout.xml
│ └── values
│ ├── attr_badge_view.xml
│ ├── attr_dsl_recycler_view.xml
│ ├── item_ids.xml
│ ├── item_styles.xml
│ └── switch_button_attrs.xml
├── dslitem2
├── .gitignore
├── README.md
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── angcyo
│ │ └── item2
│ │ ├── DslBannerItem.kt
│ │ ├── ILoopAdapterItem.kt
│ │ └── widget
│ │ └── recycler
│ │ ├── DrawableIndicator.kt
│ │ ├── InvalidateProperty.kt
│ │ ├── LoopRecyclerView.kt
│ │ ├── LoopSnapHelper.kt
│ │ └── RequestLayoutProperty.kt
│ └── res
│ ├── drawable
│ ├── lib_indicator_focus.xml
│ └── lib_indicator_normal.xml
│ ├── layout
│ └── dsl_banner_item.xml
│ └── values
│ ├── attr_border_view.xml
│ ├── attr_drawable_indicator.xml
│ ├── attr_loop_recycler_view.xml
│ └── item2_values.xml
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── png
└── item.png
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 | .idea
16 | /UICore
17 | /UICoreEx
18 | /apk
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 angcyo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DslItem
2 | 基于`DslAdapter`的`DslAdapterItem`库, 挑选能用的, 把界面拼起来.
3 |
4 | 请先了解[DslAdapter](https://github.com/angcyo/DslAdapter).
5 |
6 | 针对[DslAdapter](https://github.com/angcyo/DslAdapter)库, 编写的一些常用的`DslAdapterItem`, 欢迎PR, 欢迎提出想要的`Item`建议.
7 |
8 |   
9 | 
10 |
11 | # 愿望
12 |
13 | 安卓界面的编写形式应该是`Item+Item+Item`,轻松+高度可复用:
14 |
15 | 如下形式:
16 |
17 | ```kotlin
18 | renderAdapter{
19 | 头部Item()
20 | 轮播图Item()
21 | 列表Item()
22 | 列表Item()
23 | 列表Item()
24 | ...
25 | 尾部Item()
26 | 加载更多Item()
27 | }
28 | ```
29 |
30 | 借助[DslAdapter](https://github.com/angcyo/DslAdapter)库,再结合本库,把界面`+`起来.
31 |
32 | 希望广大同仁 能与我共同维护此库 欢迎PR.
33 |
34 |
35 | 
36 |
37 | > 对应`Item`的属性和说明, 请依赖之后在源码内查看. 因为太丰富了, 源码看了就能懂.
38 |
39 | # 使用`JitPack`的方式, 引入库.
40 |
41 | ## 根目录中的 `build.gradle`
42 |
43 | ```kotlin
44 | allprojects {
45 | repositories {
46 | ...
47 | maven { url 'https://jitpack.io' }
48 | }
49 | }
50 | ```
51 |
52 | ## APP目录中的 `build.gradle`
53 |
54 | ```kotlin
55 | dependencies {
56 | implementation 'com.github.angcyo:DslItem:1.0.9'
57 | }
58 | ```
59 |
60 | ---
61 | **群内有`各(pian)种(ni)各(jin)样(qun)`的大佬,等你来撩.**
62 |
63 | # 联系作者
64 |
65 | [点此QQ对话](http://wpa.qq.com/msgrd?v=3&uin=664738095&site=qq&menu=yes) `该死的空格` [点此快速加群](https://shang.qq.com/wpa/qunwpa?idkey=cbcf9a42faf2fe730b51004d33ac70863617e6999fce7daf43231f3cf2997460)
66 |
67 | [开源地址](https://github.com/angcyo/DslAdapter)
68 |
69 | 
70 |
71 | 
72 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.8.21'
5 | repositories {
6 | google()
7 | mavenCentral()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:7.4.2'
11 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | mavenCentral()
22 | maven { url 'https://jitpack.io' }
23 | }
24 | }
25 |
26 | task clean(type: Delete) {
27 | delete rootProject.buildDir
28 | }
29 |
--------------------------------------------------------------------------------
/demo/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/demo/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-parcelize'
4 | apply plugin: 'kotlin-kapt'
5 |
6 | android {
7 | compileSdk Integer.parseInt(C_SDK)
8 |
9 | defaultConfig {
10 | applicationId "com.angcyo.dslitem.demo"
11 | minSdk Integer.parseInt(M_SDK)
12 | targetSdk Integer.parseInt(T_SDK)
13 | versionCode 1
14 | versionName "1.0"
15 |
16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
17 | }
18 |
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 | namespace 'com.angcyo.dslitem.demo'
26 |
27 | }
28 |
29 | dependencies {
30 | implementation fileTree(dir: 'libs', include: ['*.jar'])
31 | implementation 'androidx.appcompat:appcompat:1.6.1'
32 | implementation 'androidx.core:core-ktx:1.10.0'
33 | implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
34 | testImplementation 'junit:junit:4.13.2'
35 | androidTestImplementation 'androidx.test.ext:junit:1.1.5'
36 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
37 |
38 | implementation project(":dslitem")
39 | implementation project(":dslitem2")
40 |
41 | def glide_version = "4.15.1"
42 | //https://muyangmin.github.io/glide-docs-cn/
43 | //https://github.com/bumptech/glide
44 | implementation "com.github.bumptech.glide:glide:$glide_version"
45 | kapt "com.github.bumptech.glide:compiler:$glide_version"
46 | }
47 |
--------------------------------------------------------------------------------
/demo/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/demo/src/androidTest/java/com/angcyo/dslitem/demo/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.dslitem.demo
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.angcyo.dslitem.demo", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/demo/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
14 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/angcyo/dslitem/demo/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.dslitem.demo
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import androidx.recyclerview.widget.RecyclerView
6 | import com.angcyo.dsladapter.dpi
7 | import com.angcyo.dsladapter.initDslAdapter
8 | import com.angcyo.dslitem.demo.dslitem.SingleImageItem
9 | import com.angcyo.item.DslBaseEditItem
10 | import com.angcyo.item.DslBaseInfoItem
11 | import com.angcyo.item.DslBaseLabelItem
12 | import com.angcyo.item.DslButtonItem
13 | import com.angcyo.item.DslGridItem
14 | import com.angcyo.item.DslLabelEditItem
15 | import com.angcyo.item.DslLabelTextItem
16 | import com.angcyo.item.DslSwitchInfoItem
17 | import com.angcyo.item.DslTextInfoItem
18 | import com.angcyo.item.DslTextItem
19 | import com.angcyo.item.style.itemEditText
20 | import com.angcyo.item.style.renderNestedAdapter
21 | import com.angcyo.item2.DslBannerItem
22 |
23 | class MainActivity : AppCompatActivity() {
24 |
25 | override fun onCreate(savedInstanceState: Bundle?) {
26 | super.onCreate(savedInstanceState)
27 | setContentView(R.layout.activity_main)
28 |
29 | findViewById(R.id.recycler_view)?.initDslAdapter {
30 | render {
31 | DslBannerItem()() {
32 | itemHeight = 200 * dpi
33 | renderNestedAdapter {
34 | SingleImageItem()() {
35 | itemImageUri =
36 | "https://scpic.chinaz.net/files/default/imgs/2023-04-26/22c25fc6b5b32280.jpg"
37 | }
38 | SingleImageItem()() {
39 | itemImageUri =
40 | "https://scpic.chinaz.net/files/default/imgs/2023-04-26/927afbe5af4fec22.jpg"
41 | }
42 | }
43 | }
44 |
45 | DslBaseEditItem()() {
46 | itemEditText = this::class.java.simpleName
47 | editItemConfig._lastEditSelectionStart = itemEditText?.length ?: -1
48 | configEditTextStyle {
49 | hint = "请输入..."
50 | }
51 | }
52 |
53 | DslBaseInfoItem()() {
54 | itemInfoText = this::class.java.simpleName
55 | }
56 |
57 | DslBaseLabelItem()() {
58 | itemLabelText = this::class.java.simpleName
59 | }
60 |
61 | DslButtonItem()() {
62 | itemButtonText = this::class.java.simpleName
63 | }
64 |
65 | DslButtonItem()() {
66 | itemButtonText = this::class.java.simpleName
67 | configButtonStyle {
68 | themeStyle()
69 | }
70 | }
71 | DslButtonItem()() {
72 | itemButtonText = this::class.java.simpleName
73 | configButtonStyle {
74 | fillStyle()
75 | }
76 | }
77 | DslButtonItem()() {
78 | itemButtonText = this::class.java.simpleName
79 | configButtonStyle {
80 | solidStyle()
81 | }
82 | }
83 |
84 | DslGridItem()() {
85 | itemText = this::class.java.simpleName
86 | itemIcon = R.drawable.png
87 | }
88 |
89 | DslLabelEditItem()() {
90 | itemLabelText = "Label"
91 | itemEditText = this::class.java.simpleName
92 | editItemConfig._lastEditSelectionStart = itemEditText?.length ?: -1
93 |
94 | configEditTextStyle {
95 | hint = "请输入..."
96 | }
97 | }
98 |
99 | DslLabelTextItem()() {
100 | itemLabelText = "Label"
101 | itemText = this::class.java.simpleName
102 | }
103 |
104 | DslSwitchInfoItem()() {
105 | itemInfoText = this::class.java.simpleName
106 | }
107 |
108 | DslTextInfoItem()() {
109 | itemInfoText = this::class.java.simpleName
110 | itemDarkText = "DarkText"
111 | }
112 |
113 | DslTextItem()() {
114 | itemText = this::class.java.simpleName
115 | }
116 | }
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/angcyo/dslitem/demo/dslitem/SingleImageItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.dslitem.demo.dslitem
2 |
3 | import com.angcyo.dsladapter.DslAdapterItem
4 | import com.angcyo.dsladapter.DslViewHolder
5 | import com.angcyo.dslitem.demo.R
6 | import com.bumptech.glide.Glide
7 |
8 | /**
9 | * Email:angcyo@126.com
10 | * @author angcyo
11 | * @date 2023/04/28
12 | */
13 | class SingleImageItem : DslAdapterItem() {
14 |
15 | var itemImageUri: String? = null
16 |
17 | init {
18 | itemLayoutId = R.layout.item_single_image
19 | }
20 |
21 | override fun onItemBind(
22 | itemHolder: DslViewHolder,
23 | itemPosition: Int,
24 | adapterItem: DslAdapterItem,
25 | payloads: List
26 | ) {
27 | super.onItemBind(itemHolder, itemPosition, adapterItem, payloads)
28 |
29 | itemHolder.img(R.id.lib_image_view)?.let {
30 | Glide.with(itemHolder.itemView).load(itemImageUri).centerCrop().into(it)
31 | }
32 | }
33 |
34 | }
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/png.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angcyo/DslItem/92c5a7c665636c7af4c1f497c41657653ae80326/demo/src/main/res/drawable-xhdpi/png.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/item_single_image.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angcyo/DslItem/92c5a7c665636c7af4c1f497c41657653ae80326/demo/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angcyo/DslItem/92c5a7c665636c7af4c1f497c41657653ae80326/demo/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angcyo/DslItem/92c5a7c665636c7af4c1f497c41657653ae80326/demo/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angcyo/DslItem/92c5a7c665636c7af4c1f497c41657653ae80326/demo/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angcyo/DslItem/92c5a7c665636c7af4c1f497c41657653ae80326/demo/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angcyo/DslItem/92c5a7c665636c7af4c1f497c41657653ae80326/demo/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angcyo/DslItem/92c5a7c665636c7af4c1f497c41657653ae80326/demo/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angcyo/DslItem/92c5a7c665636c7af4c1f497c41657653ae80326/demo/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angcyo/DslItem/92c5a7c665636c7af4c1f497c41657653ae80326/demo/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angcyo/DslItem/92c5a7c665636c7af4c1f497c41657653ae80326/demo/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/demo/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #6200EE
4 | #3700B3
5 | #03DAC5
6 |
7 |
--------------------------------------------------------------------------------
/demo/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | DslItem
3 |
4 |
--------------------------------------------------------------------------------
/demo/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/demo/src/test/java/com/angcyo/dslitem/demo/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.dslitem.demo
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/dslitem/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/dslitem/README.md:
--------------------------------------------------------------------------------
1 | # dslitem
2 | 2020-01-01
3 |
4 | 常用 `DslItem`, 如果此库丰富了, 那么UI, 就是`乐高`拼出来的.
5 |
6 | ```kotlin
7 | renderDslAdapter{
8 | dslItem1()
9 | dslItem2()
10 | dslItem3()
11 | ...
12 | dslItemX()
13 | dslItemY()
14 | dslItemZ()
15 | }
16 | ```
--------------------------------------------------------------------------------
/dslitem/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 |
4 | android {
5 | compileSdk Integer.parseInt(C_SDK)
6 |
7 | defaultConfig {
8 | vectorDrawables.useSupportLibrary = true
9 |
10 | minSdk Integer.parseInt(M_SDK)
11 | targetSdk Integer.parseInt(T_SDK)
12 |
13 | consumerProguardFiles 'consumer-rules.pro'
14 | }
15 | namespace 'com.angcyo.item'
16 | }
17 |
18 | dependencies {
19 | //https://mvnrepository.com/artifact/androidx.appcompat/appcompat
20 | implementation 'androidx.appcompat:appcompat:1.6.1'
21 |
22 | //https://mvnrepository.com/artifact/androidx.constraintlayout/constraintlayout
23 | api 'androidx.constraintlayout:constraintlayout:2.1.4'
24 |
25 | //https://mvnrepository.com/artifact/androidx.recyclerview/recyclerview
26 | api 'androidx.recyclerview:recyclerview:1.3.0'
27 |
28 | //https://github.com/angcyo/DslAdapter
29 | api 'com.github.angcyo:DslAdapter:6.0.1'
30 |
31 | //https://github.com/angcyo/DslSpan
32 | api 'com.github.angcyo:DslSpan:1.1.0'
33 |
34 | //https://github.com/angcyo/DslButton
35 | api 'com.github.angcyo:DslButton:1.3.0'
36 | }
37 |
--------------------------------------------------------------------------------
/dslitem/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angcyo/DslItem/92c5a7c665636c7af4c1f497c41657653ae80326/dslitem/consumer-rules.pro
--------------------------------------------------------------------------------
/dslitem/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/dslitem/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/drawable/DslAttrBadgeDrawable.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.drawable
2 |
3 | import android.content.Context
4 | import android.graphics.Canvas
5 | import android.graphics.Color
6 | import android.util.AttributeSet
7 | import android.view.Gravity
8 | import com.angcyo.dpi
9 | import com.angcyo.item.R
10 |
11 | /**
12 | * 角标
13 | * Email:angcyo@126.com
14 | * @author angcyo
15 | * @date 2019/12/13
16 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
17 | */
18 | open class DslAttrBadgeDrawable : DslBadgeDrawable() {
19 |
20 | /**是否要绘制角标*/
21 | var drawBadge: Boolean = true
22 |
23 | override fun initAttribute(context: Context, attributeSet: AttributeSet?) {
24 | val typedArray =
25 | context.obtainStyledAttributes(attributeSet, R.styleable.DslAttrBadgeDrawable)
26 | drawBadge = typedArray.getBoolean(R.styleable.DslAttrBadgeDrawable_r_draw_badge, drawBadge)
27 | gradientSolidColor =
28 | typedArray.getColor(
29 | R.styleable.DslAttrBadgeDrawable_r_badge_solid_color,
30 | Color.RED
31 | )
32 | badgeTextColor =
33 | typedArray.getColor(
34 | R.styleable.DslAttrBadgeDrawable_r_badge_text_color,
35 | Color.WHITE
36 | )
37 | badgeGravity = typedArray.getInt(
38 | R.styleable.DslAttrBadgeDrawable_r_badge_gravity,
39 | Gravity.TOP or Gravity.RIGHT
40 | )
41 | badgeOffsetX = typedArray.getDimensionPixelOffset(
42 | R.styleable.DslAttrBadgeDrawable_r_badge_offset_x,
43 | badgeOffsetX
44 | )
45 | badgeCircleRadius = typedArray.getDimensionPixelOffset(
46 | R.styleable.DslAttrBadgeDrawable_r_badge_circle_radius,
47 | 4 * dpi
48 | )
49 | val badgeRadius = typedArray.getDimensionPixelOffset(
50 | R.styleable.DslAttrBadgeDrawable_r_badge_radius,
51 | 10 * dpi
52 | )
53 | cornerRadius(badgeRadius.toFloat())
54 | badgeOffsetY = typedArray.getDimensionPixelOffset(
55 | R.styleable.DslAttrBadgeDrawable_r_badge_offset_y,
56 | badgeOffsetY
57 | )
58 | badgePaddingLeft = typedArray.getDimensionPixelOffset(
59 | R.styleable.DslAttrBadgeDrawable_r_badge_padding_left,
60 | 4 * dpi
61 | )
62 | badgePaddingRight = typedArray.getDimensionPixelOffset(
63 | R.styleable.DslAttrBadgeDrawable_r_badge_padding_right,
64 | 4 * dpi
65 | )
66 | badgePaddingTop = typedArray.getDimensionPixelOffset(
67 | R.styleable.DslAttrBadgeDrawable_r_badge_padding_top,
68 | 0
69 | )
70 | badgePaddingBottom = typedArray.getDimensionPixelOffset(
71 | R.styleable.DslAttrBadgeDrawable_r_badge_padding_bottom,
72 | 0
73 | )
74 | //脚本文本内容
75 | badgeText = typedArray.getString(R.styleable.DslAttrBadgeDrawable_r_badge_text)
76 | badgeTextSize = typedArray.getDimensionPixelOffset(
77 | R.styleable.DslAttrBadgeDrawable_r_badge_text_size,
78 | 12 * dpi
79 | ).toFloat()
80 |
81 | //自定义的背景
82 | originDrawable =
83 | typedArray.getDrawable(R.styleable.DslAttrBadgeDrawable_r_badge_bg_drawable)
84 |
85 | badgeTextOffsetX = typedArray.getDimensionPixelOffset(
86 | R.styleable.DslAttrBadgeDrawable_r_badge_text_offset_x,
87 | badgeTextOffsetX
88 | )
89 |
90 | badgeTextOffsetY = typedArray.getDimensionPixelOffset(
91 | R.styleable.DslAttrBadgeDrawable_r_badge_text_offset_y,
92 | badgeTextOffsetY
93 | )
94 |
95 | badgeCircleOffsetX = typedArray.getDimensionPixelOffset(
96 | R.styleable.DslAttrBadgeDrawable_r_badge_circle_offset_x,
97 | badgeTextOffsetX
98 | )
99 |
100 | badgeCircleOffsetY = typedArray.getDimensionPixelOffset(
101 | R.styleable.DslAttrBadgeDrawable_r_badge_circle_offset_y,
102 | badgeTextOffsetY
103 | )
104 | typedArray.recycle()
105 | super.initAttribute(context, attributeSet)
106 | }
107 |
108 | override fun draw(canvas: Canvas) {
109 | if (drawBadge) {
110 | super.draw(canvas)
111 | }
112 | }
113 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/extend/IToText.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.extend
2 |
3 | /**
4 | *
5 | * Email:angcyo@126.com
6 | * @author angcyo
7 | * @date 2021/07/20
8 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
9 | */
10 | interface IToText {
11 | fun toText(): CharSequence?
12 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/extend/IToValue.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.extend
2 |
3 | /**
4 | *
5 | * Email:angcyo@126.com
6 | * @author angcyo
7 | * @date 2021/07/20
8 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
9 | */
10 | interface IToValue {
11 | fun toValue(): Any?
12 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/DslBaseEditItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item
2 |
3 | import com.angcyo.dsladapter.DslAdapterItem
4 | import com.angcyo.dsladapter.DslViewHolder
5 | import com.angcyo.item.style.EditItemConfig
6 | import com.angcyo.item.style.IEditItem
7 |
8 | /**
9 | * 输入框item基类
10 | * Email:angcyo@126.com
11 | * @author angcyo
12 | * @date 2020/03/23
13 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
14 | */
15 |
16 | open class DslBaseEditItem : DslBaseLabelItem(), IEditItem {
17 |
18 | companion object {
19 | /**允许默认输入的字符长度*/
20 | var DEFAULT_MAX_INPUT_LENGTH = 30
21 |
22 | /**输入框文本改变节流时长, 毫秒*/
23 | var DEFAULT_INPUT_SHAKE_DELAY = 300L
24 | }
25 |
26 | override var editItemConfig: EditItemConfig = EditItemConfig()
27 |
28 | init {
29 | itemLayoutId = R.layout.dsl_edit_item
30 | }
31 |
32 | override fun onItemBind(
33 | itemHolder: DslViewHolder,
34 | itemPosition: Int,
35 | adapterItem: DslAdapterItem
36 | ) {
37 | super.onItemBind(itemHolder, itemPosition, adapterItem)
38 | }
39 |
40 | override fun onItemViewDetachedToWindow(itemHolder: DslViewHolder, itemPosition: Int) {
41 | super.onItemViewDetachedToWindow(itemHolder, itemPosition)
42 | //itemHolder.ev(R.id.lib_edit_view)?.clearListeners()
43 | }
44 |
45 | override fun onItemViewRecycled(itemHolder: DslViewHolder, itemPosition: Int) {
46 | super.onItemViewRecycled(itemHolder, itemPosition)
47 | itemHolder.ev(editItemConfig.itemEditTextViewId)?.clearListeners()
48 | }
49 |
50 | override fun onItemChangeListener(item: DslAdapterItem) {
51 | //super.onItemChangeListener(item)
52 | updateItemOnHaveDepend()
53 | }
54 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/DslBaseInfoItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item
2 |
3 | import androidx.annotation.DrawableRes
4 | import androidx.annotation.LayoutRes
5 | import com.angcyo.dsladapter.DslAdapterItem
6 | import com.angcyo.dsladapter.DslViewHolder
7 | import com.angcyo.widget.span.colorFilter
8 | import com.angcyo.widget.span.undefined_res
9 |
10 | /**
11 | * 横条文本信息基类item, 右边布局支持扩展自定义
12 | * Email:angcyo@126.com
13 | * @author angcyo
14 | * @date 2019/08/09
15 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
16 | */
17 | open class DslBaseInfoItem : DslAdapterItem() {
18 |
19 | /**条目文本*/
20 | var itemInfoText: CharSequence? = null
21 |
22 | @DrawableRes
23 | var itemInfoIcon: Int = undefined_res
24 |
25 | var itemInfoIconColor: Int = undefined_res
26 |
27 | /**扩展布局信息*/
28 | @LayoutRes
29 | var itemExtendLayoutId: Int = undefined_res
30 |
31 | init {
32 | itemLayoutId = R.layout.dsl_info_item
33 | }
34 |
35 | override fun onItemBind(
36 | itemHolder: DslViewHolder,
37 | itemPosition: Int,
38 | adapterItem: DslAdapterItem,
39 | payloads: List
40 | ) {
41 | super.onItemBind(itemHolder, itemPosition, adapterItem, payloads)
42 |
43 | //文本信息
44 | itemHolder.tv(R.id.lib_text_view)?.apply {
45 | text = itemInfoText
46 |
47 | if (itemInfoIconColor == undefined_res) {
48 | setLeftIco(itemInfoIcon)
49 | } else {
50 | setLeftIco(loadDrawable(itemInfoIcon).colorFilter(itemInfoIconColor))
51 | }
52 | }
53 |
54 | //扩展布局
55 | if (itemExtendLayoutId != undefined_res) {
56 | var inflateLayoutId = undefined_res //已经inflate的布局id
57 | itemHolder.group(R.id.wrap_layout)?.apply {
58 | if (childCount > 0) {
59 | inflateLayoutId = (getChildAt(0).getTag(R.id.tag) as? Int) ?: undefined_res
60 | }
61 |
62 | if (itemExtendLayoutId != inflateLayoutId) {
63 | //两次inflate的布局不同
64 | itemHolder.clear()
65 | inflate(itemExtendLayoutId, true)
66 | val view = getChildAt(0)
67 | view.setTag(R.id.tag, itemExtendLayoutId)
68 | }
69 | }
70 | } else {
71 | itemHolder.group(R.id.wrap_layout)?.removeAllViews()
72 | }
73 | }
74 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/DslBaseLabelItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item
2 |
3 | import android.content.res.ColorStateList
4 | import android.graphics.drawable.Drawable
5 | import android.util.TypedValue
6 | import android.view.Gravity
7 | import android.widget.TextView
8 | import com.angcyo.dsladapter.DslAdapterItem
9 | import com.angcyo.dsladapter.DslViewHolder
10 | import com.angcyo.dsladapter.UndefinedDrawable
11 | import com.angcyo.dsladapter.setBgDrawable
12 | import com.angcyo.widget.span.undefined_color
13 | import com.angcyo.widget.span.undefined_float
14 |
15 |
16 | /**
17 | * 带有Label的item
18 | * Email:angcyo@126.com
19 | * @author angcyo
20 | * @date 2020/03/23
21 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
22 | */
23 |
24 | open class DslBaseLabelItem : DslAdapterItem() {
25 |
26 | /**左边的Label文本*/
27 | var itemLabelText: CharSequence? = null
28 | set(value) {
29 | field = value
30 | itemLabelTextStyle.text = value
31 | }
32 |
33 | /**统一样式配置*/
34 | var itemLabelTextStyle = TextStyleConfig()
35 |
36 | init {
37 | itemLayoutId = R.layout.dsl_label_item
38 | }
39 |
40 | override fun onItemBind(
41 | itemHolder: DslViewHolder,
42 | itemPosition: Int,
43 | adapterItem: DslAdapterItem,
44 | payloads: List
45 | ) {
46 | super.onItemBind(itemHolder, itemPosition, adapterItem, payloads)
47 |
48 | itemHolder.gone(R.id.lib_label_view, itemLabelText == null)
49 |
50 | itemHolder.tv(R.id.lib_label_view)?.apply {
51 | itemLabelTextStyle.updateStyle(this)
52 | }
53 | }
54 |
55 | open fun configLabelTextStyle(action: TextStyleConfig.() -> Unit) {
56 | itemLabelTextStyle.action()
57 | }
58 | }
59 |
60 | /**文本样式配置*/
61 | open class TextStyleConfig {
62 | var text: CharSequence? = null
63 | var hint: CharSequence? = null
64 | var textBold: Boolean = false
65 | var textColor: Int = undefined_color
66 | var textColors: ColorStateList? = null
67 | var textSize: Float = undefined_float
68 | var textGravity: Int = Gravity.LEFT or Gravity.CENTER_VERTICAL
69 | var backgroundDrawable: Drawable? = UndefinedDrawable()
70 |
71 | /**生效*/
72 | open fun updateStyle(textView: TextView) {
73 | with(textView) {
74 | if (backgroundDrawable is UndefinedDrawable) {
75 | backgroundDrawable = background
76 | }
77 | setBgDrawable(backgroundDrawable)
78 |
79 | text = this@TextStyleConfig.text
80 | hint = this@TextStyleConfig.hint
81 |
82 | gravity = textGravity
83 |
84 | setBoldText(textBold)
85 |
86 | //颜色, 防止复用. 所以在未指定的情况下, 要获取默认的颜色.
87 | val colors = when {
88 | this@TextStyleConfig.textColors != null -> {
89 | this@TextStyleConfig.textColors
90 | }
91 | textColor != undefined_color -> {
92 | ColorStateList.valueOf(textColor)
93 | }
94 | else -> {
95 | textColors
96 | }
97 | }
98 | if (colors != this@TextStyleConfig.textColors) {
99 | this@TextStyleConfig.textColors = colors
100 | }
101 | setTextColor(colors)
102 |
103 | //字体大小同理.
104 | val size = if (this@TextStyleConfig.textSize != undefined_float) {
105 | this@TextStyleConfig.textSize
106 | } else {
107 | textSize
108 | }
109 | this@TextStyleConfig.textSize = size
110 | setTextSize(TypedValue.COMPLEX_UNIT_PX, size)
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/DslBottomButtonItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item
2 |
3 | /**
4 | * 显示的[RecyclerView]底部的item
5 | * Email:angcyo@126.com
6 | * @author angcyo
7 | * @date 2020/03/26
8 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
9 | */
10 | open class DslBottomButtonItem : DslButtonItem() {
11 | init {
12 | itemLayoutId = R.layout.dsl_bottom_button_item
13 | itemButtonStyle.themeStyle()
14 | }
15 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/DslBottomItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item
2 |
3 | import com.angcyo.dsladapter.DslAdapterItem
4 | import com.angcyo.dsladapter.DslViewHolder
5 |
6 | /**
7 | * 在[RecyclerView]底部显示的文本item
8 | * Email:angcyo@126.com
9 | * @author angcyo
10 | * @date 2020/02/29
11 | */
12 | open class DslBottomItem : DslAdapterItem() {
13 |
14 | /**显示的文本*/
15 | var itemText: CharSequence? = null
16 | set(value) {
17 | field = value
18 | itemTextStyle.text = value
19 | }
20 |
21 | /**统一样式配置*/
22 | var itemTextStyle = TextStyleConfig()
23 |
24 | init {
25 | itemLayoutId = R.layout.dsl_bottom_item
26 | }
27 |
28 | override fun onItemBind(
29 | itemHolder: DslViewHolder,
30 | itemPosition: Int,
31 | adapterItem: DslAdapterItem,
32 | payloads: List
33 | ) {
34 | super.onItemBind(itemHolder, itemPosition, adapterItem, payloads)
35 |
36 | itemHolder.tv(R.id.lib_text_view)?.apply {
37 | itemTextStyle.updateStyle(this)
38 | }
39 | }
40 |
41 | override fun _initItemSize(itemHolder: DslViewHolder) {
42 | //super._initItemSize(itemHolder)
43 | }
44 |
45 | open fun configTextStyle(action: TextStyleConfig.() -> Unit) {
46 | itemTextStyle.action()
47 | }
48 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/DslButtonItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item
2 |
3 | import android.graphics.Color
4 | import android.view.Gravity
5 | import android.widget.TextView
6 | import com.angcyo.dsladapter.DslAdapterItem
7 | import com.angcyo.dsladapter.DslViewHolder
8 | import com.angcyo.widget.DslButton
9 | import com.angcyo.widget.colorState
10 | import com.angcyo.widget.span.dpi
11 | import com.angcyo.widget.span.undefined_float
12 |
13 |
14 | /**
15 | * 带有[DslButton]的item
16 | * Email:angcyo@126.com
17 | * @author angcyo
18 | * @date 2020/03/26
19 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
20 | */
21 | open class DslButtonItem : DslAdapterItem() {
22 |
23 | /**按钮显示的文本*/
24 | var itemButtonText: CharSequence? = null
25 | set(value) {
26 | field = value
27 | itemButtonStyle.text = value
28 | }
29 |
30 | /**按钮样式配置项*/
31 | var itemButtonStyle = ButtonStyleConfig().apply {
32 | textGravity = Gravity.CENTER
33 | }
34 |
35 | /**按钮配置回调*/
36 | var itemButtonConfig: (DslButton) -> Unit = {
37 |
38 | }
39 |
40 | init {
41 | itemLayoutId = R.layout.dsl_button_item
42 | }
43 |
44 | override fun onItemBind(
45 | itemHolder: DslViewHolder,
46 | itemPosition: Int,
47 | adapterItem: DslAdapterItem,
48 | payloads: List
49 | ) {
50 | super.onItemBind(itemHolder, itemPosition, adapterItem, payloads)
51 | itemHolder.itemView.isClickable = false
52 |
53 | itemHolder.v(R.id.lib_button)?.apply {
54 | itemButtonStyle.updateStyle(this)
55 | itemButtonConfig(this)
56 |
57 | setOnClickListener(_clickListener)
58 | }
59 | }
60 |
61 | open fun configButtonStyle(action: ButtonStyleConfig.() -> Unit) {
62 | itemButtonStyle.action()
63 | }
64 | }
65 |
66 | open class ButtonStyleConfig : TextStyleConfig() {
67 |
68 | companion object {
69 | //主题渐变样式
70 | val BUTTON_STYLE_THEME = 1
71 |
72 | //填充颜色的样式
73 | val BUTTON_STYLE_SOLID = 2
74 |
75 | //边框->主题渐变
76 | val BUTTON_STYLE_FILL = 3
77 | }
78 |
79 | /**特定样式*/
80 | var style: Int = BUTTON_STYLE_THEME
81 |
82 | /**样式[BUTTON_STYLE_THEME] [BUTTON_STYLE_FILL]时, 渐变的颜色*/
83 | var styleThemeColors = intArrayOf(
84 | _color(R.color.colorPrimary),
85 | _color(R.color.colorPrimaryDark)
86 | )
87 |
88 | /**样式[BUTTON_STYLE_THEME] [BUTTON_STYLE_FILL]时, 文本的颜色*/
89 | var styleThemeTextColor = Color.WHITE
90 |
91 | /**样式[BUTTON_STYLE_SOLID]时, solid的颜色*/
92 | var styleSolidSolidColor = Color.WHITE
93 |
94 | /**样式[BUTTON_STYLE_FILL]时, solid的颜色*/
95 | var styleFillSolidColor = Color.TRANSPARENT
96 |
97 | /**样式[BUTTON_STYLE_SOLID] [BUTTON_STYLE_FILL]时, 文本的颜色*/
98 | var styleSolidTextColor = _color(R.color.text_general_color)
99 | set(value) {
100 | field = value
101 | textColor = value
102 | }
103 |
104 | /**[BUTTON_STYLE_FILL]*/
105 | var styleFillStrokeWidth = 2 * dpi
106 |
107 | /**[BUTTON_STYLE_FILL]*/
108 | var styleFillStrokeColor = _color(R.color.colorPrimary)
109 |
110 | var buttonRadius: Float = undefined_float
111 |
112 | init {
113 | themeStyle()
114 | }
115 |
116 | override fun updateStyle(textView: TextView) {
117 | super.updateStyle(textView)
118 |
119 | if (textView is DslButton) {
120 |
121 | //不支持不同圆角大小的样式
122 | if (buttonRadius == undefined_float) {
123 | buttonRadius = textView.normalRadii.first()
124 | }
125 | textView.setButtonRadius(buttonRadius)
126 |
127 | when (style) {
128 | BUTTON_STYLE_THEME -> {
129 | textView.enableTextStyle = true
130 | textView.setButtonGradientColors(styleThemeColors)
131 | textView.setButtonTextColor(textColor)
132 | textView.setButtonStrokeWidth(0)
133 | }
134 | BUTTON_STYLE_SOLID -> {
135 | textView.enableTextStyle = true
136 | textView.setButtonGradientColors(null)
137 | textView.setButtonSolidColor(styleSolidSolidColor)
138 | textView.setButtonTextColor(textColor)
139 | textView.setButtonStrokeWidth(0)
140 | }
141 | BUTTON_STYLE_FILL -> {
142 | textView.enableTextStyle = false
143 | textView.setButtonGradientColors(null)
144 | textView.setButtonSolidColor(styleFillSolidColor)
145 | textView.setButtonStrokeWidth(styleFillStrokeWidth)
146 | textView.setButtonStrokeColor(styleFillStrokeColor)
147 |
148 | textView.pressStrokeWidth = 0
149 | textView.pressGradientColors = styleThemeColors
150 | }
151 | }
152 |
153 | textView.updateDrawable()
154 | }
155 | }
156 |
157 | /**使用主题样式, 颜色渐变*/
158 | fun themeStyle() {
159 | style = BUTTON_STYLE_THEME
160 | textColor = styleThemeTextColor
161 | }
162 |
163 | /**使用渐变样式*/
164 | fun gradientStyle(gradientStartColor: Int, gradientEndColor: Int = gradientStartColor) {
165 | themeStyle()
166 | styleThemeColors = intArrayOf(gradientStartColor, gradientEndColor)
167 | }
168 |
169 | /**填充颜色的样式*/
170 | fun solidStyle() {
171 | style = BUTTON_STYLE_SOLID
172 | textColor = styleSolidTextColor
173 | }
174 |
175 | /**边框 填充样式*/
176 | fun fillStyle() {
177 | style = BUTTON_STYLE_FILL
178 | textColors = colorState(
179 | DslButton.ATTR_PRESSED to styleThemeTextColor,
180 | DslButton.ATTR_NORMAL to styleSolidTextColor
181 | )
182 | }
183 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/DslGridItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item
2 |
3 | import android.graphics.drawable.Drawable
4 | import android.view.ViewGroup
5 | import com.angcyo.dsladapter.*
6 |
7 | /**
8 | * 普通的网格item
9 | * Email:angcyo@126.com
10 | * @author angcyo
11 | * @date 2020/03/22
12 | */
13 | open class DslGridItem : DslAdapterItem() {
14 |
15 | /**显示的文本*/
16 | var itemText: CharSequence? = null
17 |
18 | /**图标*/
19 | var itemIcon: Int = -1
20 |
21 | /**图标背景*/
22 | var itemImageBg: Drawable? = null
23 | var itemImagePadding: Int = 12 * dpi
24 | var itemTextPadding: Int = 8 * dpi
25 |
26 | /**图标是1:1的大小*/
27 | var itemIconSize: Int = ViewGroup.LayoutParams.WRAP_CONTENT
28 |
29 | /**开启智能分割线, 只有在非边界的item才绘制*/
30 | var itemGridInsert = -1
31 |
32 | init {
33 | itemLayoutId = R.layout.dsl_grid_item
34 | }
35 |
36 | override fun onItemBind(
37 | itemHolder: DslViewHolder,
38 | itemPosition: Int,
39 | adapterItem: DslAdapterItem,
40 | payloads: List
41 | ) {
42 | super.onItemBind(itemHolder, itemPosition, adapterItem, payloads)
43 |
44 | //文本
45 | itemHolder.tv(R.id.lib_text_view)?.apply {
46 | text = itemText
47 | padding(itemTextPadding)
48 | }
49 |
50 | //图标
51 | itemHolder.img(R.id.lib_image_view)?.apply {
52 | padding(itemImagePadding)
53 |
54 | setImageDrawable(loadDrawable(itemIcon))
55 | setWidth(itemIconSize)
56 |
57 | setBgDrawable(itemImageBg)
58 | }
59 |
60 | //智能分割线
61 | if (itemGridInsert > 0) {
62 | itemGroupParams.apply {
63 | //itemLeftInsert = itemGridInsert
64 | //itemTopInsert = itemGridInsert
65 | itemRightInsert = itemGridInsert
66 | itemBottomInsert = itemGridInsert
67 | if (isEdgeLeft()) {
68 | itemLeftInsert = 0
69 | }
70 | if (isEdgeTop()) {
71 | itemTopInsert = 0
72 | }
73 | if (isEdgeRight()) {
74 | itemRightInsert = 0
75 | }
76 | if (isEdgeBottom()) {
77 | itemBottomInsert = 0
78 | }
79 | }
80 | }
81 | }
82 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/DslLabelEditItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item
2 |
3 | import android.graphics.drawable.Drawable
4 | import android.view.View
5 | import com.angcyo.dsladapter.DslAdapterItem
6 | import com.angcyo.dsladapter.DslViewHolder
7 |
8 | /**
9 | * 带有label的单行输入item
10 | * Email:angcyo@126.com
11 | * @author angcyo
12 | * @date 2020/03/23
13 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
14 | */
15 | open class DslLabelEditItem : DslBaseEditItem() {
16 |
17 | /**编辑提示按钮, 负数会返回null对象*/
18 | var itemEditTipIcon: Int = R.drawable.lib_icon_edit_tip
19 |
20 | /**优先于属性[itemEditTipIcon]*/
21 | var itemEditTipDrawable: Drawable? = null
22 |
23 | /**右边图标点击事件, 如果设置回调. 会影响默认的事件处理*/
24 | var itemRightIcoClick: ((DslViewHolder, View) -> Unit)? = null
25 |
26 | /**右边的文本*/
27 | var itemRightText: CharSequence? = null
28 | set(value) {
29 | field = value
30 | itemRightTextStyle.text = value
31 | }
32 |
33 | /**统一样式配置*/
34 | var itemRightTextStyle = TextStyleConfig()
35 |
36 | init {
37 | itemLayoutId = R.layout.dsl_label_edit_item
38 | }
39 |
40 | override fun onItemBind(
41 | itemHolder: DslViewHolder,
42 | itemPosition: Int,
43 | adapterItem: DslAdapterItem,
44 | payloads: List
45 | ) {
46 | super.onItemBind(itemHolder, itemPosition, adapterItem, payloads)
47 |
48 | itemHolder.img(R.id.lib_right_ico_view)?.apply {
49 | val drawable = itemEditTipDrawable ?: loadDrawable(itemEditTipIcon)
50 | if (drawable == null || editItemConfig.itemNoEditModel == true /*不可编辑*/) {
51 | gone()
52 | } else {
53 | visible()
54 | setImageDrawable(drawable)
55 | }
56 |
57 | //处理默认弹出软键盘
58 | if (itemRightIcoClick == null) {
59 | if (editItemConfig.itemEditTextStyle.noEditModel) {
60 | gone()
61 | } else {
62 | throttleClickIt {
63 | itemHolder.focus(editItemConfig.itemEditTextViewId)?.showSoftInput()
64 | }
65 | }
66 | } else {
67 | throttleClickIt {
68 | itemRightIcoClick?.invoke(itemHolder, it)
69 | }
70 | }
71 |
72 | }
73 |
74 | //右边文本, cm unit
75 | itemHolder.gone(R.id.lib_right_text_view, itemRightTextStyle.text == null)
76 | itemHolder.tv(R.id.lib_right_text_view)?.apply {
77 | itemRightTextStyle.updateStyle(this)
78 | }
79 | }
80 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/DslLabelTextItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item
2 |
3 | import com.angcyo.dsladapter.DslAdapterItem
4 | import com.angcyo.dsladapter.DslViewHolder
5 |
6 | /**
7 | * 简单的文本显示item
8 | * Email:angcyo@126.com
9 | * @author angcyo
10 | * @date 2020/03/23
11 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
12 | */
13 | open class DslLabelTextItem : DslBaseLabelItem() {
14 |
15 | /**显示的文本*/
16 | var itemText: CharSequence? = null
17 | set(value) {
18 | field = value
19 | itemTextStyle.text = value
20 | }
21 |
22 | /**统一样式配置*/
23 | var itemTextStyle = TextStyleConfig()
24 |
25 | init {
26 | itemLayoutId = R.layout.dsl_label_text_item
27 | }
28 |
29 | override fun onItemBind(
30 | itemHolder: DslViewHolder,
31 | itemPosition: Int,
32 | adapterItem: DslAdapterItem,
33 | payloads: List
34 | ) {
35 | super.onItemBind(itemHolder, itemPosition, adapterItem, payloads)
36 |
37 | itemHolder.tv(R.id.lib_text_view)?.apply {
38 | itemTextStyle.updateStyle(this)
39 | }
40 | }
41 |
42 | open fun configTextStyle(action: TextStyleConfig.() -> Unit) {
43 | itemTextStyle.action()
44 | }
45 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/DslNestedRecyclerItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item
2 |
3 | import androidx.fragment.app.Fragment
4 | import androidx.recyclerview.widget.RecyclerView
5 | import com.angcyo.dsladapter.item.IFragmentItem
6 | import com.angcyo.dsladapter.DslAdapterItem
7 | import com.angcyo.item.style.INestedRecyclerItem
8 | import com.angcyo.item.style.NestedRecyclerItemConfig
9 | import com.angcyo.dsladapter.DslViewHolder
10 |
11 | /**
12 | * 内嵌[RecyclerView]的item
13 | * Email:angcyo@126.com
14 | * @author angcyo
15 | * @date 2020/03/19
16 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
17 | */
18 | open class DslNestedRecyclerItem : DslAdapterItem(), INestedRecyclerItem, IFragmentItem {
19 |
20 | override var nestedRecyclerItemConfig: NestedRecyclerItemConfig = NestedRecyclerItemConfig()
21 |
22 | override var itemFragment: Fragment? = null
23 |
24 | init {
25 | itemLayoutId = R.layout.dsl_nested_recycler_item
26 | }
27 |
28 | override fun onItemBind(
29 | itemHolder: DslViewHolder,
30 | itemPosition: Int,
31 | adapterItem: DslAdapterItem,
32 | payloads: List
33 | ) {
34 | super.onItemBind(itemHolder, itemPosition, adapterItem, payloads)
35 | }
36 |
37 | override fun onItemViewRecycled(itemHolder: DslViewHolder, itemPosition: Int) {
38 | super.onItemViewRecycled(itemHolder, itemPosition)
39 | onNestedRecyclerViewRecycled(itemHolder, itemPosition)
40 | }
41 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/DslSwitchInfoItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item
2 |
3 | import com.angcyo.dsladapter.DslAdapterItem
4 | import com.angcyo.github.SwitchButton
5 | import com.angcyo.dsladapter.DslViewHolder
6 |
7 | /**
8 | *
9 | * Email:angcyo@126.com
10 | * @author angcyo
11 | * @date 2019/08/09
12 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
13 | */
14 | open class DslSwitchInfoItem : DslBaseInfoItem() {
15 |
16 | /**是否选中*/
17 | var itemSwitchChecked = false
18 |
19 | /**状态回调, 提供一个可以完全覆盖的方法*/
20 | var itemSwitchChanged: (checked: Boolean) -> Unit = {
21 | onItemSwitchChanged(it)
22 | }
23 |
24 | init {
25 | itemExtendLayoutId = R.layout.dsl_extent_switch_item
26 | }
27 |
28 | override fun onItemBind(
29 | itemHolder: DslViewHolder,
30 | itemPosition: Int,
31 | adapterItem: DslAdapterItem,
32 | payloads: List
33 | ) {
34 | super.onItemBind(itemHolder, itemPosition, adapterItem, payloads)
35 |
36 | itemHolder.v(R.id.lib_switch_view)?.apply {
37 |
38 | setOnCheckedChangeListener(object : SwitchButton.OnCheckedChangeListener {
39 | override fun onCheckedChanged(view: SwitchButton, isChecked: Boolean) {
40 | val old = itemSwitchChecked
41 | itemSwitchChecked = isChecked
42 | if (old != itemSwitchChecked) {
43 | itemSwitchChanged(itemSwitchChecked)
44 | }
45 | }
46 | })
47 |
48 | //刷新界面的时候, 不执行动画
49 | val old = isEnableEffect
50 | isEnableEffect = false
51 | isChecked = itemSwitchChecked
52 | isEnableEffect = old
53 | }
54 | }
55 |
56 | /**提供一个可以被重写的子类方法*/
57 | open fun onItemSwitchChanged(checked: Boolean) {
58 |
59 | }
60 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/DslTextInfoItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item
2 |
3 | import androidx.annotation.DrawableRes
4 | import com.angcyo.dsladapter.DslAdapterItem
5 | import com.angcyo.dsladapter.DslViewHolder
6 | import com.angcyo.widget.span.colorFilter
7 | import com.angcyo.widget.span.undefined_res
8 |
9 | /**
10 | * 横条左右都是文本控件的item
11 | * Email:angcyo@126.com
12 | * @author angcyo
13 | * @date 2019/08/09
14 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
15 | */
16 | open class DslTextInfoItem : DslBaseInfoItem() {
17 |
18 | /**描述文本*/
19 | var itemDarkText: CharSequence? = null
20 |
21 | @DrawableRes
22 | var itemDarkIcon: Int = undefined_res
23 | var itemDarkIconColor: Int = undefined_res
24 |
25 | init {
26 | itemExtendLayoutId = R.layout.dsl_extent_text_item
27 | }
28 |
29 | override fun onItemBind(
30 | itemHolder: DslViewHolder,
31 | itemPosition: Int,
32 | adapterItem: DslAdapterItem,
33 | payloads: List
34 | ) {
35 | super.onItemBind(itemHolder, itemPosition, adapterItem, payloads)
36 |
37 | //文本
38 | itemHolder.tv(R.id.lib_dark_text_view)?.apply {
39 | text = itemDarkText
40 |
41 | if (itemDarkIconColor == undefined_res) {
42 | setRightIco(itemDarkIcon)
43 | } else {
44 | setRightIco(loadDrawable(itemDarkIcon).colorFilter(itemDarkIconColor))
45 | }
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/DslTextItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item
2 |
3 | import com.angcyo.dsladapter.DslAdapterItem
4 | import com.angcyo.dsladapter.DslViewHolder
5 |
6 | /**
7 | * 简单的文本显示item
8 | * Email:angcyo@126.com
9 | * @author angcyo
10 | * @date 2020/04/23
11 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
12 | */
13 | open class DslTextItem : DslAdapterItem() {
14 |
15 | /**文本*/
16 | var itemText: CharSequence? = null
17 | set(value) {
18 | field = value
19 | itemTextStyle.text = value
20 | }
21 |
22 | /**统一样式配置*/
23 | var itemTextStyle = TextStyleConfig()
24 |
25 | init {
26 | itemLayoutId = R.layout.dsl_text_item
27 | }
28 |
29 | override fun onItemBind(
30 | itemHolder: DslViewHolder,
31 | itemPosition: Int,
32 | adapterItem: DslAdapterItem,
33 | payloads: List
34 | ) {
35 | super.onItemBind(itemHolder, itemPosition, adapterItem, payloads)
36 |
37 | itemHolder.tv(R.id.lib_text_view)?.apply {
38 | itemTextStyle.updateStyle(this)
39 | }
40 | }
41 |
42 | open fun configTextStyle(action: TextStyleConfig.() -> Unit) {
43 | itemTextStyle.action()
44 | }
45 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/RAnimatorListener.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item
2 |
3 | import android.animation.Animator
4 |
5 | /**
6 | *
7 | * Email:angcyo@126.com
8 | * @author angcyo
9 | * @date 2019/12/31
10 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
11 | */
12 | open class RAnimatorListener : Animator.AnimatorListener {
13 |
14 | private var isCancel = false
15 |
16 | var onAnimatorFinish: (animator: Animator, fromCancel: Boolean) -> Unit =
17 | { animator, fromCancel ->
18 | _onAnimatorFinish(animator, fromCancel)
19 | }
20 |
21 | override fun onAnimationRepeat(animation: Animator) {
22 | }
23 |
24 | override fun onAnimationEnd(animation: Animator) {
25 | if (isCancel) {
26 | //当动画被取消的时候, 系统会回调onAnimationCancel, 然后 onAnimationEnd
27 | //所以, 这里过滤一下
28 | } else {
29 | onAnimatorFinish(animation, false)
30 | }
31 | }
32 |
33 | override fun onAnimationCancel(animation: Animator) {
34 | isCancel = true
35 | onAnimatorFinish(animation, true)
36 | }
37 |
38 | override fun onAnimationStart(animation: Animator) {
39 | isCancel = false
40 | }
41 |
42 | open fun _onAnimatorFinish(animator: Animator, fromCancel: Boolean) {
43 |
44 | }
45 |
46 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/base/LibInitProvider.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.base
2 |
3 | import android.content.ContentProvider
4 | import android.content.ContentValues
5 | import android.content.Context
6 | import android.database.Cursor
7 | import android.net.Uri
8 |
9 | /**
10 | * 免入侵, 获取[Content]对象
11 | * Email:angcyo@126.com
12 | * @author angcyo
13 | * @date 2020/04/23
14 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
15 | */
16 | class LibInitProvider : ContentProvider() {
17 |
18 | companion object {
19 | lateinit var contentProvider: Context
20 | }
21 |
22 | override fun onCreate(): Boolean {
23 | contentProvider = context!!.applicationContext
24 | return true
25 | }
26 |
27 | override fun insert(uri: Uri, values: ContentValues?): Uri? = null
28 |
29 | override fun query(
30 | uri: Uri,
31 | projection: Array?,
32 | selection: String?,
33 | selectionArgs: Array?,
34 | sortOrder: String?
35 | ): Cursor? = null
36 |
37 | override fun update(
38 | uri: Uri,
39 | values: ContentValues?,
40 | selection: String?,
41 | selectionArgs: Array?
42 | ): Int = -1
43 |
44 | override fun delete(uri: Uri, selection: String?, selectionArgs: Array?): Int = -1
45 |
46 | override fun getType(uri: Uri): String? = null
47 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/base/RAnimationListener.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.base
2 |
3 | import android.view.animation.Animation
4 |
5 | /**
6 | *
7 | * Email:angcyo@126.com
8 | * @author angcyo
9 | * @date 2019/12/31
10 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
11 | */
12 | open class RAnimationListener : Animation.AnimationListener {
13 | override fun onAnimationRepeat(animation: Animation) {
14 | }
15 |
16 | override fun onAnimationEnd(animation: Animation) {
17 | }
18 |
19 | override fun onAnimationStart(animation: Animation) {
20 | }
21 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/base/SingleTextWatcher.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.widget.edit
2 |
3 | import android.text.Editable
4 | import android.text.TextWatcher
5 |
6 | /**
7 | * Email:angcyo@126.com
8 | *
9 | * @author angcyo
10 | * @date 2019/06/06
11 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
12 | */
13 | open class SingleTextWatcher : TextWatcher {
14 | override fun beforeTextChanged(sequence: CharSequence?, start: Int, count: Int, after: Int) {
15 | }
16 |
17 | override fun onTextChanged(sequence: CharSequence?, start: Int, before: Int, count: Int) {
18 | }
19 |
20 | override fun afterTextChanged(editable: Editable?) {}
21 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/style/ButtonStyleConfig.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.style
2 |
3 | import android.graphics.Color
4 | import android.view.View
5 | import com.angcyo.dpi
6 | import com.angcyo.item.R
7 | import com.angcyo.item._color
8 | import com.angcyo.widget.DslButton
9 | import com.angcyo.widget.colorState
10 | import com.angcyo.widget.span.undefined_float
11 |
12 | /**
13 | * 按钮样式配置
14 | * Email:angcyo@126.com
15 | * @author angcyo
16 | * @date 2020/06/09
17 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
18 | */
19 | open class ButtonStyleConfig : TextStyleConfig() {
20 |
21 | companion object {
22 | //主题渐变样式, 标准的填充色按钮
23 | val BUTTON_STYLE_THEME = 1
24 |
25 | //填充颜色的样式, 无渐变, 纯色填充+波纹效果
26 | val BUTTON_STYLE_SOLID = 2
27 |
28 | //边框->主题渐变填充
29 | val BUTTON_STYLE_FILL = 3
30 | }
31 |
32 | /**特定样式*/
33 | var style: Int = BUTTON_STYLE_THEME
34 |
35 | /**样式[BUTTON_STYLE_THEME] [BUTTON_STYLE_FILL]时, 渐变的颜色*/
36 | var styleThemeColors = intArrayOf(
37 | _color(R.color.colorPrimary),
38 | _color(R.color.colorPrimaryDark)
39 | )
40 |
41 | /**样式[BUTTON_STYLE_THEME] [BUTTON_STYLE_FILL]时, 文本的颜色*/
42 | var styleThemeTextColor = Color.WHITE
43 |
44 | /**样式[BUTTON_STYLE_SOLID]时, solid的颜色*/
45 | var styleSolidSolidColor = Color.WHITE
46 |
47 | /**样式[BUTTON_STYLE_FILL]时, solid的颜色*/
48 | var styleFillSolidColor = Color.TRANSPARENT
49 |
50 | /**样式[BUTTON_STYLE_SOLID] [BUTTON_STYLE_FILL]时, 文本的颜色*/
51 | var styleSolidTextColor = _color(R.color.text_general_color)
52 | set(value) {
53 | field = value
54 | textColor = value
55 | }
56 |
57 | /**[BUTTON_STYLE_FILL]*/
58 | var styleFillStrokeWidth = 2 * dpi
59 |
60 | /**[BUTTON_STYLE_FILL]*/
61 | var styleFillStrokeColor = _color(R.color.colorPrimary)
62 |
63 | var buttonRadius: Float = undefined_float
64 |
65 | init {
66 | themeStyle()
67 | }
68 |
69 | override fun updateStyle(view: View) {
70 | super.updateStyle(view)
71 |
72 | if (view is DslButton) {
73 |
74 | //不支持不同圆角大小的样式
75 | if (buttonRadius == undefined_float) {
76 | buttonRadius = view.normalRadii.first()
77 | }
78 | view.setButtonRadius(buttonRadius)
79 |
80 | when (style) {
81 | BUTTON_STYLE_THEME -> {
82 | view.enableTextStyle = true
83 | view.setButtonGradientColors(styleThemeColors)
84 | view.setButtonTextColor(textColor)
85 | view.setButtonStrokeWidth(0)
86 | }
87 |
88 | BUTTON_STYLE_SOLID -> {
89 | view.enableTextStyle = true
90 | view.setButtonGradientColors(null)
91 | view.setButtonSolidColor(styleSolidSolidColor)
92 | view.setButtonTextColor(textColor)
93 | view.setButtonStrokeWidth(0)
94 | }
95 |
96 | BUTTON_STYLE_FILL -> {
97 | view.enableTextStyle = false
98 | view.setButtonGradientColors(null)
99 | view.setButtonSolidColor(styleFillSolidColor)
100 | view.setButtonStrokeWidth(styleFillStrokeWidth)
101 | view.setButtonStrokeColor(styleFillStrokeColor)
102 |
103 | view.pressStrokeWidth = 0
104 | view.pressGradientColors = styleThemeColors
105 | }
106 | }
107 |
108 | view.updateDrawable()
109 | }
110 | }
111 |
112 | /**使用主题样式, 颜色渐变*/
113 | fun themeStyle() {
114 | style = BUTTON_STYLE_THEME
115 | textColor = styleThemeTextColor
116 | }
117 |
118 | /**使用渐变样式*/
119 | fun gradientStyle(gradientStartColor: Int, gradientEndColor: Int = gradientStartColor) {
120 | themeStyle()
121 | styleThemeColors = intArrayOf(gradientStartColor, gradientEndColor)
122 | }
123 |
124 | /**填充颜色的样式*/
125 | fun solidStyle() {
126 | style = BUTTON_STYLE_SOLID
127 | textColor = styleSolidTextColor
128 | }
129 |
130 | /**边框 填充样式*/
131 | fun fillStyle() {
132 | style = BUTTON_STYLE_FILL
133 | textColors = colorState(
134 | DslButton.ATTR_PRESSED to styleThemeTextColor,
135 | DslButton.ATTR_NORMAL to styleThemeColors[0]
136 | )
137 | }
138 |
139 | /**白底黑字样式*/
140 | fun whiteStyle() {
141 | style = BUTTON_STYLE_SOLID
142 | textColor = styleSolidTextColor
143 | styleSolidSolidColor = Color.WHITE
144 | }
145 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/style/EditStyleConfig.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.style
2 |
3 | import android.text.InputFilter
4 | import android.text.InputType
5 | import android.text.method.DigitsKeyListener
6 | import android.view.Gravity
7 | import android.view.View
8 | import android.widget.EditText
9 | import android.widget.TextView
10 | import com.angcyo.item.DslBaseEditItem
11 | import com.angcyo.item.add
12 | import com.angcyo.item.addFilter
13 | import com.angcyo.item.clearListeners
14 | import com.angcyo.item.remove
15 | import com.angcyo.item.removeFilter
16 | import com.angcyo.item.setInputText
17 | import com.angcyo.item.setMaxLine
18 | import com.angcyo.widget.CharLengthFilter
19 |
20 | /**
21 | * 输入框样式配置
22 | * Email:angcyo@126.com
23 | * @author angcyo
24 | * @date 2020/06/09
25 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
26 | */
27 |
28 | class EditStyleConfig : TextStyleConfig() {
29 |
30 | /**文本输入类型*/
31 | var editInputType = InputType.TYPE_CLASS_TEXT
32 |
33 | /**最大输入字符数, -1取消限制*/
34 | var editMaxInputLength = DslBaseEditItem.DEFAULT_MAX_INPUT_LENGTH
35 |
36 | /**输入过滤器*/
37 | var editInputFilterList = mutableListOf()
38 |
39 | /**输入限制, 此属性和[editInputFilterList]互斥
40 | * [R.string.lib_number_digits]
41 | * [R.string.lib_password_digits]
42 | * [R.string.lib_en_digits]*/
43 | var editDigits: String? = null
44 |
45 | /**输入框不可编辑*/
46 | var noEditModel: Boolean = false
47 |
48 | /**最大输入行数, <=1 单行*/
49 | var editMaxLine: Int = 1
50 | set(value) {
51 | field = value
52 | if (value <= 1) {
53 | textGravity = Gravity.LEFT or Gravity.CENTER_VERTICAL
54 | editInputType = editInputType.remove(InputType.TYPE_TEXT_FLAG_MULTI_LINE)
55 | } else {
56 | textGravity = Gravity.TOP or Gravity.LEFT
57 | editInputType = editInputType.add(InputType.TYPE_TEXT_FLAG_MULTI_LINE)
58 | }
59 | }
60 |
61 | override fun updateStyle(view: View) {
62 | super.updateStyle(view)
63 |
64 | if (view is TextView) {
65 | with(view) {
66 | //清空text change监听
67 | clearListeners()
68 |
69 | //过滤器
70 | filters = editInputFilterList.toTypedArray()
71 |
72 | //单行 or 多行
73 | setMaxLine(editMaxLine)
74 |
75 | inputType = editInputType
76 | isEnabled = !noEditModel
77 |
78 | if (editMaxInputLength > 0) {
79 | addFilter(InputFilter.LengthFilter(editMaxInputLength))
80 | } else {
81 | removeFilter {
82 | this is InputFilter.LengthFilter || this is CharLengthFilter
83 | }
84 | }
85 |
86 | //digits 放在[inputType]后面
87 | editDigits?.let {
88 | keyListener = DigitsKeyListener.getInstance(it)
89 | }
90 |
91 | if (this is EditText) {
92 | setInputText(this@EditStyleConfig.text)
93 | }
94 | }
95 | }
96 | }
97 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/style/IAutoInitItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.style
2 |
3 | import com.angcyo.dsladapter.DslAdapterItem
4 | import com.angcyo.dsladapter.DslViewHolder
5 | import com.angcyo.dsladapter.annotation.ItemInitEntryPoint
6 | import com.angcyo.dsladapter.item.IDslItem
7 |
8 | /**
9 | * 自动初始化, 继承此类的item, 可以实现自动初始化
10 | * [com.angcyo.dsladapter.DslAdapterItem._initItemConfig]
11 | * Email:angcyo@126.com
12 | * @author angcyo
13 | * @date 2021/09/23
14 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
15 | */
16 | interface IAutoInitItem : IDslItem {
17 |
18 | /**自动初始化入口, 统一入口*/
19 | @ItemInitEntryPoint
20 | override fun initItemConfig(
21 | itemHolder: DslViewHolder,
22 | itemPosition: Int,
23 | adapterItem: DslAdapterItem,
24 | payloads: List
25 | ) {
26 | super.initItemConfig(itemHolder, itemPosition, adapterItem, payloads)
27 |
28 | //分发具体的初始化方法
29 | if (this is IBadgeItem) {
30 | initBadgeItem(itemHolder, itemPosition, adapterItem, payloads)
31 | }
32 | if (this is IDesItem) {
33 | initDesItem(itemHolder, itemPosition, adapterItem, payloads)
34 | }
35 | if (this is ITextItem) {
36 | initTextItem(itemHolder, itemPosition, adapterItem, payloads)
37 | }
38 | if (this is IEditItem) {
39 | initEditItem(itemHolder, itemPosition, adapterItem, payloads)
40 | }
41 | if (this is ILabelItem) {
42 | initLabelItem(itemHolder, itemPosition, adapterItem, payloads)
43 | }
44 | if (this is ITextInfoItem) {
45 | initInfoTextItem(itemHolder, itemPosition, adapterItem, payloads)
46 | }
47 | if (this is IBodyItem) {
48 | initBodyItem(itemHolder, itemPosition, adapterItem, payloads)
49 | }
50 | if (this is IButtonItem) {
51 | initButtonItem(itemHolder, itemPosition, adapterItem, payloads)
52 | }
53 | if (this is INestedRecyclerItem) {
54 | initNestedRecyclerItem(itemHolder, itemPosition, adapterItem, payloads)
55 | }
56 | if (this is ICheckItem) {
57 | initCheckItem(itemHolder, itemPosition, adapterItem, payloads)
58 | }
59 | if (this is ISwitchItem) {
60 | initSwitchItem(itemHolder, itemPosition, adapterItem, payloads)
61 | }
62 | if (this is ICheckGroupItem) {
63 | initCheckGroupItem(itemHolder, itemPosition, adapterItem, payloads)
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/style/IBadgeItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.style
2 |
3 | import com.angcyo.dsladapter.DslAdapterItem
4 | import com.angcyo.dsladapter.DslViewHolder
5 | import com.angcyo.dsladapter.annotation.ItemInitEntryPoint
6 | import com.angcyo.dsladapter.item.IDslItemConfig
7 | import com.angcyo.item.R
8 | import com.angcyo.widget.IBadgeView
9 |
10 | /**
11 | * 角标文本[BadgeTextView]item
12 | * Email:angcyo@126.com
13 | * @author angcyo
14 | * @date 2021/09/23
15 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
16 | */
17 | interface IBadgeItem : IAutoInitItem {
18 |
19 | var badgeItemConfig: BadgeItemConfig
20 |
21 | /**初始化*/
22 | @ItemInitEntryPoint
23 | fun initBadgeItem(
24 | itemHolder: DslViewHolder,
25 | itemPosition: Int,
26 | adapterItem: DslAdapterItem,
27 | payloads: List
28 | ) {
29 | itemHolder.view(badgeItemConfig.itemBadgeViewId)?.apply {
30 | if (this is IBadgeView) {
31 | dslBadeDrawable.apply {
32 | drawBadge = true
33 | badgeText = badgeItemConfig.itemBadgeText
34 | requestLayout()
35 | }
36 | }
37 | }
38 | }
39 | }
40 |
41 | var IBadgeItem.itemBadgeText: String?
42 | get() = badgeItemConfig.itemBadgeText
43 | set(value) {
44 | badgeItemConfig.itemBadgeText = value
45 | }
46 |
47 |
48 | class BadgeItemConfig : IDslItemConfig {
49 |
50 | var itemBadgeViewId: Int = R.id.lib_badge_view
51 |
52 | /**[com.angcyo.drawable.text.DslBadgeDrawable.badgeText]*/
53 | var itemBadgeText: String? = null
54 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/style/IBodyItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.style
2 |
3 | import com.angcyo.dsladapter.DslAdapterItem
4 | import com.angcyo.dsladapter.annotation.ItemInitEntryPoint
5 | import com.angcyo.dsladapter.item.IDslItemConfig
6 | import com.angcyo.item.R
7 | import com.angcyo.dsladapter.DslViewHolder
8 |
9 | /**
10 | *
11 | * Email:angcyo@126.com
12 | * @author angcyo
13 | * @date 2021/09/23
14 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
15 | */
16 | interface IBodyItem : IAutoInitItem {
17 |
18 | /**统一样式配置*/
19 | var bodyItemConfig: BodyItemConfig
20 |
21 | /**初始化*/
22 | @ItemInitEntryPoint
23 | fun initBodyItem(itemHolder: DslViewHolder,
24 | itemPosition: Int,
25 | adapterItem: DslAdapterItem,
26 | payloads: List) {
27 | itemHolder.tv(bodyItemConfig.itemBodyViewId)?.apply {
28 | bodyItemConfig.itemBodyStyle.updateStyle(this)
29 | }
30 | }
31 |
32 | fun configBodyStyle(action: TextStyleConfig.() -> Unit) {
33 | bodyItemConfig.itemBodyStyle.action()
34 | }
35 | }
36 |
37 | var IBodyItem.itemBodyText: CharSequence?
38 | get() = bodyItemConfig.itemBodyText
39 | set(value) {
40 | bodyItemConfig.itemBodyText = value
41 | }
42 |
43 | class BodyItemConfig : IDslItemConfig {
44 |
45 | var itemBodyViewId: Int = R.id.lib_body_view
46 |
47 | /**文本*/
48 | var itemBodyText: CharSequence? = null
49 | set(value) {
50 | field = value
51 | itemBodyStyle.text = value
52 | }
53 |
54 | /**统一样式配置*/
55 | var itemBodyStyle = TextStyleConfig()
56 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/style/IButtonItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.style
2 |
3 | import android.view.Gravity
4 | import com.angcyo.dsladapter.DslAdapterItem
5 | import com.angcyo.dsladapter.annotation.ItemInitEntryPoint
6 | import com.angcyo.dsladapter.item.IDslItemConfig
7 | import com.angcyo.item.R
8 | import com.angcyo.widget.DslButton
9 | import com.angcyo.dsladapter.DslViewHolder
10 | import com.angcyo.item.button
11 |
12 | /**
13 | *
14 | * Email:angcyo@126.com
15 | * @author angcyo
16 | * @date 2021/09/24
17 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
18 | */
19 | interface IButtonItem : IAutoInitItem {
20 |
21 | var buttonItemConfig: ButtonItemConfig
22 |
23 | @ItemInitEntryPoint
24 | fun initButtonItem(itemHolder: DslViewHolder,
25 | itemPosition: Int,
26 | adapterItem: DslAdapterItem,
27 | payloads: List) {
28 | itemHolder.itemView.isClickable = false
29 |
30 | itemHolder.button(buttonItemConfig.itemButtonViewId)?.apply {
31 | buttonItemConfig.itemButtonStyle.updateStyle(this)
32 | buttonItemConfig.itemButtonConfig(this)
33 |
34 | if (this@IButtonItem is DslAdapterItem) {
35 | setOnClickListener(_clickListener)
36 | setOnLongClickListener(_longClickListener)
37 | }
38 | }
39 | }
40 |
41 | fun configButtonStyle(action: ButtonStyleConfig.() -> Unit) {
42 | buttonItemConfig.itemButtonStyle.action()
43 | }
44 | }
45 |
46 | var IButtonItem.itemButtonText: CharSequence?
47 | get() = buttonItemConfig.itemButtonText
48 | set(value) {
49 | buttonItemConfig.itemButtonText = value
50 | }
51 |
52 | class ButtonItemConfig : IDslItemConfig {
53 |
54 | var itemButtonViewId: Int = R.id.lib_button
55 |
56 | /**按钮显示的文本*/
57 | var itemButtonText: CharSequence? = null
58 | set(value) {
59 | field = value
60 | itemButtonStyle.text = value
61 | }
62 |
63 | /**按钮样式配置项*/
64 | var itemButtonStyle = ButtonStyleConfig().apply {
65 | textGravity = Gravity.CENTER
66 | }
67 |
68 | /**按钮配置回调*/
69 | var itemButtonConfig: (DslButton) -> Unit = {
70 |
71 | }
72 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/style/ICheckGroupItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.style
2 |
3 | import android.view.View
4 | import android.view.ViewGroup
5 | import android.widget.TextView
6 | import com.angcyo.dsladapter.DslAdapterItem
7 | import com.angcyo.dsladapter.DslViewHolder
8 | import com.angcyo.dsladapter.annotation.ItemInitEntryPoint
9 | import com.angcyo.dsladapter.item.IDslItemConfig
10 | import com.angcyo.extend.IToText
11 | import com.angcyo.extend.IToValue
12 | import com.angcyo.item.R
13 | import com.angcyo.item.string
14 | import com.angcyo.item.toStr
15 | import com.angcyo.widget.DslSelector
16 | import com.angcyo.widget.find
17 | import com.angcyo.widget.resetChild
18 |
19 | /**
20 | * @author angcyo
21 | * @since 2022/06/20
22 | */
23 | interface ICheckGroupItem : IAutoInitItem {
24 |
25 | /**配置项*/
26 | var checkGroupItemConfig: CheckGroupItemConfig
27 |
28 | @ItemInitEntryPoint
29 | fun initCheckGroupItem(
30 | itemHolder: DslViewHolder,
31 | itemPosition: Int,
32 | adapterItem: DslAdapterItem,
33 | payloads: List
34 | ) {
35 | itemHolder.v(checkGroupItemConfig.itemCheckGroupViewId)
36 | ?.apply {
37 |
38 | resetChild(
39 | checkGroupItemConfig.itemCheckItems.size,
40 | checkGroupItemConfig.itemCheckLayoutId
41 | ) { itemView, itemIndex ->
42 | val item = checkGroupItemConfig.itemCheckItems[itemIndex]
43 | itemView.tag = checkGroupItemConfig.itemCheckItemToValue(item) //保存数据
44 | itemView.find(R.id.lib_text_view)?.text =
45 | checkGroupItemConfig.itemCheckItemToText(item)
46 | }
47 |
48 | /**安装选择组件*/
49 | checkGroupItemConfig.itemSelectorHelper.install(this) {
50 | dslMultiMode = checkGroupItemConfig.itemMultiMode
51 | dslMinSelectLimit =
52 | if (checkGroupItemConfig.itemMultiMode) checkGroupItemConfig.itemMinSelectLimit else 1
53 |
54 | onSelectItemView = this@ICheckGroupItem::onCheckInterceptSelectView
55 | onSelectViewChange = this@ICheckGroupItem::onCheckSelectViewChange
56 | onSelectIndexChange = this@ICheckGroupItem::onCheckSelectIndexChange
57 | }
58 |
59 | val indexList = mutableListOf()
60 | checkGroupItemConfig.itemCheckedItems.forEach {
61 | indexList.add(checkGroupItemConfig.itemCheckItems.indexOf(it))
62 | }
63 | checkGroupItemConfig.itemSelectorHelper.selector(
64 | indexList,
65 | fromUser = checkGroupItemConfig.itemFirstNotifyChange
66 | )
67 | checkGroupItemConfig.itemFirstNotifyChange = false
68 | }
69 | }
70 |
71 | /**是否需要拦截选中*/
72 | fun onCheckInterceptSelectView(
73 | itemView: View,
74 | index: Int,
75 | select: Boolean,
76 | fromUser: Boolean
77 | ): Boolean {
78 | return false
79 | }
80 |
81 | /**选中后的view改变的回调*/
82 | fun onCheckSelectViewChange(
83 | fromView: View?,
84 | selectViewList: List,
85 | reselect: Boolean,
86 | fromUser: Boolean
87 | ) {
88 |
89 | }
90 |
91 | /**选中后的index改变的回调*/
92 | fun onCheckSelectIndexChange(
93 | fromIndex: Int,
94 | selectIndexList: List,
95 | reselect: Boolean,
96 | fromUser: Boolean
97 | ) {
98 | checkGroupItemConfig._itemCheckedIndexList.clear()
99 | checkGroupItemConfig._itemCheckedIndexList.addAll(selectIndexList)
100 |
101 | //清空之前
102 | checkGroupItemConfig.itemCheckedItems.clear()
103 |
104 | //当前选中项
105 | selectIndexList.forEach {
106 | checkGroupItemConfig.itemCheckedItems.add(checkGroupItemConfig.itemCheckItems[it])
107 | }
108 |
109 | //回调
110 | checkGroupItemConfig.itemCheckChangedAction(fromIndex, selectIndexList, reselect, fromUser)
111 |
112 | //更新依赖
113 | if (fromUser) {
114 | if (this is DslAdapterItem) {
115 | itemChanging = true
116 | }
117 | }
118 | }
119 |
120 | /**Dsl*/
121 | fun configCheckGroupItem(block: CheckGroupItemConfig.() -> Unit) {
122 | checkGroupItemConfig.block()
123 | }
124 | }
125 |
126 | /**需要选择的项*/
127 | var ICheckGroupItem.itemCheckItems: List
128 | get() = checkGroupItemConfig.itemCheckItems
129 | set(value) {
130 | checkGroupItemConfig.itemCheckItems = value
131 | }
132 |
133 | /**选中的项*/
134 | var ICheckGroupItem.itemCheckedItems: MutableList
135 | get() = checkGroupItemConfig.itemCheckedItems
136 | set(value) {
137 | checkGroupItemConfig.itemCheckedItems = value
138 | }
139 |
140 | /**只读属性, 选中的索引值*/
141 | val ICheckGroupItem._itemCheckedIndexList: List
142 | get() = checkGroupItemConfig._itemCheckedIndexList
143 |
144 | /**布局id*/
145 | var ICheckGroupItem.itemCheckLayoutId: Int
146 | get() = checkGroupItemConfig.itemCheckLayoutId
147 | set(value) {
148 | checkGroupItemConfig.itemCheckLayoutId = value
149 | }
150 |
151 | /**回调*/
152 | var ICheckGroupItem.itemCheckChangedAction: (fromIndex: Int, selectIndexList: List, reselect: Boolean, fromUser: Boolean) -> Unit
153 | get() = checkGroupItemConfig.itemCheckChangedAction
154 | set(value) {
155 | checkGroupItemConfig.itemCheckChangedAction = value
156 | }
157 |
158 | class CheckGroupItemConfig : IDslItemConfig {
159 |
160 | /**需要操作的控件id[R.id.lib_flow_layout]*/
161 | var itemCheckGroupViewId: Int = R.id.lib_flow_layout
162 |
163 | /**选项列表*/
164 | var itemCheckItems = listOf()
165 |
166 | /**选中的列表*/
167 | var itemCheckedItems = mutableListOf()
168 |
169 | /**选项布局*/
170 | var itemCheckLayoutId: Int = R.layout.layout_check
171 |
172 | /**是否是多选模式*/
173 | var itemMultiMode = false
174 |
175 | /**多选时, 最小选中数量*/
176 | var itemMinSelectLimit = 0
177 |
178 | /**将选项[item], 转成可以显示在界面的 文本类型*/
179 | var itemCheckItemToText: (item: Any) -> CharSequence? = { item ->
180 | if (item is IToText) {
181 | item.toText()
182 | } else {
183 | item.string()
184 | }
185 | }
186 |
187 | /**将选项[item], 转成表单上传的数据*/
188 | var itemCheckItemToValue: (item: Any) -> Any? = { item ->
189 | if (item is IToValue) {
190 | item.toValue()
191 | } else {
192 | item.toStr()
193 | }
194 | }
195 |
196 | var itemFirstNotifyChange = true
197 |
198 | /**回调*/
199 | var itemCheckChangedAction: (fromIndex: Int, selectIndexList: List, reselect: Boolean, fromUser: Boolean) -> Unit =
200 | { fromIndex, selectIndexList, reselect, fromUser ->
201 |
202 | }
203 |
204 | /**单选/多选支持*/
205 | val itemSelectorHelper = DslSelector()
206 |
207 | //内部使用
208 | var _itemCheckedIndexList = mutableListOf()
209 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/style/ICheckItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.style
2 |
3 | import android.view.View
4 | import android.widget.CompoundButton
5 | import android.widget.ImageView
6 | import com.angcyo.dsladapter.*
7 | import com.angcyo.dsladapter.annotation.ItemInitEntryPoint
8 | import com.angcyo.dsladapter.item.IDslItemConfig
9 | import com.angcyo.item.R
10 | import com.angcyo.dsladapter.DslViewHolder
11 |
12 | /**
13 | *
14 | * Email:angcyo@126.com
15 | * @author angcyo
16 | * @date 2022/02/25
17 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
18 | */
19 | interface ICheckItem : IAutoInitItem {
20 |
21 | /**配置项*/
22 | var checkItemConfig: CheckItemConfig
23 |
24 | @ItemInitEntryPoint
25 | fun initCheckItem(
26 | itemHolder: DslViewHolder,
27 | itemPosition: Int,
28 | adapterItem: DslAdapterItem,
29 | payloads: List
30 | ) {
31 | val item = this
32 | itemHolder.view(checkItemConfig.itemCheckViewId)?.apply {
33 | when (this) {
34 | is ImageView -> setImageResource(checkItemConfig.itemCheckResId)
35 | is CompoundButton -> setButtonDrawable(checkItemConfig.itemCheckResId)
36 | else -> setBackgroundResource(checkItemConfig.itemCheckResId)
37 | }
38 | }
39 |
40 | //[DslAdapterItem]
41 | if (item is DslAdapterItem) {
42 | item.itemDslAdapter?.apply {
43 | if (itemSelectorHelper.selectorModel == ItemSelectorHelper.MODEL_NORMAL) {
44 | //开启多选模式
45 | multiModel()
46 | }
47 | }
48 | item.itemClick = this::onItemClick
49 | item.onItemSelectorChange = this::onItemSelectorChange
50 |
51 | //重新初始化一下Listener
52 | item._initItemListener(itemHolder)
53 |
54 | //状态
55 | itemHolder.selected(checkItemConfig.itemCheckViewId, item.itemIsSelected)
56 | }
57 | }
58 |
59 | /**点击事件的绑定*/
60 | fun onItemClick(view: View) {
61 | val item = this
62 | if (item is DslAdapterItem) {
63 | //切换选中状态
64 | item.select {
65 | //不通知界面更新, 因为如果使用此方式更新界面, item原本的背景波纹效果会丢失
66 | notifyItemChanged = false
67 | }
68 | }
69 | }
70 |
71 | /**选中状态改变后, 通过本地更新的方式更新界面*/
72 | fun onItemSelectorChange(selectorParams: SelectorParams) {
73 | val item = this
74 | if (item is DslAdapterItem) {
75 | item.itemViewHolder()?.apply {
76 | selected(checkItemConfig.itemCheckViewId, item.itemIsSelected)
77 | }
78 | }
79 | }
80 | }
81 |
82 | class CheckItemConfig : IDslItemConfig {
83 |
84 | /**需要操作的控件id[R.id.lib_check_view]*/
85 | var itemCheckViewId: Int = R.id.lib_check_view
86 |
87 | /**选中状态提示资源*/
88 | var itemCheckResId: Int = R.drawable.lib_check_selector
89 |
90 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/style/IDesItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.style
2 |
3 | import com.angcyo.dsladapter.DslAdapterItem
4 | import com.angcyo.dsladapter.annotation.ItemInitEntryPoint
5 | import com.angcyo.dsladapter.item.IDslItemConfig
6 | import com.angcyo.item.R
7 | import com.angcyo.dsladapter.DslViewHolder
8 |
9 | /**
10 | *
11 | * Email:angcyo@126.com
12 | * @author angcyo
13 | * @date 2021/09/23
14 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
15 | */
16 | interface IDesItem : IAutoInitItem {
17 |
18 | /**统一样式配置*/
19 | var desItemConfig: DesItemConfig
20 |
21 | /**初始化*/
22 | @ItemInitEntryPoint
23 | fun initDesItem(itemHolder: DslViewHolder,
24 | itemPosition: Int,
25 | adapterItem: DslAdapterItem,
26 | payloads: List) {
27 | itemHolder.tv(desItemConfig.itemDesViewId)?.apply {
28 | desItemConfig.itemDesStyle.updateStyle(this)
29 | }
30 | }
31 |
32 | fun configDesStyle(action: TextStyleConfig.() -> Unit) {
33 | desItemConfig.itemDesStyle.action()
34 | }
35 | }
36 |
37 | var IDesItem.itemDes: CharSequence?
38 | get() = desItemConfig.itemDes
39 | set(value) {
40 | desItemConfig.itemDes = value
41 | }
42 |
43 | class DesItemConfig : IDslItemConfig {
44 |
45 | var itemDesViewId: Int = R.id.lib_des_view
46 |
47 | /**文本*/
48 | var itemDes: CharSequence? = null
49 | set(value) {
50 | field = value
51 | itemDesStyle.text = value
52 | }
53 |
54 | /**统一样式配置*/
55 | var itemDesStyle = TextStyleConfig()
56 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/style/IEditItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.style
2 |
3 | import android.text.InputFilter
4 | import android.text.InputType
5 | import com.angcyo.dsladapter.DslAdapterItem
6 | import com.angcyo.dsladapter.DslViewHolder
7 | import com.angcyo.dsladapter.annotation.ItemInitEntryPoint
8 | import com.angcyo.dsladapter.item.IDslItemConfig
9 | import com.angcyo.item.DslBaseEditItem
10 | import com.angcyo.item.R
11 | import com.angcyo.item.clearListeners
12 | import com.angcyo.item.onTextChange
13 | import com.angcyo.item.restoreSelection
14 |
15 | /**
16 | * 输入框item
17 | * Email:angcyo@126.com
18 | * @author angcyo
19 | * @date 2021/06/28
20 | * Copyright (c) 2020 angcyo. All rights reserved.
21 | */
22 |
23 | /**文本改变通知回调*/
24 | typealias TextChangeAction = (CharSequence) -> Unit
25 |
26 | interface IEditItem : IAutoInitItem {
27 |
28 | /**配置项*/
29 | var editItemConfig: EditItemConfig
30 |
31 | /**初始化*/
32 | @ItemInitEntryPoint
33 | fun initEditItem(
34 | itemHolder: DslViewHolder,
35 | itemPosition: Int,
36 | adapterItem: DslAdapterItem,
37 | payloads: List
38 | ) {
39 | itemHolder.ev(editItemConfig.itemEditTextViewId)?.apply {
40 | clearListeners()
41 |
42 | //[EditStyleConfig]样式初始化
43 | editItemConfig.itemEditTextStyle.updateStyle(this)
44 |
45 | onTextChange {
46 | editItemConfig._lastEditSelectionStart = selectionStart
47 | editItemConfig._lastEditSelectionEnd = selectionEnd
48 |
49 | editItemConfig.itemEditText = it
50 | }
51 |
52 | //放在最后监听, 防止首次setInputText, 就触发事件.
53 | onTextChange(shakeDelay = editItemConfig.itemTextChangeShakeDelay) {
54 | if (this@IEditItem is DslAdapterItem) {
55 | itemChanging = true
56 | }
57 | onItemEditTextChange(itemHolder, it)
58 | }
59 |
60 | restoreSelection(
61 | editItemConfig._lastEditSelectionStart,
62 | editItemConfig._lastEditSelectionEnd
63 | )
64 | }
65 | }
66 |
67 | fun configEditTextStyle(action: EditStyleConfig.() -> Unit) {
68 | editItemConfig.itemEditTextStyle.action()
69 | }
70 |
71 | /**清除之前的监听*/
72 | fun clearEditListeners(itemHolder: DslViewHolder) {
73 | itemHolder.ev(editItemConfig.itemEditTextViewId)?.clearListeners()
74 | }
75 |
76 | /**编辑的文本改变后*/
77 | fun onItemEditTextChange(itemHolder: DslViewHolder, text: CharSequence) {
78 | editItemConfig.itemTextChangeAction?.invoke(text)
79 | }
80 | }
81 |
82 | var IEditItem.itemEditText: CharSequence?
83 | get() = editItemConfig.itemEditText
84 | set(value) {
85 | editItemConfig.itemEditText = value
86 | }
87 |
88 | var IEditItem.itemEditHint: CharSequence?
89 | get() = editItemConfig.itemEditTextStyle.hint
90 | set(value) {
91 | editItemConfig.itemEditTextStyle.hint = value
92 | }
93 |
94 | /**
95 | * 输入类型
96 | * [InputType.TYPE_CLASS_TEXT]
97 | * [InputType.TYPE_CLASS_NUMBER]
98 | *
99 | * [InputType.TYPE_TEXT_FLAG_MULTI_LINE]
100 | *
101 | * [InputType.TYPE_NUMBER_FLAG_DECIMAL]
102 | * [InputType.TYPE_NUMBER_FLAG_SIGNED]
103 | * */
104 | var IEditItem.itemEditInputType: Int
105 | get() = editItemConfig.itemEditTextStyle.editInputType
106 | set(value) {
107 | editItemConfig.itemEditTextStyle.editInputType = value
108 | }
109 |
110 |
111 | var IEditItem.itemMaxInputLength: Int
112 | get() = editItemConfig.itemEditTextStyle.editMaxInputLength
113 | set(value) {
114 | editItemConfig.itemEditTextStyle.editMaxInputLength = value
115 | }
116 |
117 | /**输入过滤*/
118 | var IEditItem.itemInputFilterList: MutableList
119 | get() = editItemConfig.itemEditTextStyle.editInputFilterList
120 | set(value) {
121 | editItemConfig.itemEditTextStyle.editInputFilterList = value
122 | }
123 |
124 | /**输入过滤*/
125 | var IEditItem.itemEditDigits: String?
126 | get() = editItemConfig.itemEditTextStyle.editDigits
127 | set(value) {
128 | editItemConfig.itemEditTextStyle.editDigits = value
129 | }
130 |
131 | var IEditItem.itemTextChangeAction: TextChangeAction?
132 | get() = editItemConfig.itemTextChangeAction
133 | set(value) {
134 | editItemConfig.itemTextChangeAction = value
135 | }
136 |
137 | class EditItemConfig : IDslItemConfig {
138 |
139 | /**[R.id.lib_edit_view]*/
140 | var itemEditTextViewId: Int = R.id.lib_edit_view
141 |
142 | /**输入框内容*/
143 | var itemEditText: CharSequence? = null
144 | set(value) {
145 | field = value
146 | itemEditTextStyle.text = value
147 | }
148 |
149 | /**是否可编辑*/
150 | var itemNoEditModel: Boolean? = null
151 | set(value) {
152 | field = value
153 | if (value == true) {
154 | itemEditTextStyle.hint = null
155 | }
156 | }
157 |
158 | /**统一样式配置*/
159 | var itemEditTextStyle: EditStyleConfig = EditStyleConfig()
160 |
161 | /**文本改变*/
162 | var itemTextChangeAction: TextChangeAction? = null
163 |
164 | /**文本改变去频限制, 负数表示不开启, 如果短时间内关闭界面了, 可能会获取不到最新的输入框数据*/
165 | var itemTextChangeShakeDelay: Long = DslBaseEditItem.DEFAULT_INPUT_SHAKE_DELAY
166 |
167 | //用于恢复光标的位置
168 | var _lastEditSelectionStart: Int = -1
169 |
170 | var _lastEditSelectionEnd: Int = -1
171 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/style/ILabelItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.style
2 |
3 | import com.angcyo.dsladapter.DslAdapterItem
4 | import com.angcyo.dsladapter.annotation.ItemInitEntryPoint
5 | import com.angcyo.dsladapter.item.IDslItemConfig
6 | import com.angcyo.item.R
7 | import com.angcyo.dsladapter.DslViewHolder
8 |
9 | /**
10 | * 带Label的item
11 | * Email:angcyo@126.com
12 | * @author angcyo
13 | * @date 2021/06/28
14 | * Copyright (c) 2020 angcyo. All rights reserved.
15 | */
16 | interface ILabelItem : IAutoInitItem {
17 |
18 | /**统一样式配置*/
19 | var labelItemConfig: LabelItemConfig
20 |
21 | /**初始化*/
22 | @ItemInitEntryPoint
23 | fun initLabelItem(
24 | itemHolder: DslViewHolder,
25 | itemPosition: Int,
26 | adapterItem: DslAdapterItem,
27 | payloads: List
28 | ) {
29 | itemHolder.tv(labelItemConfig.itemLabelViewId)?.apply {
30 | labelItemConfig.itemLabelTextStyle.updateStyle(this)
31 | }
32 | }
33 |
34 | fun configLabelTextStyle(action: TextStyleConfig.() -> Unit) {
35 | labelItemConfig.itemLabelTextStyle.action()
36 | }
37 | }
38 |
39 | var ILabelItem.itemLabelText: CharSequence?
40 | get() = labelItemConfig.itemLabelText
41 | set(value) {
42 | labelItemConfig.itemLabelText = value
43 | }
44 |
45 | var ILabelItem.itemLabel: CharSequence?
46 | get() = labelItemConfig.itemLabelText
47 | set(value) {
48 | labelItemConfig.itemLabelText = value
49 | }
50 |
51 | /**label视图的最小宽度*/
52 | var ILabelItem.itemLabelMinWidth: Int
53 | get() = labelItemConfig.itemLabelTextStyle.viewMinWidth
54 | set(value) {
55 | configLabelTextStyle {
56 | viewMinWidth = value
57 | }
58 | }
59 |
60 | class LabelItemConfig : IDslItemConfig {
61 |
62 | /**[R.id.lib_label_view]*/
63 | var itemLabelViewId: Int = R.id.lib_label_view
64 |
65 | /**Label文本*/
66 | var itemLabelText: CharSequence? = null
67 | set(value) {
68 | field = value
69 | itemLabelTextStyle.text = value
70 | }
71 |
72 | /**统一样式配置*/
73 | var itemLabelTextStyle: TextStyleConfig = TextStyleConfig()
74 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/style/ISwitchItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.style
2 |
3 | import com.angcyo.dsladapter.DslAdapterItem
4 | import com.angcyo.dsladapter.annotation.ItemInitEntryPoint
5 | import com.angcyo.dsladapter.item.IDslItemConfig
6 | import com.angcyo.github.SwitchButton
7 | import com.angcyo.item.R
8 | import com.angcyo.dsladapter.DslViewHolder
9 |
10 | /**
11 | * [com.angcyo.github.SwitchButton]
12 | * [com.angcyo.item.DslPropertySwitchItem]
13 | * [com.angcyo.item.DslSwitchInfoItem]
14 | * @author angcyo
15 | * @since 2022/06/08
16 | */
17 | interface ISwitchItem : IAutoInitItem {
18 |
19 | /**统一样式配置*/
20 | var switchItemConfig: SwitchItemConfig
21 |
22 | @ItemInitEntryPoint
23 | fun initSwitchItem(
24 | itemHolder: DslViewHolder,
25 | itemPosition: Int,
26 | adapterItem: DslAdapterItem,
27 | payloads: List
28 | ) {
29 | itemHolder.v(switchItemConfig.itemSwitchViewId)?.apply {
30 | setOnCheckedChangeListener(null)
31 |
32 | //刷新界面的时候, 不执行动画
33 | val old = isEnableEffect
34 | isEnableEffect = false
35 | isChecked = itemSwitchChecked
36 | isEnableEffect = old
37 |
38 | setOnCheckedChangeListener(object : SwitchButton.OnCheckedChangeListener {
39 | override fun onCheckedChanged(view: SwitchButton, isChecked: Boolean) {
40 | val checked = itemSwitchChecked
41 | itemSwitchChecked = isChecked
42 | if (checked != itemSwitchChecked) {
43 | if (this@ISwitchItem is DslAdapterItem) {
44 | itemChanging = true
45 | }
46 | switchItemConfig.itemSwitchChangedAction(itemSwitchChecked)
47 | }
48 | }
49 | })
50 | }
51 | }
52 |
53 | /**config*/
54 | fun configSwitchItem(action: SwitchItemConfig.() -> Unit) {
55 | switchItemConfig.action()
56 | }
57 | }
58 |
59 | var ISwitchItem.itemSwitchChecked: Boolean
60 | get() = switchItemConfig.itemSwitchChecked
61 | set(value) {
62 | switchItemConfig.itemSwitchChecked = value
63 | }
64 |
65 | var ISwitchItem.itemSwitchChangedAction: (checked: Boolean) -> Unit
66 | get() = switchItemConfig.itemSwitchChangedAction
67 | set(value) {
68 | switchItemConfig.itemSwitchChangedAction = value
69 | }
70 |
71 | class SwitchItemConfig : IDslItemConfig {
72 |
73 | /**[R.id.lib_switch_view]*/
74 | var itemSwitchViewId: Int = R.id.lib_switch_view
75 |
76 | /**是否选中*/
77 | var itemSwitchChecked = false
78 |
79 | /**状态回调, 提供一个可以完全覆盖的方法*/
80 | var itemSwitchChangedAction: (checked: Boolean) -> Unit = {
81 | }
82 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/style/ITextInfoItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.style
2 |
3 | import com.angcyo.dsladapter.DslAdapterItem
4 | import com.angcyo.dsladapter.annotation.ItemInitEntryPoint
5 | import com.angcyo.dsladapter.item.IDslItemConfig
6 | import com.angcyo.item.R
7 | import com.angcyo.dsladapter.DslViewHolder
8 |
9 | /**
10 | * 带Text的item
11 | * Email:angcyo@126.com
12 | * @author angcyo
13 | * @date 2021/07/16
14 | * Copyright (c) 2020 angcyo. All rights reserved.
15 | */
16 | interface ITextInfoItem : IAutoInitItem {
17 |
18 | var textInfoItemConfig: TextInfoItemConfig
19 |
20 | /**初始化*/
21 | @ItemInitEntryPoint
22 | fun initInfoTextItem(
23 | itemHolder: DslViewHolder,
24 | itemPosition: Int,
25 | adapterItem: DslAdapterItem,
26 | payloads: List
27 | ) {
28 | itemHolder.tv(textInfoItemConfig.itemInfoTextViewId)?.apply {
29 | textInfoItemConfig.itemInfoTextStyle.updateStyle(this)
30 | }
31 | }
32 |
33 | fun configInfoTextStyle(action: TextStyleConfig.() -> Unit) {
34 | textInfoItemConfig.itemInfoTextStyle.action()
35 | }
36 | }
37 |
38 | var ITextInfoItem.itemInfoText: CharSequence?
39 | get() = textInfoItemConfig.itemInfoText
40 | set(value) {
41 | textInfoItemConfig.itemInfoText = value
42 | }
43 |
44 | class TextInfoItemConfig : IDslItemConfig {
45 | /**[R.id.lib_text_view]*/
46 | var itemInfoTextViewId: Int = R.id.lib_text_view
47 |
48 | /**条目文本*/
49 | var itemInfoText: CharSequence? = null
50 | set(value) {
51 | field = value
52 | itemInfoTextStyle.text = value
53 | }
54 |
55 | /**统一样式配置*/
56 | var itemInfoTextStyle: TextStyleConfig = TextStyleConfig()
57 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/style/ITextItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.style
2 |
3 | import com.angcyo.dsladapter.DslAdapterItem
4 | import com.angcyo.dsladapter.DslViewHolder
5 | import com.angcyo.dsladapter.annotation.ItemInitEntryPoint
6 | import com.angcyo.dsladapter.item.IDslItemConfig
7 | import com.angcyo.item.R
8 | import com.angcyo.item._dimen
9 | import com.angcyo.widget.span.undefined_float
10 |
11 | /**
12 | *
13 | * Email:angcyo@126.com
14 | * @author angcyo
15 | * @date 2021/09/18
16 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
17 | */
18 | interface ITextItem : IAutoInitItem {
19 |
20 | /**配置类 */
21 | var textItemConfig: TextItemConfig
22 |
23 | /**初始化*/
24 | @ItemInitEntryPoint
25 | fun initTextItem(
26 | itemHolder: DslViewHolder,
27 | itemPosition: Int,
28 | adapterItem: DslAdapterItem,
29 | payloads: List
30 | ) {
31 | itemHolder.tv(textItemConfig.itemTextViewId)?.apply {
32 | textItemConfig.itemTextStyle.updateStyle(this)
33 | }
34 | }
35 |
36 | fun configTextStyle(action: TextStyleConfig.() -> Unit) {
37 | textItemConfig.itemTextStyle.action()
38 | }
39 |
40 | /**加粗样式*/
41 | fun boldStyle() {
42 | configTextStyle {
43 | textBold = true
44 | if (textSize == undefined_float) {
45 | textSize = _dimen(R.dimen.text_sub_size).toFloat()
46 | }
47 | }
48 | }
49 | }
50 |
51 | var ITextItem.itemText: CharSequence?
52 | get() = textItemConfig.itemText
53 | set(value) {
54 | textItemConfig.itemText = value
55 | }
56 |
57 | var ITextItem.itemHint: CharSequence?
58 | get() = textItemConfig.itemTextStyle.hint
59 | set(value) {
60 | textItemConfig.itemTextStyle.hint = value
61 | }
62 |
63 | class TextItemConfig : IDslItemConfig {
64 |
65 | /**[R.id.lib_text_view]*/
66 | var itemTextViewId: Int = R.id.lib_text_view
67 |
68 | /**条目文本*/
69 | var itemText: CharSequence? = null
70 | set(value) {
71 | field = value
72 | itemTextStyle.text = value
73 | }
74 |
75 | /**统一样式配置*/
76 | var itemTextStyle: TextStyleConfig = TextStyleConfig()
77 |
78 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/style/ImageStyleConfig.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.style
2 |
3 | import android.view.View
4 | import android.widget.ImageView
5 |
6 | /**
7 | * 图片控件样式
8 | * Email:angcyo@126.com
9 | * @author angcyo
10 | * @date 2021/09/23
11 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
12 | */
13 | class ImageStyleConfig : ViewStyleConfig() {
14 |
15 | var imageScaleType: ImageView.ScaleType? = null
16 |
17 | override fun updateStyle(view: View) {
18 | super.updateStyle(view)
19 |
20 | if (view is ImageView) {
21 | //
22 | if (imageScaleType == null) {
23 | imageScaleType = view.scaleType
24 | }
25 | view.scaleType = imageScaleType
26 |
27 | //
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/style/TextStyleConfig.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.style
2 |
3 | import android.content.res.ColorStateList
4 | import android.graphics.drawable.Drawable
5 | import android.util.TypedValue
6 | import android.view.Gravity
7 | import android.view.View
8 | import android.widget.TextView
9 | import com.angcyo.dsladapter.UndefinedDrawable
10 | import com.angcyo.dsladapter.undefined_size
11 | import com.angcyo.dsladapter.visible
12 | import com.angcyo.item.bottomIco
13 | import com.angcyo.item.leftIco
14 | import com.angcyo.item.rightIco
15 | import com.angcyo.item.setBoldText
16 | import com.angcyo.item.topIco
17 | import com.angcyo.widget.span.undefined_color
18 | import com.angcyo.widget.span.undefined_float
19 |
20 | /**
21 | * 文本样式配置
22 | * Email:angcyo@126.com
23 | * @author angcyo
24 | * @date 2020/06/09
25 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
26 | */
27 |
28 | open class TextStyleConfig : ViewStyleConfig() {
29 |
30 | /**显示的文本内容*/
31 | var text: CharSequence? = null
32 |
33 | /**当[text]为null时, 隐藏控件*/
34 | var goneOnTextEmpty: Boolean = false
35 |
36 | /**提示文本内容*/
37 | var hint: CharSequence? = null
38 | var textBold: Boolean = false
39 | var textColor: Int = undefined_color
40 | var textColors: ColorStateList? = null
41 |
42 | var textSize: Float = undefined_float
43 | var textGravity: Int = Gravity.LEFT or Gravity.CENTER_VERTICAL
44 |
45 | /**四向图标, 需要指定bounds*/
46 | var leftDrawable: Drawable? = UndefinedDrawable()
47 | var topDrawable: Drawable? = UndefinedDrawable()
48 | var rightDrawable: Drawable? = UndefinedDrawable()
49 | var bottomDrawable: Drawable? = UndefinedDrawable()
50 | var drawablePadding = undefined_size
51 |
52 | /**生效*/
53 | override fun updateStyle(view: View) {
54 | super.updateStyle(view)
55 |
56 | if (view is TextView) {
57 |
58 | if (text == null) {
59 | text = view.text
60 | }
61 |
62 | if (hint == null) {
63 | hint = view.hint
64 | }
65 |
66 | with(view) {
67 | text = this@TextStyleConfig.text
68 |
69 | //[TextView]设置最小宽度和最小高度
70 | if (viewMinWidth != undefined_size) {
71 | minWidth = viewMinWidth
72 |
73 | }
74 | if (viewMinHeight != undefined_size) {
75 | minHeight = viewMinHeight
76 | }
77 |
78 | if (goneOnTextEmpty) {
79 | visible(!this@TextStyleConfig.text.isNullOrEmpty())
80 | }
81 |
82 | //兼容
83 | view.hint = hint
84 |
85 | gravity = textGravity
86 |
87 | setBoldText(textBold)
88 |
89 | //颜色, 防止复用. 所以在未指定的情况下, 要获取默认的颜色.
90 | val colors = when {
91 | this@TextStyleConfig.textColors != null -> {
92 | this@TextStyleConfig.textColors
93 | }
94 |
95 | textColor != undefined_color -> {
96 | ColorStateList.valueOf(textColor)
97 | }
98 |
99 | else -> {
100 | textColors
101 | }
102 | }
103 | if (colors != this@TextStyleConfig.textColors) {
104 | this@TextStyleConfig.textColors = colors
105 | }
106 | setTextColor(colors)
107 |
108 | //字体大小同理.
109 | val size = if (this@TextStyleConfig.textSize != undefined_float) {
110 | this@TextStyleConfig.textSize
111 | } else {
112 | textSize
113 | }
114 | this@TextStyleConfig.textSize = size
115 | setTextSize(TypedValue.COMPLEX_UNIT_PX, size)
116 |
117 | //padding
118 | if (drawablePadding == undefined_size) {
119 | drawablePadding = compoundDrawablePadding
120 | }
121 | compoundDrawablePadding = drawablePadding
122 |
123 | //四向图标修改
124 | if (leftDrawable is UndefinedDrawable) {
125 | leftDrawable = leftIco()
126 | }
127 | if (topDrawable is UndefinedDrawable) {
128 | topDrawable = topIco()
129 | }
130 | if (rightDrawable is UndefinedDrawable) {
131 | rightDrawable = rightIco()
132 | }
133 | if (bottomDrawable is UndefinedDrawable) {
134 | bottomDrawable = bottomIco()
135 | }
136 | setCompoundDrawablesRelative(
137 | leftDrawable,
138 | topDrawable,
139 | rightDrawable,
140 | bottomDrawable
141 | )
142 | }
143 | }
144 | }
145 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/item/style/ViewStyleConfig.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item.style
2 |
3 | import android.graphics.drawable.Drawable
4 | import android.os.Build
5 | import android.view.Gravity
6 | import android.view.View
7 | import android.widget.FrameLayout
8 | import androidx.constraintlayout.widget.ConstraintLayout
9 | import com.angcyo.dsladapter.UndefinedDrawable
10 | import com.angcyo.dsladapter.setBgDrawable
11 | import com.angcyo.dsladapter.setWidthHeight
12 | import com.angcyo.dsladapter.undefined_size
13 | import com.angcyo.widget.span.undefined_int
14 |
15 | /**
16 | * View基础样式配置
17 | * Email:angcyo@126.com
18 | * @author angcyo
19 | * @date 2020/06/09
20 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
21 | */
22 |
23 | open class ViewStyleConfig {
24 |
25 | /**限制最小宽高*/
26 | var viewWidth: Int = undefined_size
27 | var viewMinWidth: Int = undefined_size
28 |
29 | /**指定宽高*/
30 | var viewHeight: Int = undefined_size
31 | var viewMinHeight: Int = undefined_size
32 |
33 | /**视图可见性[visibility]*/
34 | var viewVisibility: Int = undefined_int
35 |
36 | /**padding值*/
37 | var paddingLeft: Int = undefined_size
38 | var paddingRight: Int = undefined_size
39 | var paddingTop: Int = undefined_size
40 | var paddingBottom: Int = undefined_size
41 |
42 | /**背景*/
43 | var backgroundDrawable: Drawable? = UndefinedDrawable()
44 |
45 | /**部分布局支持*/
46 | var layoutGravity: Int = Gravity.NO_GRAVITY
47 |
48 | /**
49 | * 需要parent为[ConstraintLayout]
50 | * [androidx.constraintlayout.widget.ConstraintLayout.LayoutParams.dimensionRatio]*/
51 | var viewDimensionRatio: String? = null
52 |
53 | /**更新样式*/
54 | open fun updateStyle(view: View) {
55 | with(view) {
56 | //初始化默认值
57 | if (this@ViewStyleConfig.paddingLeft == undefined_size) {
58 | this@ViewStyleConfig.paddingLeft = paddingLeft
59 | }
60 | if (this@ViewStyleConfig.paddingRight == undefined_size) {
61 | this@ViewStyleConfig.paddingRight = paddingRight
62 | }
63 | if (this@ViewStyleConfig.paddingTop == undefined_size) {
64 | this@ViewStyleConfig.paddingTop = paddingTop
65 | }
66 | if (this@ViewStyleConfig.paddingBottom == undefined_size) {
67 | this@ViewStyleConfig.paddingBottom = paddingBottom
68 | }
69 |
70 | //可见性
71 | if (viewVisibility == undefined_int) {
72 | viewVisibility = visibility
73 | }
74 | visibility = viewVisibility
75 |
76 | //设置
77 | setPadding(
78 | this@ViewStyleConfig.paddingLeft,
79 | this@ViewStyleConfig.paddingTop,
80 | this@ViewStyleConfig.paddingRight,
81 | this@ViewStyleConfig.paddingBottom
82 | )
83 |
84 | val lp = layoutParams
85 |
86 | if (backgroundDrawable is UndefinedDrawable) {
87 | backgroundDrawable = background
88 | }
89 | setBgDrawable(backgroundDrawable)
90 |
91 | //初始化默认值
92 | if (viewMinWidth == undefined_size && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
93 | viewMinWidth = minimumWidth
94 | }
95 | if (viewMinHeight == undefined_size && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
96 | viewMinHeight = minimumHeight
97 | }
98 | //设置
99 | if (viewMinWidth != undefined_size) {
100 | minimumWidth = viewMinWidth
101 | when (view) {
102 | is ConstraintLayout -> view.minWidth = viewMinWidth
103 | }
104 | }
105 | if (viewMinHeight != undefined_size) {
106 | minimumHeight = viewMinHeight
107 | when (view) {
108 | is ConstraintLayout -> view.minHeight = viewMinHeight
109 | }
110 | }
111 |
112 | //初始化默认值
113 | if (viewWidth == undefined_size) {
114 | viewWidth = lp.width
115 | }
116 | if (viewHeight == undefined_size) {
117 | viewHeight = lp.height
118 | }
119 | //设置
120 | setWidthHeight(viewWidth, viewHeight)
121 | if (lp is ConstraintLayout.LayoutParams) {
122 | if (viewDimensionRatio == null) {
123 | viewDimensionRatio = lp.dimensionRatio
124 | } else {
125 | lp.dimensionRatio = viewDimensionRatio
126 | layoutParams = lp
127 | }
128 | }
129 |
130 | //Gravity
131 | if (lp is FrameLayout.LayoutParams) {
132 | val oldGravity = lp.gravity
133 | if (layoutGravity == Gravity.NO_GRAVITY) {
134 | layoutGravity = oldGravity
135 | }
136 | lp.gravity = layoutGravity
137 | if (oldGravity != layoutGravity) {
138 | layoutParams = lp
139 | }
140 | }
141 | }
142 | }
143 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/widget/BadgeTextView.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.widget
2 |
3 | import android.content.Context
4 | import android.graphics.Canvas
5 | import android.util.AttributeSet
6 | import androidx.appcompat.widget.AppCompatTextView
7 | import com.angcyo.drawable.DslAttrBadgeDrawable
8 | import com.angcyo.item.isNotSpecified
9 |
10 | /**
11 | * 单纯的用来绘制角标的控件
12 | * 使用属性[app:r_badge_text="xxx"]设置角标
13 | *
14 | * badgePaddingLeft
15 | * badgePaddingRight
16 | * badgePaddingTop
17 | * badgePaddingBottom
18 | *
19 | * Email:angcyo@126.com
20 | * @author angcyo
21 | * @date 2021/09/23
22 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
23 | */
24 | class BadgeTextView : AppCompatTextView, IBadgeView {
25 |
26 | /**角标绘制*/
27 | override var dslBadeDrawable = DslAttrBadgeDrawable()
28 |
29 | constructor(context: Context) : super(context) {
30 | initAttribute(context, null)
31 | }
32 |
33 | constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
34 | initAttribute(context, attrs)
35 | }
36 |
37 | constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
38 | context,
39 | attrs,
40 | defStyleAttr
41 | ) {
42 | initAttribute(context, attrs)
43 | }
44 |
45 | private fun initAttribute(context: Context, attributeSet: AttributeSet?) {
46 | dslBadeDrawable.apply {
47 | badgeOffsetX = 0
48 | badgeOffsetY = 0
49 | initAttribute(context, attributeSet)
50 | callback = this@BadgeTextView
51 | dslGravity.gravityRelativeCenter = false
52 | }
53 | }
54 |
55 | override fun onDraw(canvas: Canvas) {
56 | super.onDraw(canvas)
57 |
58 | dslBadeDrawable.apply {
59 | setBounds(0, 0, measuredWidth, measuredHeight)
60 | draw(canvas)
61 | }
62 | }
63 |
64 | /*override fun setText(text: CharSequence?, type: BufferType?) {
65 | super.setText(text, type)
66 | //在构造方法中调用此方法[dslBadeDrawable]为空
67 | dslBadeDrawable?.badgeText = text.toString()
68 | }*/
69 |
70 | /**角标的文本, 空字符串会绘制成小圆点*/
71 | fun updateBadge(text: String? = null, action: DslAttrBadgeDrawable.() -> Unit = {}) {
72 | dslBadeDrawable.apply {
73 | drawBadge = true
74 | //badgeGravity = Gravity.TOP or Gravity.RIGHT
75 | badgeText = text
76 | //badgeCircleRadius
77 | //badgeOffsetY = 4 * dpi
78 | //cornerRadius(25 * dp)
79 | action()
80 | }
81 | postInvalidateOnAnimation()
82 | }
83 |
84 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
85 | //of kotlin
86 | //val widthSize = MeasureSpec.getSize(widthMeasureSpec)
87 | val widthMode = MeasureSpec.getMode(widthMeasureSpec)
88 | //val heightSize = MeasureSpec.getSize(heightMeasureSpec)
89 | val heightMode = MeasureSpec.getMode(heightMeasureSpec)
90 |
91 | if (widthMode.isNotSpecified() && heightMode.isNotSpecified()) {
92 | setMeasuredDimension(
93 | dslBadeDrawable.intrinsicWidth + paddingLeft + paddingRight,
94 | dslBadeDrawable.intrinsicHeight + paddingTop + paddingBottom
95 | )
96 | } else {
97 | super.onMeasure(widthMeasureSpec, heightMeasureSpec)
98 | }
99 | }
100 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/widget/CharLengthFilter.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.widget
2 |
3 | import android.text.InputFilter
4 | import android.text.Spanned
5 |
6 | /**
7 | * 使用英文字符数过滤, 一个汉字等于2个英文, 一个emoji表情等于2个汉字
8 | * Created by angcyo on 2018-08-10.
9 | * Email:angcyo@126.com
10 | */
11 | class CharLengthFilter(var maxLen: Int) : InputFilter {
12 |
13 | companion object {
14 | const val MAX_CHAR: Char = 255.toChar()
15 | }
16 |
17 | /**
18 | * 将 dest 字符中, 的dstart 位置到 dend 位置的字符串,
19 | * 替换成 source 字符中, 的start 位置到 end 对应的字符串
20 | */
21 | override fun filter(
22 | source: CharSequence,
23 | start: Int,
24 | end: Int,
25 | dest: Spanned,
26 | dstart: Int,
27 | dend: Int
28 | ): CharSequence? {
29 | var dIndex = 0
30 | var count = 0
31 | var dCount = 0 //dest 中, 需要替换掉多少个char
32 | //当前已经存在char数量
33 | while (count <= maxLen && dIndex < dest.length) {
34 | val c = dest[dIndex++]
35 | if (c <= MAX_CHAR) {
36 | count += 1
37 | if (dIndex in dstart until dend) {
38 | dCount += 1
39 | }
40 | } else {
41 | if (dIndex in dstart until dend) {
42 | dCount += 1
43 | }
44 | count += 2
45 | }
46 | }
47 | count -= dCount
48 | if (count > maxLen) {
49 | return dest.subSequence(0, dIndex - 1)
50 | }
51 | //本次需要输入的char数量
52 | var sIndex = 0
53 | while (count <= maxLen && sIndex < source.length) {
54 | val c = source[sIndex++]
55 | count = if (c <= MAX_CHAR) {
56 | count + 1
57 | } else {
58 | count + 2
59 | }
60 | }
61 | return if (count > maxLen) { //已经存在的char长度, + 输入的char长度, 大于限制长度
62 | //越界
63 | sIndex--
64 | source.subSequence(0, sIndex)
65 | } else { // keep original
66 | null
67 | }
68 | }
69 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/widget/IBadgeView.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.widget
2 |
3 | import com.angcyo.drawable.DslAttrBadgeDrawable
4 |
5 | /**
6 | *
7 | * Email:angcyo@126.com
8 | * @author angcyo
9 | * @date 2021/09/23
10 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
11 | */
12 | interface IBadgeView {
13 | var dslBadeDrawable: DslAttrBadgeDrawable
14 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/widget/ITouchDelegate.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.widget
2 |
3 | import android.view.MotionEvent
4 |
5 | /**
6 | *
7 | * Email:angcyo@126.com
8 | * @author angcyo
9 | * @date 2021/11/19
10 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
11 | */
12 | interface ITouchDelegate {
13 | fun getTouchActionDelegate(): TouchActionDelegate
14 | }
15 |
16 | fun ITouchDelegate.onDispatchTouchEventAction(action: (ev: MotionEvent) -> Unit): TouchListener {
17 | val listener = object : TouchListener {
18 | override fun onDispatchTouchEventAction(ev: MotionEvent) {
19 | action(ev)
20 | }
21 | }
22 | getTouchActionDelegate()?.touchListener?.add(listener)
23 | return listener
24 | }
25 |
26 | fun ITouchDelegate.onInterceptTouchEventAction(action: (ev: MotionEvent) -> Unit): TouchListener {
27 | val listener = object : TouchListener {
28 | override fun onInterceptTouchEventAction(ev: MotionEvent) {
29 | action(ev)
30 | }
31 | }
32 | getTouchActionDelegate()?.touchListener?.add(listener)
33 | return listener
34 | }
35 |
36 | fun ITouchDelegate.onTouchEventAction(action: (ev: MotionEvent) -> Unit): TouchListener {
37 | val listener = object : TouchListener {
38 | override fun onTouchEventAction(ev: MotionEvent) {
39 | action(ev)
40 | }
41 | }
42 | getTouchActionDelegate()?.touchListener?.add(listener)
43 | return listener
44 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/widget/ITouchHold.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.widget
2 |
3 | /**
4 | *
5 | * Email:angcyo@126.com
6 | * @author angcyo
7 | * @date 2021/06/28
8 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
9 | */
10 | interface ITouchHold {
11 | /**手势是否为松开*/
12 | var isTouchHold: Boolean
13 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/widget/TouchActionDelegate.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.widget
2 |
3 | import android.view.MotionEvent
4 |
5 | /**
6 | * 手势代理
7 | * Email:angcyo@126.com
8 | * @author angcyo
9 | * @date 2021/11/19
10 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
11 | */
12 | open class TouchActionDelegate {
13 |
14 | val touchListener = mutableSetOf()
15 |
16 | fun dispatchTouchEvent(ev: MotionEvent) {
17 | touchListener.forEach {
18 | it.onDispatchTouchEventAction(ev)
19 | }
20 | }
21 |
22 | fun onInterceptTouchEvent(ev: MotionEvent) {
23 | touchListener.forEach {
24 | it.onInterceptTouchEventAction(ev)
25 | }
26 | }
27 |
28 | fun onTouchEvent(ev: MotionEvent) {
29 | touchListener.forEach {
30 | it.onTouchEventAction(ev)
31 | }
32 | }
33 |
34 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/widget/TouchListener.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.widget
2 |
3 | import android.view.MotionEvent
4 |
5 | /**
6 | * Touch监听
7 | * Email:angcyo@126.com
8 | * @author angcyo
9 | * @date 2021/11/19
10 | * Copyright (c) 2020 ShenZhen Wayto Ltd. All rights reserved.
11 | */
12 | interface TouchListener {
13 |
14 | fun onDispatchTouchEventAction(ev: MotionEvent) {
15 |
16 | }
17 |
18 | fun onInterceptTouchEventAction(ev: MotionEvent) {
19 |
20 | }
21 |
22 | fun onTouchEventAction(ev: MotionEvent) {
23 |
24 | }
25 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/widget/ViewGroupEx.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.widget
2 |
3 | import android.view.LayoutInflater
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import androidx.annotation.IdRes
7 | import com.angcyo.dsladapter.size
8 | import com.angcyo.item.R
9 | import kotlin.math.absoluteValue
10 | import kotlin.math.min
11 |
12 | /**
13 | * Kotlin ViewGroup的扩展
14 | * Created by angcyo on 2017-07-26.
15 | */
16 |
17 | fun View?.find(@IdRes id: Int): T? {
18 | return this?.findViewById(id)
19 | }
20 |
21 | fun ViewGroup.resetChild(
22 | list: List?,
23 | layoutId: Int,
24 | init: (itemView: View, item: T, itemIndex: Int) -> Unit = { _, _, _ -> }
25 | ) {
26 | resetChild(list.size(), layoutId) { itemView, itemIndex ->
27 | val item = list!!.get(itemIndex)
28 | init(itemView, item, itemIndex)
29 | }
30 | }
31 |
32 | fun ViewGroup.resetChild(
33 | size: Int,
34 | layoutId: Int,
35 | init: (itemView: View, itemIndex: Int) -> Unit = { _, _ -> }
36 | ) {
37 | //如果布局id不一样, 说明child不一样, 需要remove
38 | for (index in childCount - 1 downTo 0) {
39 | val tag = getChildAt(index).getTag(R.id.tag)
40 | if (tag == null || (tag is Int && tag != layoutId)) {
41 | removeViewAt(index)
42 | }
43 | }
44 |
45 | resetChildCount(size) { childIndex, childView ->
46 | if (childView == null) {
47 | val itemView = LayoutInflater.from(context).inflate(layoutId, this, false)
48 | itemView.setTag(R.id.tag, layoutId)
49 | itemView
50 | } else {
51 | childView
52 | }
53 | }
54 |
55 | for (i in 0 until size) {
56 | init(getChildAt(i), i)
57 | }
58 | }
59 |
60 | /**将子View的数量, 重置到指定的数量*/
61 | fun ViewGroup.resetChildCount(
62 | newSize: Int,
63 | createOrInitView: (childIndex: Int, childView: View?) -> View
64 | ) {
65 | val oldSize = childCount
66 | val count = newSize - oldSize
67 | if (count > 0) {
68 | //需要补充子View
69 | for (i in 0 until count) {
70 | addView(createOrInitView.invoke(oldSize + i, null))
71 | }
72 | } else if (count < 0) {
73 | //需要移除子View
74 | for (i in 0 until count.absoluteValue) {
75 | removeViewAt(oldSize - 1 - i)
76 | }
77 | }
78 |
79 | //初始化
80 | for (i in 0 until min(oldSize, newSize)) {
81 | createOrInitView.invoke(i, getChildAt(i))
82 | }
83 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/widget/recycler/GridLayoutManagerWrap.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.widget.recycler
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import androidx.recyclerview.widget.GridLayoutManager
6 | import androidx.recyclerview.widget.RecyclerView
7 |
8 | /**
9 | *
10 | * Email:angcyo@126.com
11 | * @author angcyo
12 | * @date 2020/01/02
13 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
14 | */
15 | class GridLayoutManagerWrap : GridLayoutManager {
16 |
17 | constructor(context: Context, spanCount: Int) : super(context, spanCount)
18 |
19 | constructor(
20 | context: Context,
21 | attrs: AttributeSet?,
22 | defStyleAttr: Int,
23 | defStyleRes: Int
24 | ) : super(context, attrs, defStyleAttr, defStyleRes)
25 |
26 | constructor(
27 | context: Context,
28 | spanCount: Int,
29 | orientation: Int,
30 | reverseLayout: Boolean
31 | ) : super(context, spanCount, orientation, reverseLayout)
32 |
33 | override fun onLayoutChildren(
34 | recycler: RecyclerView.Recycler,
35 | state: RecyclerView.State
36 | ) {
37 | try {
38 | super.onLayoutChildren(recycler, state)
39 | } catch (e: Exception) {
40 | e.printStackTrace()
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/widget/recycler/LinearLayoutManagerWrap.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.widget.recycler
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import androidx.recyclerview.widget.LinearLayoutManager
6 | import androidx.recyclerview.widget.RecyclerView
7 |
8 | /**
9 | *
10 | * Email:angcyo@126.com
11 | * @author angcyo
12 | * @date 2020/01/02
13 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
14 | */
15 |
16 | class LinearLayoutManagerWrap : LinearLayoutManager {
17 |
18 | constructor(context: Context) : super(context)
19 |
20 | constructor(
21 | context: Context,
22 | orientation: Int = RecyclerView.VERTICAL
23 | ) : super(context, orientation, false)
24 |
25 | constructor(
26 | context: Context,
27 | orientation: Int,
28 | reverseLayout: Boolean
29 | ) : super(context, orientation, reverseLayout)
30 |
31 | constructor(
32 | context: Context,
33 | attrs: AttributeSet?,
34 | defStyleAttr: Int,
35 | defStyleRes: Int
36 | ) : super(context, attrs, defStyleAttr, defStyleRes)
37 |
38 | override fun onLayoutChildren(recycler: RecyclerView.Recycler, state: RecyclerView.State) {
39 | try {
40 | super.onLayoutChildren(recycler, state)
41 | } catch (e: Exception) {
42 | e.printStackTrace()
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/widget/recycler/ScrollPositionConfig.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.widget.recycler
2 |
3 | import androidx.recyclerview.widget.RecyclerView
4 |
5 | /**
6 | * 记录[RecyclerView]的滚动位置状态
7 | * Email:angcyo@126.com
8 | * @author angcyo
9 | * @date 2020/03/19
10 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
11 | */
12 |
13 | data class ScrollPositionConfig(
14 | //位置
15 | var adapterPosition: Int = RecyclerView.NO_POSITION,
16 |
17 | //上下距离
18 | var left: Int = 0,
19 | var top: Int = 0
20 | )
--------------------------------------------------------------------------------
/dslitem/src/main/java/com/angcyo/widget/recycler/StaggeredGridLayoutManagerWrap.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.widget.recycler
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import androidx.recyclerview.widget.RecyclerView
6 | import androidx.recyclerview.widget.StaggeredGridLayoutManager
7 |
8 | /**
9 | *
10 | * Email:angcyo@126.com
11 | * @author angcyo
12 | * @date 2020/01/02
13 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
14 | */
15 |
16 | class StaggeredGridLayoutManagerWrap : StaggeredGridLayoutManager {
17 |
18 | constructor(spanCount: Int, orientation: Int) : super(spanCount, orientation)
19 |
20 | constructor(
21 | context: Context,
22 | attrs: AttributeSet?,
23 | defStyleAttr: Int,
24 | defStyleRes: Int
25 | ) : super(context, attrs, defStyleAttr, defStyleRes)
26 |
27 | override fun onLayoutChildren(
28 | recycler: RecyclerView.Recycler,
29 | state: RecyclerView.State
30 | ) {
31 | try {
32 | super.onLayoutChildren(recycler, state)
33 | } catch (e: Exception) {
34 | e.printStackTrace()
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable-anydpi/lib_audio_cover_tip.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable-anydpi/lib_audio_tip.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable-anydpi/lib_check_checked.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable-anydpi/lib_check_normal.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable-anydpi/lib_icon_edit_tip.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable-anydpi/lib_image_remove.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable-anydpi/lib_image_tip.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable-anydpi/lib_video_cover_tip.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
13 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable-anydpi/lib_video_tip.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable-v21/lib_bg2_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable-v21/lib_bg_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable-v21/lib_ripple_shape.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable/lib_bottom_line_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable/lib_check_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable/lib_dark_bottom_line_shape.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
7 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable/lib_duration_bg_shape.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable/lib_image_remove_circle_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable/lib_remove_circle_shape.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable/lib_theme_bottom_line_shape.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
7 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable/lib_theme_circle_shape.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/drawable/lib_theme_press_circle_shape.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/layout/dsl_bottom_button_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
24 |
25 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/layout/dsl_bottom_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/layout/dsl_button_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/layout/dsl_edit_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/layout/dsl_extent_switch_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
18 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/layout/dsl_extent_text_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
23 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/layout/dsl_grid_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
23 |
24 |
36 |
37 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/layout/dsl_info_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
30 |
31 |
42 |
43 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/layout/dsl_label_edit_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
26 |
27 |
35 |
36 |
43 |
44 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/layout/dsl_label_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/layout/dsl_label_text_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
21 |
22 |
35 |
36 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/layout/dsl_nested_recycler_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/layout/dsl_text_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/layout/layout_check.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/layout/lib_tab_item_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
23 |
24 |
37 |
38 |
48 |
49 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/values/attr_badge_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/values/attr_dsl_recycler_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/values/item_ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/values/item_styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 75dp
5 | 2dp
6 | 1dp
7 |
8 |
9 | 50dp
10 |
11 | 20dp
12 |
13 | @dimen/text_assist_size
14 |
15 | 50dp
16 |
17 | #C3C7CF
18 |
19 |
29 |
30 |
40 |
41 |
48 |
49 |
50 |
59 |
60 |
63 |
64 |
--------------------------------------------------------------------------------
/dslitem/src/main/res/values/switch_button_attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/dslitem2/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/dslitem2/README.md:
--------------------------------------------------------------------------------
1 | # dslitem
2 | 2020-01-01
3 |
4 | 常用 `DslItem`, 如果此库丰富了, 那么UI, 就是`乐高`拼出来的.
5 |
6 | ```kotlin
7 | renderDslAdapter{
8 | dslItem1()
9 | dslItem2()
10 | dslItem3()
11 | ...
12 | dslItemX()
13 | dslItemY()
14 | dslItemZ()
15 | }
16 | ```
--------------------------------------------------------------------------------
/dslitem2/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 |
4 | android {
5 | compileSdk Integer.parseInt(C_SDK)
6 |
7 | defaultConfig {
8 | vectorDrawables.useSupportLibrary = true
9 |
10 | minSdk Integer.parseInt(M_SDK)
11 | targetSdk Integer.parseInt(T_SDK)
12 |
13 | consumerProguardFiles 'consumer-rules.pro'
14 | }
15 | namespace 'com.angcyo.item2'
16 | }
17 |
18 | dependencies {
19 | api project(":dslitem")
20 |
21 | //https://jcenter.bintray.com/rouchuan/viewpagerlayoutmanager/viewpagerlayoutmanager/
22 | //https://github.com/leochuan/ViewPagerLayoutManager
23 | //https://github.com/angcyo/ViewPagerLayoutManager
24 | //api 'rouchuan.viewpagerlayoutmanager:viewpagerlayoutmanager:2.0.22'
25 | api 'com.github.angcyo:ViewPagerLayoutManager:2.1.3'
26 |
27 | //https://mvnrepository.com/artifact/androidx.appcompat/appcompat
28 | implementation 'androidx.appcompat:appcompat:1.6.1'
29 | }
30 |
--------------------------------------------------------------------------------
/dslitem2/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angcyo/DslItem/92c5a7c665636c7af4c1f497c41657653ae80326/dslitem2/consumer-rules.pro
--------------------------------------------------------------------------------
/dslitem2/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/dslitem2/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/dslitem2/src/main/java/com/angcyo/item2/DslBannerItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item2
2 |
3 | import android.widget.LinearLayout
4 | import androidx.recyclerview.widget.RecyclerView
5 | import com.angcyo.dsladapter.DslAdapterItem
6 | import com.angcyo.dsladapter.DslViewHolder
7 | import com.angcyo.item.DslNestedRecyclerItem
8 | import com.angcyo.item.base.LibInitProvider
9 | import com.angcyo.item2.widget.recycler.DrawableIndicator
10 | import com.leochuan.ScaleLayoutManager
11 | import com.leochuan.ViewPagerLayoutManager
12 |
13 | /**
14 | * 轮播图切换item
15 | * Email:angcyo@126.com
16 | * @author angcyo
17 | * @date 2020/03/18
18 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
19 | */
20 | open class DslBannerItem : DslNestedRecyclerItem() {
21 |
22 | init {
23 | itemLayoutId = R.layout.dsl_banner_item
24 |
25 | nestedRecyclerItemConfig.itemNestedLayoutManager =
26 | ScaleLayoutManager(LibInitProvider.contentProvider, 0).apply {
27 | recycleChildrenOnDetach = true
28 | isFullItem = true //全屏item
29 | maxVisibleItemCount = 3 //最大可见item数量
30 | infinite = true //无限滚动
31 | itemSpace = 0 //item之间的间隙
32 | minScale = 1f
33 | maxScale = 1f
34 | maxAlpha = 1f
35 | minAlpha = 1f
36 | }
37 |
38 | itemHeight = LinearLayout.LayoutParams.WRAP_CONTENT
39 | }
40 |
41 | val pagerLayoutManager: ViewPagerLayoutManager?
42 | get() = nestedRecyclerItemConfig.itemNestedLayoutManager as? ViewPagerLayoutManager
43 |
44 | override fun onBindNestedRecyclerView(
45 | recyclerView: RecyclerView,
46 | itemHolder: DslViewHolder,
47 | itemPosition: Int,
48 | adapterItem: DslAdapterItem,
49 | payloads: List
50 | ) {
51 | super.onBindNestedRecyclerView(
52 | recyclerView, itemHolder, itemPosition, adapterItem, payloads
53 | )
54 |
55 | val drawableIndicator: DrawableIndicator? = itemHolder.v(R.id.lib_drawable_indicator)
56 |
57 | //page切换监听
58 | pagerLayoutManager?.setOnPageChangeListener(object :
59 | ViewPagerLayoutManager.OnPageChangeListener {
60 | override fun onPageScrollStateChanged(state: Int) {
61 | //L.v(state)
62 | }
63 |
64 | override fun onPageSelected(position: Int) {
65 | //L.v(position), 相当页面滑动也会通知.
66 | nestedRecyclerItemConfig._scrollPositionConfig?.adapterPosition = position
67 | drawableIndicator?.animatorToIndex(position)
68 | }
69 | })
70 |
71 | //列表
72 | recyclerView.apply {
73 | drawableIndicator?.indicatorCount = nestedRecyclerItemConfig.itemNestedAdapter.itemCount
74 |
75 | nestedRecyclerItemConfig.itemNestedAdapter.onDispatchUpdatesOnce {
76 | drawableIndicator?.indicatorCount = it.itemCount
77 | }
78 |
79 | if (nestedRecyclerItemConfig.itemKeepScrollPosition) {
80 | nestedRecyclerItemConfig._scrollPositionConfig?.run {
81 | scrollToPosition(adapterPosition)
82 | }
83 | }
84 | }
85 | }
86 | }
--------------------------------------------------------------------------------
/dslitem2/src/main/java/com/angcyo/item2/ILoopAdapterItem.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item2
2 |
3 | import com.angcyo.dsladapter.item.IDslItem
4 | import com.leochuan.AutoPlaySnapHelper
5 |
6 | /**
7 | *
8 | * Email:angcyo@126.com
9 | * @author angcyo
10 | * @date 2020/03/18
11 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
12 | */
13 | interface ILoopAdapterItem : IDslItem {
14 |
15 | /**获取轮播图循环间隔时长, 毫秒*/
16 | fun getLoopInterval(): Int = AutoPlaySnapHelper.TIME_INTERVAL
17 | }
--------------------------------------------------------------------------------
/dslitem2/src/main/java/com/angcyo/item2/widget/recycler/DrawableIndicator.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item2.widget.recycler
2 |
3 | import android.animation.ValueAnimator
4 | import android.content.Context
5 | import android.graphics.Canvas
6 | import android.graphics.drawable.Drawable
7 | import android.util.AttributeSet
8 | import android.view.View
9 | import com.angcyo.dpi
10 | import com.angcyo.item.anim
11 | import com.angcyo.item.drawHeight
12 | import com.angcyo.item.getMode
13 | import com.angcyo.item.getSize
14 | import com.angcyo.item.loadDrawable
15 | import com.angcyo.item2.R
16 | import kotlin.math.max
17 |
18 | /**
19 | * 2种Drawable切换的指示器
20 | * Email:angcyo@126.com
21 | * @author angcyo
22 | * @date 2020/03/18
23 | */
24 | class DrawableIndicator(context: Context, attributeSet: AttributeSet? = null) :
25 | View(context, attributeSet) {
26 |
27 | /**影响宽高*/
28 | var drawableSize: Int by RequestLayoutProperty(6 * dpi)
29 |
30 | /**影响宽度*/
31 | var drawableSizeFocus: Int by RequestLayoutProperty(12 * dpi)
32 |
33 | var indicatorDrawable: Drawable? = loadDrawable(R.drawable.lib_indicator_normal)
34 | var indicatorDrawableFocus: Drawable? = loadDrawable(R.drawable.lib_indicator_focus)
35 |
36 | /**指示器数量*/
37 | var indicatorCount: Int by RequestLayoutProperty(0)
38 |
39 | /**当前显示*/
40 | var indicatorIndex: Int by InvalidateProperty(0)
41 |
42 | /**间隙*/
43 | var indicatorSpace: Int by RequestLayoutProperty(4 * dpi)
44 |
45 | init {
46 | val typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.DrawableIndicator)
47 |
48 | if (typedArray.hasValue(R.styleable.DrawableIndicator_r_indicator_drawable)) {
49 | indicatorDrawable =
50 | typedArray.getDrawable(R.styleable.DrawableIndicator_r_indicator_drawable)
51 | }
52 | if (typedArray.hasValue(R.styleable.DrawableIndicator_r_indicator_drawable_focus)) {
53 | indicatorDrawableFocus =
54 | typedArray.getDrawable(R.styleable.DrawableIndicator_r_indicator_drawable_focus)
55 | }
56 |
57 | drawableSize = typedArray.getDimensionPixelOffset(
58 | R.styleable.DrawableIndicator_r_indicator_size,
59 | drawableSize
60 | )
61 | drawableSizeFocus = typedArray.getDimensionPixelOffset(
62 | R.styleable.DrawableIndicator_r_indicator_size_focus,
63 | drawableSizeFocus
64 | )
65 | indicatorSpace = typedArray.getDimensionPixelOffset(
66 | R.styleable.DrawableIndicator_r_indicator_space,
67 | indicatorSpace
68 | )
69 | typedArray.recycle()
70 |
71 | if (isInEditMode) {
72 | indicatorCount = 5
73 | indicatorIndex = 2
74 | }
75 | }
76 |
77 | override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
78 | var widthSize = widthMeasureSpec.getSize()
79 | var heightSize = heightMeasureSpec.getSize()
80 | if (widthMeasureSpec.getMode() != MeasureSpec.EXACTLY) {
81 | widthSize = paddingLeft + paddingRight +
82 | drawableSize * (indicatorCount - 1) + drawableSizeFocus +
83 | indicatorSpace * (indicatorCount - 1)
84 | }
85 | if (heightMeasureSpec.getMode() != MeasureSpec.EXACTLY) {
86 | heightSize = paddingTop + paddingBottom + max(drawableSize, drawableSizeFocus)
87 | }
88 | //super.onMeasure(widthMeasureSpec, heightMeasureSpec)
89 | setMeasuredDimension(
90 | max(widthSize, suggestedMinimumWidth),
91 | max(heightSize, suggestedMinimumHeight)
92 | )
93 | }
94 |
95 | override fun onDraw(canvas: Canvas) {
96 | super.onDraw(canvas)
97 |
98 | if (indicatorCount > 1) {
99 | //大于1个时, 才绘制
100 | var left = paddingLeft
101 | var top = paddingTop
102 | for (i in 0 until indicatorCount) {
103 | val width: Int = when {
104 | _animator?.isStarted == true && i == indicatorIndex -> (drawableSize - (drawableSize - drawableSizeFocus) * _animatorFraction).toInt()
105 | _animator?.isStarted == true && i == _animatorFromIndex -> (drawableSizeFocus - (drawableSizeFocus - drawableSize) * _animatorFraction).toInt()
106 | i == indicatorIndex -> drawableSizeFocus
107 | else -> drawableSize
108 | }
109 |
110 | val height = drawableSize
111 |
112 | top = paddingTop + (drawHeight - height) / 2
113 |
114 | val drawable = if (i == indicatorIndex) {
115 | indicatorDrawableFocus
116 | } else {
117 | indicatorDrawable
118 | }
119 | drawable?.apply {
120 | val right = left + width
121 | setBounds(left, top, right, top + height)
122 | left = right + indicatorSpace
123 | draw(canvas)
124 | }
125 | }
126 | }
127 | }
128 |
129 | var _animator: ValueAnimator? = null
130 | var _animatorFromIndex: Int = -1
131 | var _animatorFraction: Float = 1f
132 |
133 | /**使用动画的方式切换*/
134 | fun animatorToIndex(index: Int) {
135 | _animator?.cancel()
136 | _animator = null
137 |
138 | _animatorFromIndex = indicatorIndex
139 | indicatorIndex = index
140 |
141 | if (_animatorFromIndex == indicatorIndex) {
142 | return
143 | }
144 |
145 | _animator = anim(0f, 1f) {
146 | onAnimatorUpdateValue = { value, fraction ->
147 | _animatorFraction = fraction
148 | postInvalidateOnAnimation()
149 | }
150 | }
151 | }
152 | }
--------------------------------------------------------------------------------
/dslitem2/src/main/java/com/angcyo/item2/widget/recycler/InvalidateProperty.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item2.widget.recycler
2 |
3 | import android.graphics.drawable.Drawable
4 | import android.view.View
5 | import kotlin.properties.ReadWriteProperty
6 | import kotlin.reflect.KProperty
7 |
8 | /**
9 | * 属性改变时, 自动触发[android.view.View.invalidate]
10 | * @author angcyo
11 | * @since 2022/08/06
12 | */
13 | class InvalidateProperty(var value: VALUE) : ReadWriteProperty {
14 |
15 | override fun getValue(thisRef: VIEW, property: KProperty<*>): VALUE {
16 | val v = value
17 | if (v is Drawable) {
18 | if (v.callback != thisRef) {
19 | v.callback = thisRef
20 | }
21 | }
22 | return v
23 | }
24 |
25 | override fun setValue(thisRef: VIEW, property: KProperty<*>, value: VALUE) {
26 | val old = this.value
27 | this.value = value
28 | if (old != value) {
29 | thisRef.invalidate()
30 | }
31 | }
32 |
33 | }
--------------------------------------------------------------------------------
/dslitem2/src/main/java/com/angcyo/item2/widget/recycler/LoopRecyclerView.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item2.widget.recycler
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import android.view.MotionEvent
6 | import android.view.View
7 | import com.angcyo.item2.R
8 | import com.angcyo.widget.recycler.DslRecyclerView
9 | import com.leochuan.AutoPlaySnapHelper
10 |
11 | /**
12 | *
13 | * Email:angcyo@126.com
14 | * @author angcyo
15 | * @date 2020/03/18
16 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
17 | */
18 | open class LoopRecyclerView(context: Context, attributeSet: AttributeSet? = null) :
19 | DslRecyclerView(context, attributeSet) {
20 |
21 | /**是否自动开始循环滚动*/
22 | var autoStartLoop: Boolean = true
23 |
24 | /**循环滚动助手*/
25 | var loopSnapHelper: LoopSnapHelper =
26 | LoopSnapHelper(AutoPlaySnapHelper.TIME_INTERVAL, AutoPlaySnapHelper.RIGHT)
27 |
28 | /**一个一个滑动*/
29 | var snapByOne: Boolean = true
30 |
31 | val enableLoop: Boolean
32 | get() = (adapter?.itemCount ?: 0) > 1
33 |
34 | init {
35 | val typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.LoopRecyclerView)
36 | val timeInterval = typedArray.getInt(
37 | R.styleable.LoopRecyclerView_r_loop_interval,
38 | 3000
39 | )
40 | val direction =
41 | typedArray.getInt(
42 | R.styleable.LoopRecyclerView_r_loop_direction,
43 | AutoPlaySnapHelper.RIGHT
44 | )
45 | autoStartLoop =
46 | typedArray.getBoolean(R.styleable.LoopRecyclerView_r_auto_start, autoStartLoop)
47 |
48 | snapByOne = typedArray.getBoolean(R.styleable.LoopRecyclerView_r_snap_by_one, snapByOne)
49 |
50 | loopSnapHelper.loopDuration = typedArray.getInt(
51 | R.styleable.LoopRecyclerView_r_loop_duration,
52 | loopSnapHelper.loopDuration
53 | )
54 |
55 | typedArray.recycle()
56 |
57 | loopSnapHelper.setTimeInterval(timeInterval)
58 | loopSnapHelper.setDirection(direction)
59 | loopSnapHelper.snapScrollOne = snapByOne
60 | }
61 |
62 | override fun onAttachedToWindow() {
63 | super.onAttachedToWindow()
64 | _startInner()
65 | }
66 |
67 | override fun onDetachedFromWindow() {
68 | super.onDetachedFromWindow()
69 | pause()
70 | }
71 |
72 | override fun onVisibilityChanged(changedView: View, visibility: Int) {
73 | super.onVisibilityChanged(changedView, visibility)
74 | if (visibility == View.VISIBLE) {
75 | _startInner()
76 | } else {
77 | pause()
78 | }
79 | }
80 |
81 | override fun setLayoutManager(layout: LayoutManager?) {
82 | super.setLayoutManager(layout)
83 |
84 | if (!isInEditMode) {
85 | loopSnapHelper.detachFromRecyclerView()
86 | //如果在super的构造方法里面调用了setLayoutManager, 此时[loopSnapHelper]还未初始化, 就会报空指针
87 | loopSnapHelper.attachToRecyclerView(this) //会自动开启无线循环
88 | _startInner()
89 | }
90 | }
91 |
92 | override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
93 | val result = super.dispatchTouchEvent(ev)
94 | when (ev.action) {
95 | MotionEvent.ACTION_DOWN -> pause()
96 | MotionEvent.ACTION_UP -> _startInner()
97 | }
98 | return result
99 | }
100 |
101 | override fun onTouchEvent(ev: MotionEvent): Boolean {
102 | return super.onTouchEvent(ev)
103 | }
104 |
105 | override fun scrollBy(x: Int, y: Int) {
106 | super.scrollBy(x, y)
107 | }
108 |
109 | override fun scrollTo(x: Int, y: Int) {
110 | super.scrollTo(x, y)
111 | }
112 |
113 | fun _startInner() {
114 | if (autoStartLoop) {
115 | start()
116 | }
117 | }
118 |
119 | open fun start() {
120 | if (enableLoop) {
121 | //大于一个时才滚动
122 | loopSnapHelper.start()
123 | } else {
124 | pause()
125 | }
126 | }
127 |
128 | open fun pause() {
129 | loopSnapHelper.pause()
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/dslitem2/src/main/java/com/angcyo/item2/widget/recycler/LoopSnapHelper.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item2.widget.recycler
2 |
3 | import android.view.animation.DecelerateInterpolator
4 | import android.view.animation.Interpolator
5 | import androidx.recyclerview.widget.RecyclerView
6 | import com.angcyo.dsladapter.DslAdapter
7 | import com.angcyo.item2.ILoopAdapterItem
8 | import com.leochuan.AutoPlaySnapHelper
9 | import com.leochuan.ViewPagerLayoutManager
10 |
11 | /**
12 | *
13 | * Email:angcyo@126.com
14 | * @author angcyo
15 | * @date 2020/03/18
16 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
17 | */
18 | class LoopSnapHelper(val interval: Int, direction: Int) : AutoPlaySnapHelper(interval, direction) {
19 |
20 | var loopInterpolator: Interpolator? = DecelerateInterpolator()
21 |
22 | var loopDuration: Int = 1000//UNDEFINED_DURATION
23 |
24 | /**替换默认的时间间隔*/
25 | fun hookInterval() {
26 | if (mRecyclerView.adapter is DslAdapter && mRecyclerView.layoutManager is ViewPagerLayoutManager) {
27 | val layoutManager: ViewPagerLayoutManager =
28 | mRecyclerView.layoutManager as ViewPagerLayoutManager
29 |
30 | val currentPosition =
31 | layoutManager.currentPosition * if (layoutManager.reverseLayout) -1 else 1
32 |
33 | (mRecyclerView.adapter as DslAdapter).getItemData(currentPosition, true)?.apply {
34 | if (this is ILoopAdapterItem) {
35 | //替换默认的时间间隔
36 | setTimeInterval(this.getLoopInterval())
37 | }
38 | }
39 | }
40 | }
41 |
42 | /**恢复默认的时间间隔*/
43 | fun restoreInterval() {
44 | //恢复默认的时间间隔
45 | setTimeInterval(interval)
46 | }
47 |
48 | override fun onRun(layoutManager: ViewPagerLayoutManager) {
49 | if (mRecyclerView?.adapter?.itemCount ?: 0 <= 0) {
50 | return
51 | }
52 | hookInterval()
53 |
54 | val currentPosition =
55 | layoutManager.currentPositionOffset * if (layoutManager.reverseLayout) -1 else 1
56 |
57 | val targetPosition = if (direction == RIGHT) currentPosition + 1 else currentPosition - 1
58 |
59 | val delta: Int = layoutManager.getOffsetToPosition(targetPosition)
60 | if (layoutManager.orientation == RecyclerView.VERTICAL) {
61 | mRecyclerView?.smoothScrollBy(0, delta, loopInterpolator, loopDuration)
62 | } else {
63 | mRecyclerView?.smoothScrollBy(delta, 0, loopInterpolator, loopDuration)
64 | }
65 |
66 | handler.postDelayed(autoPlayRunnable, timeInterval.toLong())
67 |
68 | restoreInterval()
69 | }
70 |
71 | override fun start() {
72 | if (mRecyclerView == null) {
73 | return
74 | }
75 |
76 | if (mRecyclerView.layoutManager == null) {
77 | return
78 | }
79 |
80 | if (mRecyclerView.layoutManager !is ViewPagerLayoutManager) {
81 | return
82 | }
83 | hookInterval()
84 | super.start()
85 | restoreInterval()
86 | }
87 |
88 | fun detachFromRecyclerView() {
89 | if (mRecyclerView != null) {
90 | destroyCallbacks()
91 | }
92 | mRecyclerView = null
93 | }
94 | }
--------------------------------------------------------------------------------
/dslitem2/src/main/java/com/angcyo/item2/widget/recycler/RequestLayoutProperty.kt:
--------------------------------------------------------------------------------
1 | package com.angcyo.item2.widget.recycler
2 |
3 | import android.view.View
4 | import kotlin.properties.ReadWriteProperty
5 | import kotlin.reflect.KProperty
6 |
7 | /**
8 | *
9 | * Email:angcyo@126.com
10 | * @author angcyo
11 | * @date 2019/12/24
12 | * Copyright (c) 2019 ShenZhen O&M Cloud Co., Ltd. All rights reserved.
13 | */
14 | class RequestLayoutProperty(var value: T) : ReadWriteProperty {
15 | override fun getValue(thisRef: View, property: KProperty<*>): T = value
16 |
17 | override fun setValue(thisRef: View, property: KProperty<*>, value: T) {
18 | this.value = value
19 | thisRef.requestLayout()
20 | }
21 | }
22 |
23 | class RequestLayoutAnyProperty(var value: T, val view: View?) : ReadWriteProperty {
24 | override fun getValue(thisRef: Any, property: KProperty<*>): T = value
25 |
26 | override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
27 | this.value = value
28 | view?.requestLayout()
29 | }
30 | }
--------------------------------------------------------------------------------
/dslitem2/src/main/res/drawable/lib_indicator_focus.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/dslitem2/src/main/res/drawable/lib_indicator_normal.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/dslitem2/src/main/res/layout/dsl_banner_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
24 |
25 |
--------------------------------------------------------------------------------
/dslitem2/src/main/res/values/attr_border_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/dslitem2/src/main/res/values/attr_drawable_indicator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/dslitem2/src/main/res/values/attr_loop_recycler_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/dslitem2/src/main/res/values/item2_values.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #4D727272
4 | @color/colorAccent
5 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 | # Kotlin code style for this project: "official" or "obsolete":
21 | kotlin.code.style=official
22 | android.defaults.buildfeatures.buildconfig=true
23 | android.nonTransitiveRClass=false
24 | android.nonFinalResIds=false
25 |
26 | M_SDK=18
27 | T_SDK=33
28 | C_SDK=33
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angcyo/DslItem/92c5a7c665636c7af4c1f497c41657653ae80326/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Apr 28 14:29:15 CST 2023
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/png/item.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/angcyo/DslItem/92c5a7c665636c7af4c1f497c41657653ae80326/png/item.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name='DslItem'
2 | include ':demo'
3 | include ':dslitem'
4 | include ':dslitem2'
5 |
--------------------------------------------------------------------------------