├── .gitignore
├── .idea
├── .gitignore
├── .name
├── compiler.xml
├── gradle.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── misc.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── peakmain
│ │ └── compose
│ │ └── project
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── peakmain
│ │ │ └── compose
│ │ │ └── project
│ │ │ ├── MainActivity.kt
│ │ │ ├── bean
│ │ │ ├── home
│ │ │ │ └── BannerBean.kt
│ │ │ ├── main
│ │ │ │ └── MainBean.kt
│ │ │ └── mine
│ │ │ │ └── MineItemBean.kt
│ │ │ ├── component
│ │ │ ├── CpCell.kt
│ │ │ ├── CpColumn.kt
│ │ │ └── CpTitle.kt
│ │ │ ├── constants
│ │ │ └── PkColor.kt
│ │ │ ├── page
│ │ │ ├── basic
│ │ │ │ ├── BasicComponentActivity.kt
│ │ │ │ └── compose
│ │ │ │ │ ├── ButtonPage.kt
│ │ │ │ │ ├── CellPage.kt
│ │ │ │ │ ├── ImagePage.kt
│ │ │ │ │ ├── NavBarPage.kt
│ │ │ │ │ └── TitlePage.kt
│ │ │ ├── display
│ │ │ │ ├── DisplayComponentActivity.kt
│ │ │ │ └── compose
│ │ │ │ │ ├── BannerPage.kt
│ │ │ │ │ ├── DividerPage.kt
│ │ │ │ │ ├── FlowRowPage.kt
│ │ │ │ │ ├── GridPage.kt
│ │ │ │ │ ├── HighlightTextPage.kt
│ │ │ │ │ └── StaggeredVerticalGridPage.kt
│ │ │ ├── expand
│ │ │ │ ├── ExpandActivity.kt
│ │ │ │ └── component
│ │ │ │ │ └── ListExtPage.kt
│ │ │ └── tools
│ │ │ │ ├── ToolsActivity.kt
│ │ │ │ └── component
│ │ │ │ └── ImagePainterUtilsPage.kt
│ │ │ ├── ui
│ │ │ ├── theme
│ │ │ │ ├── Color.kt
│ │ │ │ ├── Shape.kt
│ │ │ │ ├── Theme.kt
│ │ │ │ └── Type.kt
│ │ │ └── view
│ │ │ │ ├── MainFrame.kt
│ │ │ │ └── main
│ │ │ │ ├── BasicFragment.kt
│ │ │ │ ├── DisplayFragment.kt
│ │ │ │ ├── ExpandFragment.kt
│ │ │ │ └── ToolsFragment.kt
│ │ │ └── viewmodel
│ │ │ ├── home
│ │ │ └── HomeFragmentViewModel.kt
│ │ │ └── mine
│ │ │ └── MineFragmentViewModel.kt
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable
│ │ ├── background_laundry_delivery.xml
│ │ ├── ic_expend_arrow_down.xml
│ │ ├── ic_expend_arrow_up.xml
│ │ ├── ic_launcher_background.xml
│ │ ├── ic_menu.xml
│ │ ├── ic_online_check_out_disable.xml
│ │ └── portrair.JPG
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.webp
│ │ └── ic_launcher_round.webp
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── themes.xml
│ └── test
│ └── java
│ └── com
│ └── peakmain
│ └── compose
│ └── project
│ └── ExampleUnitTest.kt
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── library
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── peakmain
│ │ └── compose
│ │ └── library
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── peakmain
│ │ │ └── compose
│ │ │ ├── basic
│ │ │ ├── BasicColor.kt
│ │ │ ├── BasicFont.kt
│ │ │ ├── BasicRadius.kt
│ │ │ ├── BasicSize.kt
│ │ │ └── BasicSpace.kt
│ │ │ ├── ext
│ │ │ ├── IntExt.kt
│ │ │ ├── ListExt.kt
│ │ │ └── StringExt.kt
│ │ │ ├── library
│ │ │ └── TopAppBar.kt
│ │ │ ├── space
│ │ │ └── PkSpacer.kt
│ │ │ ├── theme
│ │ │ ├── PkColors.kt
│ │ │ ├── PkIndication.kt
│ │ │ ├── PkTheme.kt
│ │ │ └── PkTranslateIndication.kt
│ │ │ ├── ui
│ │ │ ├── PkGridLayout.kt
│ │ │ ├── banner
│ │ │ │ └── PkBanner.kt
│ │ │ ├── basic
│ │ │ │ └── PkColumn.kt
│ │ │ ├── button
│ │ │ │ ├── PkButton.kt
│ │ │ │ ├── PkButtonDefault.kt
│ │ │ │ └── PkShapes.kt
│ │ │ ├── cell
│ │ │ │ └── PkCell.kt
│ │ │ ├── divier
│ │ │ │ ├── PkDashDivider.kt
│ │ │ │ ├── PkDivider.kt
│ │ │ │ └── PkFullDivider.kt
│ │ │ ├── flow
│ │ │ │ └── PkFlowRow.kt
│ │ │ ├── grid
│ │ │ │ └── PkStaggeredVerticalGrid.kt
│ │ │ ├── image
│ │ │ │ └── PkImageView.kt
│ │ │ ├── progress
│ │ │ │ └── RoundedLinearProgressIndicator.kt
│ │ │ ├── text
│ │ │ │ └── PkHighlightText.kt
│ │ │ └── title
│ │ │ │ ├── PkNavBar.kt
│ │ │ │ └── PkTitle.kt
│ │ │ └── utils
│ │ │ └── ImagePainterUtils.kt
│ └── res
│ │ └── drawable
│ │ ├── compose_icon_retrun.xml
│ │ ├── ic_right_arrow.xml
│ │ └── icon_loading.xml
│ └── test
│ └── java
│ └── com
│ └── peakmain
│ └── compose
│ └── library
│ └── ExampleUnitTest.kt
└── 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 | local.properties
16 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | ComposeUI
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
20 |
21 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.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 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # composeProject
2 |
3 | > **常用Compose UI封装——提高Android Compose UI开发**
4 |
5 | **使用文档链接:** https://www.yuque.com/peakmain/alaof0/fis43sflpl602m18
6 |
7 | **How To**
8 |
9 | - Step 1. Add the JitPack repository to your build file
10 | - gradle
11 |
12 | ```groovy
13 | dependencyResolutionManagement {
14 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
15 | repositories {
16 | mavenCentral()
17 | maven { url 'https://jitpack.io' }
18 | }
19 | }
20 | ```
21 | - gradle.kts
22 | ```kotlin
23 | dependencyResolutionManagement {
24 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
25 | repositories {
26 | mavenCentral()
27 | maven { url = uri("https://jitpack.io") }
28 | }
29 | }
30 | ```
31 | - Step 2. Add the dependency
32 | ```groovy
33 | dependencies {
34 | implementation("com.github.Peakmain:ComposeUI:+")
35 | }
36 | ```
37 | #### 关于我
38 |
39 | - 简书: https://www.jianshu.com/u/3ff32f5aea98
40 | - 我的GitHub地址:https://github.com/Peakmain
41 |
42 | #### Donations
43 |
44 | 如果您觉得我的开源库帮您节省了大量的开发时间,请扫描下方的二维码随意打赏,您的支持将激励我不断前进
45 | 
46 | 
47 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.application'
3 | id 'kotlin-android'
4 | }
5 |
6 | android {
7 | compileSdk 34
8 |
9 | defaultConfig {
10 | applicationId "com.peakmain.compose.project"
11 | minSdk 21
12 | targetSdk 31
13 | versionCode 1
14 | versionName "1.0"
15 |
16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
17 | vectorDrawables {
18 | useSupportLibrary true
19 | }
20 | }
21 |
22 | buildTypes {
23 | release {
24 | minifyEnabled false
25 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
26 | }
27 | }
28 | compileOptions {
29 | sourceCompatibility JavaVersion.VERSION_1_8
30 | targetCompatibility JavaVersion.VERSION_1_8
31 | }
32 | kotlinOptions {
33 | jvmTarget = '1.8'
34 | }
35 | buildFeatures {
36 | compose true
37 | }
38 | composeOptions {
39 | kotlinCompilerExtensionVersion = "1.5.4"
40 | }
41 | packagingOptions {
42 | resources {
43 | excludes += '/META-INF/{AL2.0,LGPL2.1}'
44 | }
45 | }
46 | namespace 'com.peakmain.compose.project'
47 | }
48 |
49 | dependencies {
50 | implementation project(path: ':library')
51 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
52 | implementation 'androidx.activity:activity-ktx:1.0.0'
53 | implementation 'androidx.activity:activity-compose:1.0.0'
54 |
55 | def lifecycle_version = "2.4.1"
56 |
57 | implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
58 | implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
59 |
60 |
61 | testImplementation 'junit:junit:4.13.2'
62 | androidTestImplementation 'androidx.test.ext:junit:1.1.2'
63 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
64 | }
--------------------------------------------------------------------------------
/app/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
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/peakmain/compose/project/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project
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.peakmain.compose.project", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
15 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project
2 |
3 | import android.os.Bundle
4 | import androidx.activity.ComponentActivity
5 | import androidx.activity.compose.setContent
6 | import androidx.compose.foundation.layout.BoxWithConstraints
7 | import androidx.compose.material.Divider
8 | import androidx.compose.material.MaterialTheme
9 | import androidx.compose.material.Surface
10 | import androidx.compose.material.Text
11 | import androidx.compose.runtime.Composable
12 | import androidx.compose.ui.tooling.preview.Preview
13 | import androidx.core.view.WindowCompat
14 | import com.peakmain.compose.project.ui.theme.ComposeProjectTheme
15 | import com.peakmain.compose.project.ui.view.MainFrame
16 |
17 | class MainActivity : ComponentActivity() {
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 | //设置沉浸式状态栏
21 | WindowCompat.setDecorFitsSystemWindows(window, false)
22 | setContent {
23 | ComposeProjectTheme {
24 | // A surface container using the 'background' color from the theme
25 | Surface(color = MaterialTheme.colors.background) {
26 | MainFrame()
27 | }
28 | }
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/bean/home/BannerBean.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.bean.home
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2022/5/5
6 | * mail:2726449200@qq.com
7 | * describe:轮播图
8 | */
9 | data class BannerBean(val imagePath:String,val desc:String)
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/bean/main/MainBean.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.bean.main
2 |
3 | import androidx.compose.ui.graphics.vector.ImageVector
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2022/5/2
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | data class NavigationItem(val title:String,val icon:ImageVector)
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/bean/mine/MineItemBean.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.bean.mine
2 |
3 | import androidx.compose.ui.graphics.vector.ImageVector
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2022/5/7
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | data class MineItemBean(val title: String, val icon: ImageVector)
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/component/CpCell.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.component
2 |
3 | import android.content.Context
4 | import android.content.Intent
5 | import androidx.compose.foundation.clickable
6 | import androidx.compose.runtime.Composable
7 | import androidx.compose.ui.Modifier
8 | import androidx.compose.ui.platform.LocalContext
9 | import com.peakmain.compose.project.page.display.DisplayComponentActivity
10 | import com.peakmain.compose.ui.cell.PkCell
11 | import com.peakmain.compose.ui.title.PkTitleType
12 |
13 | /**
14 | * author :Peakmain
15 | * createTime:2025/6/27
16 | * mail:2726449200@qq.com
17 | * describe:
18 | */
19 | @Composable
20 | fun CpCell(title:String,intent:Intent,type:Int) {
21 | val context = LocalContext.current
22 | PkCell(text = title, modifier = Modifier.clickable {
23 | intent.putExtra("type",type)
24 | context.startActivity(intent)
25 | }, type = PkTitleType.TitleBold1())
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/component/CpColumn.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.component
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Column
5 | import androidx.compose.foundation.layout.ColumnScope
6 | import androidx.compose.foundation.layout.fillMaxSize
7 | import androidx.compose.runtime.Composable
8 | import androidx.compose.ui.Modifier
9 | import com.peakmain.compose.project.constants.PkColor
10 | import com.peakmain.compose.ui.title.PkNavBar
11 |
12 | /**
13 | * author :Peakmain
14 | * createTime:2025/6/27
15 | * mail:2726449200@qq.com
16 | * describe:
17 | */
18 | @Composable
19 | fun CpColumn(title:String, content: @Composable ColumnScope.() -> Unit) {
20 | Column(
21 | modifier = Modifier
22 | .background(PkColor.color_fill1)
23 | .fillMaxSize()
24 | ) {
25 | PkNavBar(title)
26 | content()
27 | }
28 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/component/CpTitle.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.component
2 |
3 | import androidx.compose.foundation.layout.padding
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.ui.Modifier
6 | import androidx.compose.ui.unit.dp
7 | import com.peakmain.compose.ui.title.PkTitle
8 | import com.peakmain.compose.ui.title.PkTitleType
9 |
10 | /**
11 | * author :Peakmain
12 | * createTime:2025/6/27
13 | * mail:2726449200@qq.com
14 | * describe:
15 | */
16 | @Composable
17 | fun CpTitle(title:String) {
18 | PkTitle(title, type = PkTitleType.TextBold1(), modifier = Modifier.padding(18.dp))
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/constants/PkColor.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.constants
2 |
3 | import com.peakmain.compose.basic.BasicColor
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2025/6/26
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | object PkColor {
12 | /**
13 | * 主色
14 | */
15 | val green1 = BasicColor.color_1F401B
16 | val green2 = BasicColor.color_677C64
17 | val green3_15 = BasicColor.color_1F401B_15
18 |
19 | /**
20 | * 辅色
21 | */
22 | val brown1 = BasicColor.color_B59E6D
23 | val brown2 = BasicColor.color_DDCC9E
24 |
25 | /**
26 | * 中性色
27 | */
28 | val grey1 = BasicColor.color_333333
29 | val grey2 = BasicColor.color_666666
30 | val grey3 = BasicColor.color_9D9C96
31 | val grey4 = BasicColor.color_D4D4D5
32 | val grey5 = BasicColor.color_EBEBF0
33 | val grey6_10 = BasicColor.color_9D9C96_10
34 | val grey7 = BasicColor.color_F8F9F3
35 | val grey8 = BasicColor.color_FFFEFA
36 |
37 | /**
38 | * 功能色
39 | */
40 | val orange1=BasicColor.color_B9824C
41 | val red1=BasicColor.color_A5534D
42 | val color_67696a=BasicColor.color_67696a
43 |
44 | /**
45 | * 品牌色
46 | */
47 | val color_brand1=BasicColor.color_1F401B
48 | val color_brand2=BasicColor.color_677C64
49 | val color_brand3=BasicColor.color_B59E6D
50 | val color_brand4=BasicColor.color_DDCC9E
51 | val color_fill1=BasicColor.color_F8F9F3
52 | val color_fill2=BasicColor.color_FFFEFA
53 | val color_fill3_10=BasicColor.color_9D9C96_10
54 | val color_fill4_15=BasicColor.color_1F401B_15
55 |
56 |
57 | /**
58 | * 文本色
59 | */
60 | val color_text1=BasicColor.color_333333
61 | val color_text2=BasicColor.color_666666
62 | val color_text3=BasicColor.color_9D9C96
63 | val color_text4=BasicColor.color_D4D4D5
64 | val color_text5=BasicColor.color_FFFEFA
65 | val color_text6=BasicColor.color_1F401B
66 | val color_text7=BasicColor.color_126E82
67 | val color_272A2B=BasicColor.color_272A2B
68 | val color_line1=BasicColor.color_D4D4D5
69 | val color_line2=BasicColor.color_EBEBF0
70 |
71 | val color_price1=BasicColor.color_B9824C
72 |
73 |
74 | /**
75 | * 背景色
76 | */
77 | val color_background1=BasicColor.color_ECECE0B3
78 | val color_background2=BasicColor.color_FFF3F3F3
79 | val color_background3=BasicColor.color_FF000000
80 |
81 | val color_notice1=BasicColor.color_A5534D
82 | val color_launch=BasicColor.color_F2F3EC
83 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/page/basic/BasicComponentActivity.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.page.basic
2 |
3 | import android.os.Bundle
4 | import androidx.activity.ComponentActivity
5 | import androidx.activity.compose.setContent
6 | import com.peakmain.compose.project.page.basic.compose.ButtonPage
7 | import com.peakmain.compose.project.page.basic.compose.CellPage
8 | import com.peakmain.compose.project.page.basic.compose.ImagePage
9 | import com.peakmain.compose.project.page.basic.compose.NavBarPage
10 | import com.peakmain.compose.project.page.basic.compose.TitlePage
11 |
12 | /**
13 | * author :Peakmain
14 | * createTime:2025/6/26
15 | * mail:2726449200@qq.com
16 | * describe:基础组件
17 | */
18 | class BasicComponentActivity : ComponentActivity() {
19 | val type by lazy {
20 | intent.getIntExtra("type", 0)
21 | }
22 |
23 | override fun onCreate(savedInstanceState: Bundle?) {
24 | super.onCreate(savedInstanceState)
25 | setContent {
26 | when (type) {
27 | 1 -> {
28 | //标题组件
29 | TitlePage()
30 | }
31 |
32 | 2 -> {
33 | //导航栏组件
34 | NavBarPage()
35 | }
36 |
37 | 3 -> {
38 | //单元格组件
39 | CellPage()
40 | }
41 |
42 | 4 -> {
43 | //按钮组件
44 | ButtonPage()
45 | }
46 |
47 | 5 -> {
48 | //图片组件
49 | ImagePage()
50 | }
51 | }
52 | }
53 | }
54 |
55 |
56 | }
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/page/basic/compose/ButtonPage.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.page.basic.compose
2 |
3 | import androidx.compose.foundation.BorderStroke
4 | import androidx.compose.foundation.layout.Arrangement
5 | import androidx.compose.foundation.layout.Column
6 | import androidx.compose.foundation.layout.Row
7 | import androidx.compose.foundation.layout.padding
8 | import androidx.compose.material.Text
9 | import androidx.compose.runtime.Composable
10 | import androidx.compose.ui.Modifier
11 | import androidx.compose.ui.graphics.Color
12 | import androidx.compose.ui.text.font.FontWeight
13 | import androidx.compose.ui.unit.dp
14 | import com.peakmain.compose.basic.BasicFont
15 | import com.peakmain.compose.theme.PkTheme
16 | import com.peakmain.compose.ui.button.PkButton
17 | import com.peakmain.compose.ui.button.PkButtonDefault
18 | import com.peakmain.compose.ui.title.PkNavBar
19 |
20 | /**
21 | * author :Peakmain
22 | * createTime:2025/6/26
23 | * mail:2726449200@qq.com
24 | * describe:
25 | */
26 | /**
27 | * 按钮组件
28 | */
29 | @Composable
30 | fun ButtonPage() {
31 | Column {
32 | PkNavBar("按钮组件")
33 | Row(
34 | horizontalArrangement = Arrangement.spacedBy(10.dp),
35 | modifier = Modifier.padding(top = 20.dp, start = 20.dp)
36 | ) {
37 | PkButton(
38 | onClick = {
39 |
40 | }, elevation = null,
41 | colors = PkButtonDefault.transparentColor(),
42 | shape = PkTheme.shapes.medium,
43 | border = BorderStroke(0.5.dp, Color(0xFFD4D4D5))
44 | ) {
45 | Text(
46 | "继续挑战", fontWeight = FontWeight.W500,
47 | fontSize = BasicFont.font_12
48 | )
49 | }
50 | PkButton(
51 | onClick = {
52 |
53 | },
54 | elevation = null,
55 | colors = PkButtonDefault.buttonColors(),
56 | shape = PkTheme.shapes.medium,
57 | ) {
58 | Text(
59 | "领取任务", fontWeight = FontWeight.W500,
60 | fontSize = BasicFont.font_12
61 | )
62 | }
63 | }
64 | }
65 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/page/basic/compose/CellPage.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.page.basic.compose
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Arrangement
5 | import androidx.compose.foundation.layout.Column
6 | import androidx.compose.foundation.layout.Spacer
7 | import androidx.compose.foundation.layout.padding
8 | import androidx.compose.foundation.layout.width
9 | import androidx.compose.material.Icon
10 | import androidx.compose.material.Switch
11 | import androidx.compose.material.Text
12 | import androidx.compose.material.icons.Icons
13 | import androidx.compose.material.icons.filled.ArrowForward
14 | import androidx.compose.runtime.Composable
15 | import androidx.compose.ui.Modifier
16 | import androidx.compose.ui.graphics.Color
17 | import androidx.compose.ui.unit.dp
18 | import com.peakmain.compose.project.constants.PkColor
19 | import com.peakmain.compose.ui.cell.PkCell
20 | import com.peakmain.compose.ui.title.PkNavBar
21 | import com.peakmain.compose.ui.title.PkTitleType
22 |
23 | /**
24 | * author :Peakmain
25 | * createTime:2025/6/26
26 | * mail:2726449200@qq.com
27 | * describe:
28 | */
29 | @Composable
30 | fun CellPage() {
31 | Column(
32 | verticalArrangement = Arrangement.spacedBy(10.dp),
33 | modifier = Modifier.background(PkColor.color_fill2)
34 | ) {
35 | PkNavBar("单元格组件")
36 | PkCell(
37 | "常用功能",
38 | PkTitleType.BigTitle3(),
39 | rightText = "展开",
40 | modifier = Modifier
41 | .padding(horizontal = 18.dp),
42 | color = Color(0xFF14401B)
43 | )
44 | // 基础用法(右侧带箭头图标)
45 | PkCell(
46 | text = "个人资料",
47 | type = PkTitleType.TitleBold1(),
48 | modifier = Modifier.padding(16.dp),
49 | rightContent = {
50 | Icon(
51 | imageVector = Icons.Default.ArrowForward,
52 | contentDescription = "进入",
53 | tint = Color.Gray
54 | )
55 | }
56 | )
57 |
58 | // 复杂右侧内容(文字 + 开关)
59 | PkCell(
60 | text = "夜间模式",
61 | color = Color.Black,
62 | rightContent = {
63 | Text("已开启", color = Color.Gray)
64 | Spacer(Modifier.width(8.dp))
65 | Switch(
66 | checked = true,
67 | onCheckedChange = { /* 状态更新逻辑 */ }
68 | )
69 | }
70 | )
71 | }
72 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/page/basic/compose/ImagePage.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.page.basic.compose
2 |
3 | import androidx.compose.foundation.layout.Arrangement
4 | import androidx.compose.foundation.layout.Column
5 | import androidx.compose.foundation.layout.size
6 | import androidx.compose.runtime.Composable
7 | import androidx.compose.ui.Modifier
8 | import androidx.compose.ui.graphics.Color
9 | import androidx.compose.ui.res.painterResource
10 | import androidx.compose.ui.unit.dp
11 | import com.peakmain.compose.project.R
12 | import com.peakmain.compose.ui.image.PkImageView
13 | import com.peakmain.compose.ui.title.PkNavBar
14 | import com.peakmain.compose.ui.title.PkTitle
15 | import com.peakmain.compose.ui.title.PkTitleType
16 | import com.peakmain.compose.utils.ImagePainterUtils
17 |
18 | /**
19 | * author :Peakmain
20 | * createTime:2025/6/26
21 | * mail:2726449200@qq.com
22 | * describe:
23 | */
24 | @Composable
25 | fun ImagePage() {
26 | val imageUrl="https://coil-kt.github.io/coil/images/coil_logo_black.svg"
27 | Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
28 | PkNavBar("图片组件")
29 | Column {
30 | PkTitle("加载本地图片", type = PkTitleType.BigTitle3())
31 | PkImageView(painter = painterResource(R.drawable.portrair), modifier = Modifier.size(80.dp))
32 | }
33 | Column {
34 | PkTitle("加载网络图片", type = PkTitleType.BigTitle3())
35 | PkImageView(painter = ImagePainterUtils.getPainter(imageUrl), modifier = Modifier.size(80.dp))
36 | }
37 | Column {
38 | PkTitle("加载网络图片,并修改颜色为红色", type = PkTitleType.BigTitle3())
39 | PkImageView(painter = ImagePainterUtils.getPainter(imageUrl), tintColor = Color.Red,modifier = Modifier.size(80.dp))
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/page/basic/compose/NavBarPage.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.page.basic.compose
2 |
3 | import android.widget.Toast
4 | import androidx.compose.foundation.layout.Arrangement
5 | import androidx.compose.foundation.layout.Column
6 | import androidx.compose.runtime.Composable
7 | import androidx.compose.ui.platform.LocalContext
8 | import androidx.compose.ui.unit.dp
9 | import com.peakmain.compose.project.R
10 | import com.peakmain.compose.ui.divier.PkDivider
11 | import com.peakmain.compose.ui.title.PkNavBar
12 |
13 | /**
14 | * author :Peakmain
15 | * createTime:2025/6/26
16 | * mail:2726449200@qq.com
17 | * describe:
18 | */
19 | /**
20 | * 导航栏组件
21 | */
22 | @Composable
23 | fun NavBarPage() {
24 | val context = LocalContext.current
25 | Column() {
26 | PkNavBar("NavBar组件")
27 | PkDivider(isHorizontal = true)
28 | Column(verticalArrangement = Arrangement.spacedBy(10.dp)) {
29 | PkNavBar("默认NavBar导航栏")
30 | PkNavBar("我是长文本的NavBar导航栏,超长的,但是不显示右边按钮")
31 | PkNavBar(
32 | "我是长文本的NavBar导航栏,超长的,显示右边按钮",
33 | rightResource = R.drawable.ic_menu
34 | )
35 | PkNavBar("自定义返回事件", onBackClick = {
36 | Toast.makeText(context, "自定义返回事件", Toast.LENGTH_LONG).show()
37 | })
38 | }
39 |
40 | }
41 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/page/basic/compose/TitlePage.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.page.basic.compose
2 |
3 | import androidx.compose.foundation.layout.Arrangement
4 | import androidx.compose.foundation.layout.Column
5 | import androidx.compose.foundation.layout.padding
6 | import androidx.compose.runtime.Composable
7 | import androidx.compose.ui.Alignment
8 | import androidx.compose.ui.Modifier
9 | import androidx.compose.ui.unit.dp
10 | import com.peakmain.compose.ui.divier.PkDivider
11 | import com.peakmain.compose.ui.title.PkNavBar
12 | import com.peakmain.compose.ui.title.PkTitle
13 | import com.peakmain.compose.ui.title.PkTitleType
14 |
15 | /**
16 | * author :Peakmain
17 | * createTime:2025/6/26
18 | * mail:2726449200@qq.com
19 | * describe:
20 | */
21 | /**
22 | * 标题组件
23 | */
24 | @Composable
25 | fun TitlePage() {
26 | Column(
27 | verticalArrangement = Arrangement.spacedBy(8.dp),
28 | horizontalAlignment = Alignment.CenterHorizontally
29 | ) {
30 | PkNavBar("标题组件")
31 | PkTitle("大标题1", PkTitleType.BigTitle1())
32 | PkTitle("大标题2", PkTitleType.BigTitle2())
33 | PkTitle("大标题3", PkTitleType.BigTitle3())
34 | PkDivider(modifier = Modifier.padding(vertical = 10.dp), isHorizontal = true)
35 | PkTitle("标题1加粗", PkTitleType.TitleBold1())
36 | PkTitle("标题1常规", PkTitleType.TitleNormal1())
37 | PkTitle("标题2加粗", PkTitleType.TitleBold2())
38 | PkTitle("标题2常规", PkTitleType.TitleNormal2())
39 | PkDivider(modifier = Modifier.padding(vertical = 10.dp), isHorizontal = true)
40 | PkTitle("小标题加粗", PkTitleType.SmallTitleBold())
41 | PkTitle("小标题常规", PkTitleType.SmallTitleNormal())
42 | PkDivider(modifier = Modifier.padding(vertical = 10.dp), isHorizontal = true)
43 | PkTitle("内文1加粗", PkTitleType.TextBold1())
44 | PkTitle("内文1正常", PkTitleType.TextNormal1())
45 | PkTitle("内文2加粗", PkTitleType.TextBold2())
46 | PkTitle("内文2正常", PkTitleType.TextNormal2())
47 | }
48 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/page/display/DisplayComponentActivity.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.page.display
2 |
3 | import android.os.Bundle
4 | import androidx.activity.ComponentActivity
5 | import androidx.activity.compose.setContent
6 | import androidx.compose.runtime.Composable
7 | import androidx.compose.runtime.staticCompositionLocalOf
8 | import androidx.compose.ui.Modifier
9 | import com.peakmain.compose.project.page.display.compose.BannerPage
10 | import com.peakmain.compose.project.page.display.compose.DividerPage
11 | import com.peakmain.compose.project.page.display.compose.FlowRowPage
12 | import com.peakmain.compose.project.page.display.compose.GridPage
13 | import com.peakmain.compose.project.page.display.compose.HighlightTextPage
14 | import com.peakmain.compose.project.page.display.compose.StaggeredVerticalGridPage
15 | import com.peakmain.compose.ui.grid.PkStaggeredVerticalGrid
16 |
17 | /**
18 | * author :Peakmain
19 | * createTime:2025/6/26
20 | * mail:2726449200@qq.com
21 | * describe:展示组件
22 | */
23 | class DisplayComponentActivity:ComponentActivity() {
24 | val type by lazy {
25 | intent.getIntExtra("type",0)
26 | }
27 | override fun onCreate(savedInstanceState: Bundle?) {
28 | super.onCreate(savedInstanceState)
29 | setContent {
30 | when(type){
31 | 1->{
32 | //网格布局
33 | GridPage()
34 | }
35 | 2->{
36 | //分割线
37 | DividerPage()
38 | }
39 | 3->{
40 | //流式布局
41 | FlowRowPage()
42 | }
43 | 4->{
44 | //轮播图
45 | BannerPage()
46 | }
47 |
48 | 5->{
49 | //高亮文本
50 | HighlightTextPage()
51 | }
52 | 6->{
53 | //瀑布流组件
54 | StaggeredVerticalGridPage()
55 | }
56 | }
57 | }
58 | }
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/page/display/compose/BannerPage.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.page.display.compose
2 |
3 | import android.util.Log
4 | import androidx.compose.foundation.Image
5 | import androidx.compose.foundation.background
6 | import androidx.compose.foundation.layout.Box
7 | import androidx.compose.foundation.layout.Column
8 | import androidx.compose.foundation.layout.Row
9 | import androidx.compose.foundation.layout.Spacer
10 | import androidx.compose.foundation.layout.fillMaxHeight
11 | import androidx.compose.foundation.layout.fillMaxSize
12 | import androidx.compose.foundation.layout.fillMaxWidth
13 | import androidx.compose.foundation.layout.height
14 | import androidx.compose.foundation.layout.padding
15 | import androidx.compose.foundation.layout.size
16 | import androidx.compose.foundation.layout.width
17 | import androidx.compose.foundation.layout.wrapContentHeight
18 | import androidx.compose.foundation.layout.wrapContentWidth
19 | import androidx.compose.foundation.shape.CircleShape
20 | import androidx.compose.foundation.shape.RoundedCornerShape
21 | import androidx.compose.material.Text
22 | import androidx.compose.runtime.Composable
23 | import androidx.compose.ui.Alignment
24 | import androidx.compose.ui.Modifier
25 | import androidx.compose.ui.draw.clip
26 | import androidx.compose.ui.graphics.Color
27 | import androidx.compose.ui.layout.ContentScale
28 | import androidx.compose.ui.res.colorResource
29 | import androidx.compose.ui.res.dimensionResource
30 | import androidx.compose.ui.res.painterResource
31 | import androidx.compose.ui.text.style.TextOverflow
32 | import androidx.compose.ui.unit.dp
33 | import androidx.compose.ui.unit.sp
34 | import com.peakmain.compose.basic.BasicColor
35 | import com.peakmain.compose.basic.BasicFont
36 | import com.peakmain.compose.basic.BasicRadius
37 | import com.peakmain.compose.basic.BasicSize
38 | import com.peakmain.compose.basic.BasicSpace
39 | import com.peakmain.compose.library.TopAppBarCenter
40 | import com.peakmain.compose.project.R
41 | import com.peakmain.compose.project.component.CpColumn
42 | import com.peakmain.compose.project.constants.PkColor
43 | import com.peakmain.compose.space.PkSpacer
44 | import com.peakmain.compose.ui.banner.PkBanner
45 | import com.peakmain.compose.ui.image.PkImageView
46 | import com.peakmain.compose.ui.progress.RoundedLinearProgressIndicator
47 | import com.peakmain.compose.ui.title.PkNavBar
48 | import com.peakmain.compose.ui.title.PkTitle
49 | import com.peakmain.compose.ui.title.PkTitleType
50 | import com.peakmain.compose.utils.ImagePainterUtils
51 |
52 | /**
53 | * author :Peakmain
54 | * createTime:2025/6/27
55 | * mail:2726449200@qq.com
56 | * describe:轮播图
57 | */
58 | @Composable
59 | fun BannerPage() {
60 | val lists = ArrayList().apply {
61 | add("https://img2.baidu.com/it/u=292395973,2170347184&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800")
62 | add("https://img0.baidu.com/it/u=3492687357,1203050466&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500")
63 | add("https://img2.baidu.com/it/u=2843793126,682473204&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800")
64 | add("https://img1.baidu.com/it/u=3907217777,761642486&fm=253&fmt=auto&app=120&f=JPEG?w=1280&h=800")
65 | add("https://img1.baidu.com/it/u=1082651511,4058105193&fm=253&fmt=auto&app=120&f=JPEG?w=1422&h=800")
66 | }
67 | val vLists = arrayListOf("广告", "我是垂直轮播", "生活好滋味,就要上四休三")
68 | CpColumn("轮播图组件") {
69 | PkTitle("默认水平轮播", type = PkTitleType.TextBold1(), modifier = Modifier.padding(18.dp))
70 | PkBanner(
71 | lists,
72 | isAutoPlay = true,
73 | initialPage = 3,
74 | onBannerClick = { index, item ->
75 | Log.e("TAG", "获取到点击后的数据:${item}")
76 | }) { index, item ->
77 | Image(
78 | painter = ImagePainterUtils.getPainter(item),
79 | contentDescription = null,
80 | modifier = Modifier
81 | .clip(RoundedCornerShape(8.dp))
82 | .fillMaxSize(),
83 | contentScale = ContentScale.Crop,
84 | alignment = Alignment.TopCenter
85 | )
86 | }
87 | PkTitle("垂直轮播", type = PkTitleType.TextBold1(), modifier = Modifier.padding(18.dp))
88 | PkBanner(
89 | vLists,
90 | isAutoPlay = true,
91 | isVertical = true
92 | ) { index, item ->
93 | Box() {
94 | Column(
95 | modifier = Modifier
96 | .clip(RoundedCornerShape(BasicRadius.radius_8))
97 | .background(PkColor.color_fill2)
98 | .padding(bottom = BasicSpace.space_16)
99 | .fillMaxHeight(),
100 | ) {
101 | Box() {
102 | Column {
103 | Row(
104 | modifier = Modifier
105 | .padding(
106 | top = BasicSpace.space_16,
107 | start = BasicSpace.space_12,
108 | end = BasicSpace.space_12
109 | ),
110 | ) {
111 | // 左侧 圆形背景 + 图标
112 | Box(
113 | modifier = Modifier
114 | .size(BasicSize.size_40)
115 | .clip(CircleShape)
116 | .background(PkColor.color_fill1),
117 | contentAlignment = Alignment.Center
118 | ) {
119 | PkImageView(
120 | painter = painterResource(
121 | id = R.drawable.ic_online_check_out_disable
122 | ),
123 | modifier = Modifier.size(BasicSize.size_24),
124 | )
125 | }
126 |
127 | Spacer(modifier = Modifier.width(BasicSpace.space_8))
128 |
129 | // 中间 内容
130 | Column(
131 | modifier = Modifier.weight(1f)
132 | ) {
133 | Text(
134 | text = "已入住",
135 | color = PkColor.color_text1,
136 | fontSize = BasicFont.font_14,
137 | )
138 | Spacer(modifier = Modifier.height(BasicSize.size_2))
139 | Text(
140 | text = "2025年06月27日" + " | " + "金会员",
141 | color = PkColor.color_text2,
142 | fontSize = BasicFont.font_11,
143 | maxLines = 1,
144 | overflow = TextOverflow.Ellipsis
145 | )
146 | }
147 |
148 | }
149 | // 底部进度条
150 | RoundedLinearProgressIndicator(
151 | progress = 0.5f,
152 | modifier = Modifier
153 | .padding(top = BasicSize.size_12)
154 | .fillMaxWidth()
155 | .height(BasicSize.size_4)
156 | .padding(horizontal = BasicSpace.space_16),
157 | color = PkColor.color_brand1,
158 | cornerRadius = BasicRadius.radius_2
159 | )
160 | PkSpacer(height = BasicSize.size_16)
161 | }
162 | //洗衣取送
163 | Box(
164 | contentAlignment = Alignment.Center,
165 | modifier = Modifier
166 | .padding(end = BasicSpace.space_8)
167 | .align(Alignment.TopEnd)
168 | ) {
169 | Image(
170 | painter = painterResource(id = R.drawable.background_laundry_delivery),
171 | contentDescription = null,
172 | contentScale = ContentScale.FillBounds,
173 | modifier = Modifier
174 | .wrapContentWidth()
175 | .wrapContentHeight()
176 | )
177 | androidx.compose.material3.Text(
178 | text = "垂直轮播",
179 | color = PkColor.color_text5,
180 | fontSize = BasicFont.font_11,
181 | modifier = Modifier
182 | .padding(
183 | horizontal = BasicSpace.space_7,
184 | vertical = BasicSpace.space_4
185 | )
186 | )
187 |
188 |
189 | }
190 |
191 | }
192 | }
193 | }
194 | }
195 | }
196 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/page/display/compose/DividerPage.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.page.display.compose
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Arrangement
5 | import androidx.compose.foundation.layout.Column
6 | import androidx.compose.foundation.layout.fillMaxHeight
7 | import androidx.compose.foundation.layout.padding
8 | import androidx.compose.runtime.Composable
9 | import androidx.compose.ui.Alignment
10 | import androidx.compose.ui.Modifier
11 | import androidx.compose.ui.unit.dp
12 | import com.peakmain.compose.project.constants.PkColor
13 | import com.peakmain.compose.ui.divier.PkDivider
14 | import com.peakmain.compose.ui.title.PkNavBar
15 | import com.peakmain.compose.ui.title.PkTitle
16 | import com.peakmain.compose.ui.title.PkTitleType
17 |
18 | /**
19 | * author :Peakmain
20 | * createTime:2025/6/26
21 | * mail:2726449200@qq.com
22 | * describe:分割线组件
23 | */
24 | @Composable
25 | fun DividerPage() {
26 | Column(Modifier
27 | .background(PkColor.color_brand2)
28 | .fillMaxHeight(), horizontalAlignment = Alignment.CenterHorizontally) {
29 | PkNavBar("分割线组件")
30 | Column {
31 | PkTitle("默认垂直实线分割线", type = PkTitleType.TextBold1())
32 | PkDivider()
33 | }
34 | Column {
35 | PkTitle("水平实线", type = PkTitleType.TextBold1())
36 | PkDivider(modifier = Modifier.padding(top = 10.dp), isHorizontal = true)
37 | }
38 | Column {
39 | PkTitle("垂直虚线", type = PkTitleType.TextBold1())
40 | PkDivider(isDash = true)
41 | }
42 | Column {
43 | PkTitle("水平虚线", type = PkTitleType.TextBold1())
44 | PkDivider(modifier = Modifier.padding(top = 10.dp), isHorizontal = true, isDash = true)
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/page/display/compose/FlowRowPage.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.page.display.compose
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Column
5 | import androidx.compose.foundation.layout.fillMaxSize
6 | import androidx.compose.foundation.layout.padding
7 | import androidx.compose.foundation.shape.RoundedCornerShape
8 | import androidx.compose.material.Text
9 | import androidx.compose.runtime.Composable
10 | import androidx.compose.runtime.getValue
11 | import androidx.compose.runtime.mutableStateOf
12 | import androidx.compose.runtime.remember
13 | import androidx.compose.runtime.setValue
14 | import androidx.compose.ui.Modifier
15 | import androidx.compose.ui.graphics.Color
16 | import androidx.compose.ui.unit.dp
17 | import com.peakmain.compose.basic.BasicSize
18 | import com.peakmain.compose.project.R
19 | import com.peakmain.compose.ui.cell.PkCell
20 | import com.peakmain.compose.ui.divier.PkDivider
21 | import com.peakmain.compose.ui.flow.PkFlowRow
22 | import com.peakmain.compose.ui.title.PkNavBar
23 | import com.peakmain.compose.ui.title.PkTitle
24 | import com.peakmain.compose.ui.title.PkTitleType
25 |
26 | /**
27 | * author :Peakmain
28 | * createTime:2025/6/26
29 | * mail:2726449200@qq.com
30 | * describe:
31 | */
32 | @Composable
33 | fun FlowRowPage() {
34 | val tags = listOf(
35 | "Android",
36 | "Kotlin",
37 | "Jetpack Compose",
38 | "KMP",
39 | "Material Design",
40 | "UI",
41 | "Development"
42 | )
43 | var currentLine by remember {
44 | mutableStateOf(0)
45 | }
46 | var isExpand by remember {
47 | mutableStateOf(false)
48 | }
49 | Column(modifier = Modifier.fillMaxSize()) {
50 | PkNavBar("流式布局组件")
51 | Column(Modifier.padding(horizontal = 20.dp, vertical = 10.dp)) {
52 | Column {
53 | PkTitle("默认限制2行", type = PkTitleType.TextBold1())
54 | PkFlowRow(
55 | modifier = Modifier.padding(top = BasicSize.size_12),
56 | horizontalSpacing = 8.dp,
57 | verticalSpacing = 12.dp,
58 | ) {
59 | tags.forEach { tag ->
60 | Text(
61 | text = tag,
62 | modifier = Modifier
63 | .background(Color.LightGray, RoundedCornerShape(16.dp))
64 | .padding(horizontal = 12.dp, vertical = 8.dp)
65 | )
66 | }
67 | }
68 | }
69 |
70 | Column(modifier = Modifier.padding(top = 40.dp)) {
71 | if (currentLine > 2) {
72 | PkCell(
73 | "超过2行显示展开/更多",
74 | type = PkTitleType.TextBold1(),
75 | rightText = if (!isExpand) "展开" else "收起",
76 | rightIcon= if (isExpand) R.drawable.ic_expend_arrow_down else R.drawable.ic_expend_arrow_up,
77 | rightClick = {
78 | isExpand = !isExpand
79 | }
80 | )
81 | }
82 | PkFlowRow(
83 | modifier = Modifier.padding(top = BasicSize.size_12),
84 | horizontalSpacing = 8.dp,
85 | verticalSpacing = 12.dp,
86 | maxLine = if (isExpand) Int.MAX_VALUE else 2,
87 | onLineCountChanged = {
88 | currentLine = it
89 | }) {
90 | tags.forEach { tag ->
91 | Text(
92 | text = tag,
93 | modifier = Modifier
94 | .background(Color.LightGray, RoundedCornerShape(16.dp))
95 | .padding(horizontal = 12.dp, vertical = 8.dp)
96 | )
97 | }
98 | }
99 | }
100 | }
101 |
102 | }
103 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/page/display/compose/GridPage.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.page.display.compose
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Column
5 | import androidx.compose.foundation.layout.Spacer
6 | import androidx.compose.foundation.layout.fillMaxWidth
7 | import androidx.compose.foundation.layout.padding
8 | import androidx.compose.foundation.layout.width
9 | import androidx.compose.foundation.shape.RoundedCornerShape
10 | import androidx.compose.material.TabRowDefaults.Divider
11 | import androidx.compose.material.Text
12 | import androidx.compose.runtime.Composable
13 | import androidx.compose.ui.Modifier
14 | import androidx.compose.ui.graphics.Color
15 | import androidx.compose.ui.unit.dp
16 | import com.peakmain.compose.project.page.basic.compose.NavBarPage
17 | import com.peakmain.compose.space.PkSpacer
18 | import com.peakmain.compose.ui.PkGridLayout
19 | import com.peakmain.compose.ui.title.PkNavBar
20 |
21 | /**
22 | * author :Peakmain
23 | * createTime:2025/6/26
24 | * mail:2726449200@qq.com
25 | * describe:
26 | */
27 | /**
28 | * 网格布局
29 | */
30 | @Composable
31 | fun GridPage() {
32 | val dataList = mutableListOf("A", "B", "C", "D", "E", "F", "G")
33 |
34 | Column(modifier = Modifier.padding(horizontal = 15.dp)) {
35 | PkNavBar("网格布局")
36 | // 基础用法(2列,带列间距和默认分割线)
37 | PkSpacer(isHorizontal = true)
38 | PkGridLayout(
39 | columns = 2,
40 | data = dataList,
41 | isShowHorizontalDivider = true,
42 | columnSpacing = 16.dp,
43 | divider = {
44 | PkSpacer(isHorizontal = true)
45 | },
46 | ) { index, item ->
47 | Text(
48 | text = "$item${index + 1}",
49 | modifier = Modifier
50 | .background(Color.LightGray, RoundedCornerShape(8.dp))
51 | .padding(vertical = 8.dp)
52 | .fillMaxWidth()
53 |
54 | )
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/page/display/compose/HighlightTextPage.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.page.display.compose
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Column
5 | import androidx.compose.material.MaterialTheme
6 | import androidx.compose.runtime.Composable
7 | import androidx.compose.ui.Modifier
8 | import androidx.compose.ui.graphics.Color
9 | import com.peakmain.compose.project.constants.PkColor
10 | import com.peakmain.compose.ui.text.PkHighlightText
11 | import com.peakmain.compose.ui.title.PkNavBar
12 |
13 | /**
14 | * author :Peakmain
15 | * createTime:2025/6/27
16 | * mail:2726449200@qq.com
17 | * describe:
18 | */
19 | @Composable
20 | fun HighlightTextPage() {
21 | Column(modifier = Modifier.background(PkColor.color_fill1)) {
22 | PkNavBar("高亮文本组件")
23 | // 示例1:基本用法(多个关键字)
24 | PkHighlightText(
25 | text = "Jetpack Compose 是 Android 的现代 UI 工具包",
26 | keywords = listOf("compose", "android"),
27 | highlightColor = Color.Blue,
28 | style = MaterialTheme.typography.body1
29 | )
30 |
31 | // 示例2:含特殊字符的关键字
32 | PkHighlightText(
33 | text = "价格:$199 (限时优惠)",
34 | keywords = listOf("$199", "(限时优惠)"),
35 | highlightColor = Color(0xFF4CAF50)
36 | )
37 |
38 | // 示例3:无关键字/空列表
39 | PkHighlightText(
40 | text = "Hello World",
41 | keywords = emptyList() // 显示普通文本
42 | )
43 | }
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/page/display/compose/StaggeredVerticalGridPage.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.page.display.compose
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Arrangement
5 | import androidx.compose.foundation.layout.Box
6 | import androidx.compose.foundation.layout.Column
7 | import androidx.compose.foundation.layout.PaddingValues
8 | import androidx.compose.foundation.layout.fillMaxSize
9 | import androidx.compose.foundation.layout.fillMaxWidth
10 | import androidx.compose.foundation.layout.height
11 | import androidx.compose.foundation.layout.heightIn
12 | import androidx.compose.foundation.layout.padding
13 | import androidx.compose.foundation.layout.wrapContentHeight
14 | import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
15 | import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
16 | import androidx.compose.material.Text
17 | import androidx.compose.runtime.Composable
18 | import androidx.compose.ui.Alignment
19 | import androidx.compose.ui.Modifier
20 | import androidx.compose.ui.graphics.Color
21 | import androidx.compose.ui.unit.Dp
22 | import androidx.compose.ui.unit.dp
23 | import androidx.compose.ui.unit.min
24 | import com.peakmain.compose.project.component.CpColumn
25 | import com.peakmain.compose.project.constants.PkColor
26 | import com.peakmain.compose.ui.grid.PkStaggeredVerticalGrid
27 | import kotlin.random.Random
28 |
29 | /**
30 | * author :Peakmain
31 | * createTime:2025/6/27
32 | * mail:2726449200@qq.com
33 | * describe:
34 | */
35 | @Composable
36 | fun StaggeredVerticalGridPage() {
37 | // 生成示例数据(包含随机高度)
38 | val items = List(5) { index ->
39 | StaggeredItem(
40 | id = index, height = (20 + Random.nextInt(50)).dp, // 随机高度 (120-270dp)
41 | title = "Item ${index + 1}"
42 | )
43 | }
44 | CpColumn("瀑布流组件") {
45 | Column {
46 | PkStaggeredVerticalGrid(
47 | columns = 2,
48 | contentPadding = PaddingValues(16.dp),
49 | verticalItemSpacing = 4.dp,
50 | horizontalItemSpacing = 16.dp, // 水平间距
51 | modifier = Modifier.wrapContentHeight()
52 |
53 | ) {
54 | items.forEach { item ->
55 | Box(
56 | modifier = Modifier
57 | .fillMaxWidth()
58 | .height(item.height)
59 | .background(
60 | Color(
61 | red = Random.nextInt(256),
62 | green = Random.nextInt(256),
63 | blue = Random.nextInt(256),
64 | alpha = 255
65 | )
66 | ),
67 | ) {
68 | Box(
69 | modifier = Modifier
70 | .fillMaxSize(), contentAlignment = Alignment.Center
71 | ) {
72 | Text(
73 | text = item.title,
74 | color = Color.White,
75 | modifier = Modifier.padding(8.dp)
76 | )
77 | }
78 | }
79 | }
80 | }
81 | }
82 | }
83 | }
84 |
85 | data class StaggeredItem(
86 | val id: Int, val height: Dp, val title: String
87 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/page/expand/ExpandActivity.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.page.expand
2 |
3 | import android.os.Bundle
4 | import androidx.activity.ComponentActivity
5 | import androidx.activity.compose.setContent
6 | import com.peakmain.compose.project.page.expand.component.ListExtPage
7 |
8 | /**
9 | * author :Peakmain
10 | * createTime:2025/6/27
11 | * mail:2726449200@qq.com
12 | * describe:
13 | */
14 | class ExpandActivity : ComponentActivity() {
15 | val type by lazy {
16 | intent.getIntExtra("type", 0)
17 | }
18 |
19 | override fun onCreate(savedInstanceState: Bundle?) {
20 | super.onCreate(savedInstanceState)
21 | setContent {
22 | when (type) {
23 | 1 -> {
24 | //List扩展类
25 | ListExtPage()
26 | }
27 | }
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/page/expand/component/ListExtPage.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.page.expand.component
2 |
3 | import androidx.compose.foundation.layout.padding
4 | import androidx.compose.material.Text
5 | import androidx.compose.runtime.Composable
6 | import androidx.compose.ui.Modifier
7 | import androidx.compose.ui.input.key.Key.Companion.At
8 | import androidx.compose.ui.unit.dp
9 | import com.peakmain.compose.basic.BasicFont
10 | import com.peakmain.compose.ext.orSize
11 | import com.peakmain.compose.ext.sizeBigZero
12 | import com.peakmain.compose.ext.slice
13 | import com.peakmain.compose.project.component.CpColumn
14 | import com.peakmain.compose.project.component.CpTitle
15 | import com.peakmain.compose.project.constants.PkColor
16 |
17 | /**
18 | * author :Peakmain
19 | * createTime:2025/6/27
20 | * mail:2726449200@qq.com
21 | * describe:
22 | */
23 | @Composable
24 | fun ListExtPage() {
25 | val list1: List? = null
26 | val list2 = arrayListOf("list1", "list2", "list3", "list4")
27 | CpColumn("List扩展类") {
28 | CpTitle("空数组list1的大小:${list1.orSize()}")
29 | CpTitle("空数组list1的大小是否等于0:${list1.sizeBigZero()}")
30 | CpTitle("空数组list1的大小是否大于0:${list1.sizeBigZero()}")
31 | CpTitle("定索引范围 [fromIndex, toIndex) 内的子列表视图")
32 | var result: String = "结果是:"
33 | list2.slice(1, 3)?.forEach {
34 | result +="$it,"
35 | }
36 | Text(result, fontSize = BasicFont.font_10, color = PkColor.color_text1, modifier = Modifier.padding(horizontal = 18.dp))
37 |
38 | }
39 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/page/tools/ToolsActivity.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.page.tools
2 |
3 | import android.os.Bundle
4 | import androidx.activity.ComponentActivity
5 | import androidx.activity.compose.setContent
6 | import com.peakmain.compose.project.page.tools.component.ImagePainterUtilsPage
7 |
8 | /**
9 | * author :Peakmain
10 | * createTime:2025/6/27
11 | * mail:2726449200@qq.com
12 | * describe:
13 | */
14 | class ToolsActivity : ComponentActivity() {
15 | val type by lazy {
16 | intent.getIntExtra("type", 0)
17 | }
18 |
19 | override fun onCreate(savedInstanceState: Bundle?) {
20 | super.onCreate(savedInstanceState)
21 | setContent {
22 | when (type) {
23 | 1 -> {
24 | ImagePainterUtilsPage()
25 | }
26 | }
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/page/tools/component/ImagePainterUtilsPage.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.page.tools.component
2 |
3 | import androidx.compose.foundation.Image
4 | import androidx.compose.foundation.layout.Column
5 | import androidx.compose.foundation.layout.Row
6 | import androidx.compose.foundation.layout.height
7 | import androidx.compose.foundation.layout.padding
8 | import androidx.compose.foundation.layout.size
9 | import androidx.compose.foundation.layout.width
10 | import androidx.compose.material.Text
11 | import androidx.compose.runtime.Composable
12 | import androidx.compose.ui.Modifier
13 | import androidx.compose.ui.input.pointer.PointerIcon.Companion.Text
14 | import androidx.compose.ui.unit.dp
15 | import com.peakmain.compose.project.component.CpCell
16 | import com.peakmain.compose.project.component.CpColumn
17 | import com.peakmain.compose.project.component.CpTitle
18 | import com.peakmain.compose.ui.image.PkImageView
19 | import com.peakmain.compose.ui.title.PkTitle
20 | import com.peakmain.compose.ui.title.PkTitleType
21 | import com.peakmain.compose.utils.ImagePainterUtils
22 |
23 | /**
24 | * author :Peakmain
25 | * createTime:2025/6/27
26 | * mail:2726449200@qq.com
27 | * describe:
28 | */
29 | @Composable
30 | fun ImagePainterUtilsPage() {
31 | val imageUrls =
32 | arrayListOf(
33 | "https://inews.gtimg.com/om_bt/O3HPBXvE8uZQS2PlMcFZpECPpRqLPVJ-ti-LYB2z5JdiYAA/641",
34 | "https://coil-kt.github.io/coil/images/coil_logo_black.svg",
35 | "https://ww3.sinaimg.cn/mw690/005Ohgevjw1eobhokb9ekg30cc06y1l0.gif"
36 | )
37 | CpColumn("ImagePainterUtils工具类") {
38 | Row {
39 | Column {
40 | CpTitle("正常展示png/jpg/webp图片")
41 | PkImageView(
42 | ImagePainterUtils.getPainter(imageUrls[0]),
43 | modifier = Modifier.height(150.dp)
44 | )
45 | }
46 | Column {
47 | CpTitle("展示svg图片")
48 | PkImageView(
49 | painter = ImagePainterUtils.getPainter(imageUrls[1]),
50 | modifier = Modifier.height(150.dp)
51 | )
52 | }
53 |
54 | }
55 | Row {
56 | Column {
57 | CpTitle("展示gif图片")
58 | PkImageView(
59 | painter = ImagePainterUtils.getPainter(imageUrls[2]),
60 | )
61 |
62 | }
63 | Column(modifier = Modifier.padding(horizontal = 18.dp)) {
64 | CpTitle("占位图")
65 | PkImageView(
66 | painter = ImagePainterUtils.getPainter(null),
67 | modifier = Modifier.size(150.dp)
68 | )
69 | }
70 | }
71 | }
72 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/ui/theme/Color.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.ui.theme
2 |
3 | import androidx.compose.ui.graphics.Color
4 | val Color_149EE7= Color(0xFF149EE7)
5 | val Color_2DCDF5= Color(0xFF2DCDF5)
6 |
7 | val Color_999999=Color(0xFF999999)
8 | val Color_969799=Color(0xFF969799)
9 | val Color_323233=Color(0xFF323233)
10 | val Color_D1D1D1=Color(0xFFD1D1D1)
11 |
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/ui/theme/Shape.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.ui.theme
2 |
3 | import androidx.compose.foundation.shape.RoundedCornerShape
4 | import androidx.compose.material.Shapes
5 | import androidx.compose.ui.unit.dp
6 |
7 | val Shapes = Shapes(
8 | small = RoundedCornerShape(4.dp),
9 | medium = RoundedCornerShape(4.dp),
10 | large = RoundedCornerShape(0.dp)
11 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/ui/theme/Theme.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.ui.theme
2 |
3 | import androidx.compose.material.MaterialTheme
4 | import androidx.compose.material.lightColors
5 | import androidx.compose.runtime.Composable
6 |
7 | private val LightColorPalette = lightColors(
8 | primary = Color_149EE7,
9 | primaryVariant = Color_149EE7,
10 | secondary = Color_2DCDF5
11 | )
12 |
13 | @Composable
14 | fun ComposeProjectTheme(
15 | content: @Composable() () -> Unit,
16 | ) {
17 | val colors =
18 | LightColorPalette
19 |
20 | MaterialTheme(
21 | colors = colors,
22 | typography = Typography,
23 | shapes = Shapes,
24 | content = content
25 | )
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/ui/theme/Type.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.ui.theme
2 |
3 | import androidx.compose.material.Typography
4 | import androidx.compose.ui.text.TextStyle
5 | import androidx.compose.ui.text.font.FontFamily
6 | import androidx.compose.ui.text.font.FontWeight
7 | import androidx.compose.ui.unit.sp
8 |
9 | // Set of Material typography styles to start with
10 | val Typography = Typography(
11 | body1 = TextStyle(
12 | fontFamily = FontFamily.Default,
13 | fontWeight = FontWeight.Normal,
14 | fontSize = 16.sp
15 | )
16 | /* Other default text styles to override
17 | button = TextStyle(
18 | fontFamily = FontFamily.Default,
19 | fontWeight = FontWeight.W500,
20 | fontSize = 14.sp
21 | ),
22 | caption = TextStyle(
23 | fontFamily = FontFamily.Default,
24 | fontWeight = FontWeight.Normal,
25 | fontSize = 12.sp
26 | )
27 | */
28 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/ui/view/MainFrame.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.ui.view
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2022/5/2
6 | * mail:2726449200@qq.com
7 | * describe:
8 | */
9 | import android.annotation.SuppressLint
10 | import androidx.compose.foundation.layout.navigationBarsPadding
11 | import androidx.compose.material.*
12 | import androidx.compose.material.icons.Icons
13 | import androidx.compose.material.icons.filled.*
14 | import androidx.compose.runtime.*
15 | import androidx.compose.ui.Modifier
16 | import androidx.compose.ui.tooling.preview.Preview
17 | import com.peakmain.compose.project.bean.main.NavigationItem
18 | import com.peakmain.compose.project.ui.theme.Color_149EE7
19 | import com.peakmain.compose.project.ui.theme.Color_999999
20 | import com.peakmain.compose.project.ui.view.main.HomeFragment
21 | import com.peakmain.compose.project.ui.view.main.ExpandFragment
22 | import com.peakmain.compose.project.ui.view.main.ProjectFragment
23 | import com.peakmain.compose.project.ui.view.main.TypeFragment
24 |
25 | @SuppressLint("UnusedMaterialScaffoldPaddingParameter")
26 | @Composable
27 | fun MainFrame() {
28 | val navigationItems = listOf(
29 | NavigationItem("基础组件", Icons.Default.Home),
30 | NavigationItem("展示组件", Icons.Default.AccountCircle),
31 | NavigationItem("工具类", Icons.Default.LocationOn),
32 | NavigationItem("扩展类", Icons.Default.Person)
33 | )
34 | var currentNavigationIndex by remember {
35 | mutableStateOf(0)
36 | }
37 | Scaffold(
38 | bottomBar = {
39 | BottomNavigation(
40 | backgroundColor = MaterialTheme.colors.surface,
41 | modifier = Modifier.navigationBarsPadding()
42 | ) {
43 | navigationItems.forEachIndexed { index, navigationItem ->
44 | BottomNavigationItem(
45 | selected = currentNavigationIndex == index,
46 | onClick = { currentNavigationIndex = index },
47 | icon = {
48 | Icon(imageVector = navigationItem.icon, contentDescription = null)
49 | },
50 | label = {
51 | Text(text = navigationItem.title)
52 | },
53 | selectedContentColor = Color_149EE7,
54 | unselectedContentColor = Color_999999
55 | )
56 | }
57 | }
58 | },
59 | ) {
60 | when (currentNavigationIndex) {
61 | 0 -> HomeFragment()
62 | 1 -> ProjectFragment()
63 | 2 -> TypeFragment()
64 | else -> ExpandFragment()
65 | }
66 | }
67 | }
68 |
69 | @Preview
70 | @Composable
71 | fun MainFramePreview() {
72 | MainFrame()
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/ui/view/main/BasicFragment.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.ui.view.main
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2022/5/2
6 | * mail:2726449200@qq.com
7 | * describe:
8 | */
9 | import android.content.Intent
10 | import androidx.compose.foundation.background
11 | import androidx.compose.foundation.clickable
12 | import androidx.compose.foundation.layout.Arrangement
13 | import androidx.compose.foundation.layout.Column
14 | import androidx.compose.foundation.layout.fillMaxSize
15 | import androidx.compose.foundation.layout.padding
16 | import androidx.compose.material.Text
17 | import androidx.compose.runtime.Composable
18 | import androidx.compose.ui.Alignment
19 | import androidx.compose.ui.Modifier
20 | import androidx.compose.ui.graphics.Brush
21 | import androidx.compose.ui.graphics.Color
22 | import androidx.compose.ui.platform.LocalContext
23 | import com.peakmain.compose.basic.BasicSpace
24 | import com.peakmain.compose.library.TopAppBarCenter
25 | import com.peakmain.compose.project.page.basic.BasicComponentActivity
26 | import com.peakmain.compose.project.ui.theme.Color_149EE7
27 | import com.peakmain.compose.project.ui.theme.Color_2DCDF5
28 | import com.peakmain.compose.ui.cell.PkCell
29 | import com.peakmain.compose.ui.title.PkTitleType
30 |
31 | @Composable
32 | fun HomeFragment() {
33 | val context = LocalContext.current
34 | val intent=Intent(context,BasicComponentActivity::class.java)
35 | TopAppBarCenter(
36 | title = {
37 | Text(text = "首页", color = Color.White)
38 | },
39 | isImmersive = true,
40 | modifier = Modifier.background(Brush.linearGradient(listOf(Color_149EE7, Color_2DCDF5)))
41 | ) {
42 |
43 | Column(
44 | modifier = Modifier
45 | .padding(BasicSpace.space_18)
46 | .fillMaxSize(),
47 | verticalArrangement = Arrangement.spacedBy(BasicSpace.space_18),
48 | horizontalAlignment = Alignment.CenterHorizontally
49 | ) {
50 | PkCell(text = "标题组件", modifier = Modifier.clickable {
51 | intent.putExtra("type",1)
52 | context.startActivity(intent)
53 | }, type = PkTitleType.TitleBold1())
54 | PkCell(text = "NavBar导航栏", modifier = Modifier.clickable {
55 | intent.putExtra("type",2)
56 | context.startActivity(intent)
57 | }, type = PkTitleType.TitleBold1())
58 |
59 | PkCell(text = "单元格组件", modifier = Modifier.clickable {
60 | intent.putExtra("type",3)
61 | context.startActivity(intent)
62 | }, type = PkTitleType.TitleBold1())
63 | PkCell(text = "按钮组件", modifier = Modifier.clickable {
64 | intent.putExtra("type",4)
65 | context.startActivity(intent)
66 | }, type = PkTitleType.TitleBold1())
67 | PkCell(text = "图片组件", modifier = Modifier.clickable {
68 | intent.putExtra("type",5)
69 | context.startActivity(intent)
70 | }, type = PkTitleType.TitleBold1())
71 | }
72 | }
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/ui/view/main/DisplayFragment.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.ui.view.main
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2022/5/2
6 | * mail:2726449200@qq.com
7 | * describe:
8 | */
9 | import android.content.Intent
10 | import androidx.compose.foundation.background
11 | import androidx.compose.foundation.layout.Arrangement
12 | import androidx.compose.foundation.layout.Column
13 | import androidx.compose.foundation.layout.fillMaxSize
14 | import androidx.compose.foundation.layout.padding
15 | import androidx.compose.material.Text
16 | import androidx.compose.runtime.Composable
17 | import androidx.compose.ui.Alignment
18 | import androidx.compose.ui.Modifier
19 | import androidx.compose.ui.graphics.Brush
20 | import androidx.compose.ui.graphics.Color
21 | import androidx.compose.ui.platform.LocalContext
22 | import com.peakmain.compose.basic.BasicSpace
23 | import com.peakmain.compose.library.TopAppBarCenter
24 | import com.peakmain.compose.project.component.CpCell
25 | import com.peakmain.compose.project.page.display.DisplayComponentActivity
26 | import com.peakmain.compose.project.ui.theme.Color_149EE7
27 | import com.peakmain.compose.project.ui.theme.Color_2DCDF5
28 |
29 | @Composable
30 | fun ProjectFragment() {
31 | val context = LocalContext.current
32 | val intent = Intent(context, DisplayComponentActivity::class.java)
33 | val lists = arrayListOf("网格布局", "分割线", "流式布局", "轮播图", "高亮文本", "瀑布流")
34 | TopAppBarCenter(
35 | title = {
36 | Text(text = "展示组件", color = Color.White)
37 | },
38 | isImmersive = true,
39 | modifier = Modifier.background(Brush.linearGradient(listOf(Color_149EE7, Color_2DCDF5)))
40 | ) {
41 |
42 | Column(
43 | modifier = Modifier
44 | .padding(BasicSpace.space_18)
45 | .fillMaxSize(),
46 | verticalArrangement = Arrangement.spacedBy(BasicSpace.space_18),
47 | horizontalAlignment = Alignment.CenterHorizontally
48 | ) {
49 | lists.forEachIndexed { index, item ->
50 | CpCell(item, intent, index + 1)
51 | }
52 | }
53 | }
54 | }
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/ui/view/main/ExpandFragment.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.ui.view.main
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2022/5/2
6 | * mail:2726449200@qq.com
7 | * describe:我的
8 | */
9 | import android.content.Intent
10 | import androidx.compose.foundation.background
11 | import androidx.compose.foundation.layout.*
12 | import androidx.compose.material.Text
13 | import androidx.compose.runtime.Composable
14 | import androidx.compose.ui.Alignment
15 | import androidx.compose.ui.Modifier
16 | import androidx.compose.ui.graphics.Brush
17 | import androidx.compose.ui.graphics.Color
18 | import androidx.compose.ui.platform.LocalContext
19 | import com.peakmain.compose.project.ui.theme.Color_149EE7
20 | import com.peakmain.compose.project.ui.theme.Color_2DCDF5
21 | import com.peakmain.compose.basic.BasicSpace
22 | import com.peakmain.compose.library.TopAppBarCenter
23 | import com.peakmain.compose.project.component.CpCell
24 | import com.peakmain.compose.project.page.display.DisplayComponentActivity
25 | import com.peakmain.compose.project.page.expand.ExpandActivity
26 |
27 | @Composable
28 | fun ExpandFragment() {
29 | val context = LocalContext.current
30 | val intent = Intent(context, ExpandActivity::class.java)
31 | val lists = arrayListOf("List扩展类", "String扩展类")
32 | TopAppBarCenter(
33 | title = {
34 | Text(text = "展示组件", color = Color.White)
35 | },
36 | isImmersive = true,
37 | modifier = Modifier.background(Brush.linearGradient(listOf(Color_149EE7, Color_2DCDF5)))
38 | ) {
39 |
40 | Column(
41 | modifier = Modifier
42 | .padding(BasicSpace.space_18)
43 | .fillMaxSize(),
44 | verticalArrangement = Arrangement.spacedBy(BasicSpace.space_18),
45 | horizontalAlignment = Alignment.CenterHorizontally
46 | ) {
47 | lists.forEachIndexed { index, item ->
48 | CpCell(item, intent, index + 1)
49 | }
50 | }
51 | }
52 | }
53 |
54 |
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/ui/view/main/ToolsFragment.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.ui.view.main
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2022/5/2
6 | * mail:2726449200@qq.com
7 | * describe:分类Fragment
8 | */
9 | import android.content.Intent
10 | import androidx.compose.foundation.ExperimentalFoundationApi
11 | import androidx.compose.foundation.background
12 | import androidx.compose.foundation.layout.Arrangement
13 | import androidx.compose.foundation.layout.Column
14 | import androidx.compose.foundation.layout.fillMaxSize
15 | import androidx.compose.foundation.layout.padding
16 | import androidx.compose.material.Text
17 | import androidx.compose.runtime.Composable
18 | import androidx.compose.ui.Alignment
19 | import androidx.compose.ui.Modifier
20 | import androidx.compose.ui.graphics.Brush
21 | import androidx.compose.ui.graphics.Color
22 | import androidx.compose.ui.platform.LocalContext
23 | import com.peakmain.compose.basic.BasicSpace
24 | import com.peakmain.compose.library.TopAppBarCenter
25 | import com.peakmain.compose.project.component.CpCell
26 | import com.peakmain.compose.project.page.tools.ToolsActivity
27 | import com.peakmain.compose.project.ui.theme.Color_149EE7
28 | import com.peakmain.compose.project.ui.theme.Color_2DCDF5
29 |
30 |
31 | @OptIn(ExperimentalFoundationApi::class)
32 | @Composable
33 | fun TypeFragment() {
34 | val context = LocalContext.current
35 | val intent = Intent(context, ToolsActivity::class.java)
36 | val lists = arrayListOf("ImagePainter工具类")
37 | TopAppBarCenter(
38 | title = {
39 | Text(text = "展示组件", color = Color.White)
40 | },
41 | isImmersive = true,
42 | modifier = Modifier.background(Brush.linearGradient(listOf(Color_149EE7, Color_2DCDF5)))
43 | ) {
44 |
45 | Column(
46 | modifier = Modifier
47 | .padding(BasicSpace.space_18)
48 | .fillMaxSize(),
49 | verticalArrangement = Arrangement.spacedBy(BasicSpace.space_18),
50 | horizontalAlignment = Alignment.CenterHorizontally
51 | ) {
52 | lists.forEachIndexed { index, item ->
53 | CpCell(item, intent, index + 1)
54 | }
55 | }
56 | }
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/viewmodel/home/HomeFragmentViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.viewmodel.home
2 |
3 | import androidx.compose.runtime.getValue
4 | import androidx.compose.runtime.mutableStateOf
5 | import androidx.lifecycle.ViewModel
6 | import com.peakmain.compose.project.bean.home.BannerBean
7 |
8 | /**
9 | * author :Peakmain
10 | * createTime:2022/5/5
11 | * mail:2726449200@qq.com
12 | * describe:
13 | */
14 | class HomeFragmentViewModel : ViewModel() {
15 |
16 | val bannerData by mutableStateOf(
17 | listOf(
18 | BannerBean("http://img.ahhuabang.com/data/banner/phone20220429gtvjsq.jpg","标题一"),
19 | BannerBean("http://img.ahhuabang.com/data/banner/phone20220429plqcyr.jpg","标题二"),
20 | BannerBean("http://img.ahhuabang.com/data/banner/phone20220429taojjf.jpg","标题三"),
21 | BannerBean("http://img.ahhuabang.com/data/banner/phone20220422aeoihx.jpg","标题四"),
22 | )
23 | )
24 |
25 |
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/compose/project/viewmodel/mine/MineFragmentViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project.viewmodel.mine
2 |
3 | import androidx.compose.material.icons.Icons
4 | import androidx.compose.material.icons.filled.Settings
5 | import androidx.compose.material.icons.filled.ThumbUp
6 | import androidx.compose.runtime.getValue
7 | import androidx.compose.runtime.mutableStateOf
8 | import androidx.lifecycle.ViewModel
9 | import com.peakmain.compose.project.bean.mine.MineItemBean
10 |
11 | /**
12 | * author :Peakmain
13 | * createTime:2022/5/7
14 | * mail:2726449200@qq.com
15 | * describe:
16 | */
17 | class MineFragmentViewModel :ViewModel(){
18 | val mineItemBeans by mutableStateOf(
19 | listOf(
20 | MineItemBean("我的收藏",Icons.Default.ThumbUp),
21 | MineItemBean("设置",Icons.Default.Settings),
22 |
23 | )
24 | )
25 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/background_laundry_delivery.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_expend_arrow_down.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_expend_arrow_up.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/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 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_online_check_out_disable.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/portrair.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/ComposeUI/130ddea901c25d528b4a130ba2c6919cb55a8155/app/src/main/res/drawable/portrair.JPG
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/ComposeUI/130ddea901c25d528b4a130ba2c6919cb55a8155/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/ComposeUI/130ddea901c25d528b4a130ba2c6919cb55a8155/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/ComposeUI/130ddea901c25d528b4a130ba2c6919cb55a8155/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/ComposeUI/130ddea901c25d528b4a130ba2c6919cb55a8155/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/ComposeUI/130ddea901c25d528b4a130ba2c6919cb55a8155/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/ComposeUI/130ddea901c25d528b4a130ba2c6919cb55a8155/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/ComposeUI/130ddea901c25d528b4a130ba2c6919cb55a8155/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/ComposeUI/130ddea901c25d528b4a130ba2c6919cb55a8155/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/ComposeUI/130ddea901c25d528b4a130ba2c6919cb55a8155/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/ComposeUI/130ddea901c25d528b4a130ba2c6919cb55a8155/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FF149EE7
4 | #9D9C96
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ComposeProject
3 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
--------------------------------------------------------------------------------
/app/src/test/java/com/peakmain/compose/project/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.project
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 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | ext.kotlin_version = '1.9.20'
4 | repositories {
5 | maven { url = uri("https://maven.aliyun.com/repository/central") }
6 | maven { url = uri("https://maven.aliyun.com/repository/google") }
7 | maven { url = uri("https://maven.aliyun.com/repository/public") }
8 | google()
9 | mavenCentral()
10 | }
11 | dependencies {
12 | classpath 'com.android.tools.build:gradle:8.4.0'
13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14 |
15 | // NOTE: Do not place your application dependencies here; they belong
16 | // in the individual module build.gradle files
17 | }
18 | }
19 |
20 | task clean(type: Delete) {
21 | delete rootProject.buildDir
22 | }
--------------------------------------------------------------------------------
/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=-Xmx2048m -Dfile.encoding=UTF-8
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.nonTransitiveRClass=false
23 | android.nonFinalResIds=false
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/ComposeUI/130ddea901c25d528b4a130ba2c6919cb55a8155/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon May 02 12:27:14 CST 2022
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.android.library'
3 | id 'kotlin-android'
4 | }
5 |
6 | android {
7 | compileSdk 35
8 |
9 | defaultConfig {
10 | minSdk 21
11 | targetSdk 31
12 |
13 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
14 | consumerProguardFiles "consumer-rules.pro"
15 | }
16 |
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | buildFeatures {
24 | compose true
25 | }
26 | composeOptions {
27 | kotlinCompilerExtensionVersion = "1.5.4"
28 | }
29 | kotlinOptions {
30 | jvmTarget = '1.8'
31 | }
32 | namespace 'com.peakmain.compose.library'
33 | }
34 |
35 | dependencies {
36 | api platform('androidx.compose:compose-bom:2023.10.01')
37 |
38 | // 按需引入组件(无需指定版本)
39 | api 'androidx.compose.ui:ui'
40 | api 'androidx.compose.material3:material3'
41 | api 'androidx.compose.foundation:foundation'
42 | api "androidx.compose.ui:ui-tooling:1.5.4"
43 | api "androidx.constraintlayout:constraintlayout-compose:1.0.0"
44 | api ("io.coil-kt:coil-compose:2.4.0")
45 | api ("io.coil-kt:coil-svg:2.4.0")
46 | api ("io.coil-kt:coil-gif:2.4.0")
47 |
48 | def accompanist_version = "0.33.1-alpha"
49 | api "com.google.accompanist:accompanist-systemuicontroller:${accompanist_version}"
50 | //api "com.google.accompanist:accompanist-insets:$accompanist_version"
51 | api "com.google.accompanist:accompanist-pager:${accompanist_version}"
52 | api "com.google.accompanist:accompanist-pager-indicators:${accompanist_version}"
53 |
54 | }
--------------------------------------------------------------------------------
/library/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/ComposeUI/130ddea901c25d528b4a130ba2c6919cb55a8155/library/consumer-rules.pro
--------------------------------------------------------------------------------
/library/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
--------------------------------------------------------------------------------
/library/src/androidTest/java/com/peakmain/compose/library/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.library
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.peakmain.compose.base_library.test", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/basic/BasicColor.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.basic
2 |
3 | import androidx.compose.material.Card
4 | import androidx.compose.ui.graphics.Color
5 |
6 | /**
7 | * author :Peakmain
8 | * createTime:2025/3/31
9 | * mail:2726449200@qq.com
10 | * describe:
11 | */
12 |
13 | /**
14 | * 不透明度 (Opacity) 与十六进制 (Hex) 对照表
15 | *
16 | * 不透明度 (%) | 十六进制 (Hex) | 不透明度 (%) | 十六进制 (Hex) | 不透明度 (%) | 十六进制 (Hex)
17 | * ---------------------------------------------------------------------------------------------
18 | * 0% | 00 | 34% | 57 | 68% | AC
19 | * 1% | 03 | 35% | 5A | 69% | AE
20 | * 2% | 05 | 36% | 5C | 70% | B2
21 | * 3% | 08 | 37% | 5F | 71% | B5
22 | * 4% | 0A | 38% | 61 | 72% | B7
23 | * 5% | 0D | 39% | 63 | 73% | BA
24 | * 6% | 0F | 40% | 66 | 74% | BC
25 | * 7% | 12 | 41% | 68 | 75% | BF
26 | * 8% | 14 | 42% | 6B | 76% | C1
27 | * 9% | 17 | 43% | 6D | 77% | C4
28 | * 10% | 1A | 44% | 70 | 78% | C6
29 | * 11% | 1C | 45% | 73 | 79% | C9
30 | * 12% | 1F | 46% | 75 | 80% | CC
31 | * 13% | 21 | 47% | 78 | 81% | CE
32 | * 14% | 24 | 48% | 7A | 82% | D1
33 | * 15% | 26 | 49% | 7D | 83% | D3
34 | * 16% | 29 | 50% | 80 | 84% | D6
35 | * 17% | 2B | 51% | 83 | 85% | D9
36 | * 18% | 2E | 52% | 85 | 86% | DB
37 | * 19% | 30 | 53% | 88 | 87% | DE
38 | * 20% | 33 | 54% | 8A | 88% | E0
39 | * 21% | 36 | 55% | 8D | 89% | E3
40 | * 22% | 38 | 56% | 8F | 90% | E6
41 | * 23% | 3B | 57% | 92 | 91% | E8
42 | * 24% | 3D | 58% | 94 | 92% | EB
43 | * 25% | 40 | 59% | 97 | 93% | ED
44 | * 26% | 42 | 60% | 99 | 94% | F0
45 | * 27% | 45 | 61% | 9C | 95% | F2
46 | * 28% | 47 | 62% | 9E | 96% | F5
47 | * 29% | 4A | 63% | A1 | 97% | F7
48 | * 30% | 4D | 64% | A3 | 98% | FA
49 | * 31% | 4F | 65% | A6 | 99% | FC
50 | * 32% | 52 | 66% | A8 | 100% | FF
51 | * 33% | 54 | 67% | AB
52 | */
53 | object BasicColor {
54 | val color_80cbc4 = Color(0xFF80CBC4)
55 | val color_212121 = Color(0xFF212121)
56 | val color_FFFFFF = Color(0xFFFFFFFF)
57 | val color_E1F1EB = Color(0xFFE1F1EB)
58 | val color_EFF2F4 = Color(0xFFEFF2F4)
59 |
60 |
61 | val color_FFFFFF_80 = Color(0xCCFFFFFF)
62 | val color_FFFFFF_50 = Color(0x80FFFFFF)
63 |
64 | val color_E2263D = Color(0xFFE2263D)
65 | val color_0076ff = Color(0xFF0076FF)
66 | val color_FF5368 = Color(0xFFFF5368)
67 | val color_40BE65 = Color(0xFF40BE65)
68 | val color_80E56A54 = Color(0x80E56A54)
69 | val color_00FFFFFF =Color(0x00FFFFFF)
70 | val color_FFF3F3F3=Color(0xFFF3F3F3)
71 | val color_FF000000=Color(0xFF000000)
72 |
73 | val color_F7F7F7_80 = Color(0xCCF7F7F7)
74 | val color_ECECE080 = Color(0xECECE080)
75 | val color_000000_60 = Color(0x99000000)
76 | val color_ECECE0B3 = Color(0xB3ECECE0)
77 |
78 | val color_1F401B_15 = Color(0x261F401B)
79 |
80 | val color_333333 = Color(0xFF333333)
81 | val color_666666 = Color(0xFF666666)
82 | val color_9D9C96 = Color(0xFF9D9C96)
83 | val color_D4D4D5 = Color(0xFFD4D4D5)
84 | val color_EBEBF0 = Color(0xFFEBEBF0)
85 | val color_F8F9F3= Color(0xFFF8F9F3)
86 | val color_9D9C96_10 = Color(0x1A9D9C96)
87 | val color_FFFEFA= Color(0xFFFFFEFA)
88 |
89 | val color_B9824C=Color(0xFFB9824C)
90 | val color_A5534D=Color(0xFFA5534D)
91 | val color_67696a=Color(0xFF67696a)
92 | val color_272A2B=Color(0xFF272A2B)
93 |
94 | val color_1F401B=Color(0xFF1F401B)
95 | val color_677C64=Color(0xFF677C64)
96 | val color_B59E6D=Color(0xFFB59E6D)
97 | val color_DDCC9E=Color(0xFFDDCC9E)
98 | val color_126E82=Color(0xFF126E82)
99 | val color_F2F3EC=Color(0xFFF2F3EC)
100 |
101 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/basic/BasicFont.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.basic
2 | import androidx.compose.ui.unit.sp
3 |
4 | /**
5 | * author :Peakmain
6 | * createTime:2025/3/31
7 | * mail:2726449200@qq.com
8 | * describe:
9 | */
10 |
11 | object BasicFont {
12 | val font_1 = 1.sp
13 | val font_2 = 2.sp
14 | val font_3 = 3.sp
15 | val font_4 = 4.sp
16 | val font_5 = 5.sp
17 | val font_6 = 6.sp
18 | val font_7 = 7.sp
19 | val font_8 = 8.sp
20 | val font_9 = 9.sp
21 | val font_10 = 10.sp
22 | val font_11 = 11.sp
23 | val font_12 = 12.sp
24 | val font_13 = 13.sp
25 | val font_14 = 14.sp
26 | val font_15 = 15.sp
27 | val font_16 = 16.sp
28 | val font_17 = 17.sp
29 | val font_18 = 18.sp
30 | val font_19 = 19.sp
31 | val font_20 = 20.sp
32 | val font_21 = 21.sp
33 | val font_22 = 22.sp
34 | val font_23 = 23.sp
35 | val font_24 = 24.sp
36 | val font_25 = 25.sp
37 | val font_26 = 26.sp
38 | val font_27 = 27.sp
39 | val font_28 = 28.sp
40 | val font_29 = 29.sp
41 | val font_30 = 30.sp
42 | val font_31 = 31.sp
43 | val font_32 = 32.sp
44 | val font_33 = 33.sp
45 | val font_34 = 34.sp
46 | val font_35 = 35.sp
47 | val font_36 = 36.sp
48 | val font_37 = 37.sp
49 | val font_38 = 38.sp
50 | val font_39 = 39.sp
51 | val font_40 = 40.sp
52 | val font_41 = 41.sp
53 | val font_42 = 42.sp
54 | val font_43 = 43.sp
55 | val font_44 = 44.sp
56 | val font_45 = 45.sp
57 | val font_46 = 46.sp
58 | val font_47 = 47.sp
59 | val font_48 = 48.sp
60 | val font_49 = 49.sp
61 | val font_50 = 50.sp
62 | val font_51 = 51.sp
63 | val font_52 = 52.sp
64 | val font_53 = 53.sp
65 | val font_54 = 54.sp
66 | val font_55 = 55.sp
67 | val font_56 = 56.sp
68 | val font_57 = 57.sp
69 | val font_58 = 58.sp
70 | val font_59 = 59.sp
71 | val font_60 = 60.sp
72 | val font_61 = 61.sp
73 | val font_62 = 62.sp
74 | val font_63 = 63.sp
75 | val font_64 = 64.sp
76 | val font_65 = 65.sp
77 | val font_66 = 66.sp
78 | val font_67 = 67.sp
79 | val font_68 = 68.sp
80 | val font_69 = 69.sp
81 | val font_70 = 70.sp
82 | val font_71 = 71.sp
83 | val font_72 = 72.sp
84 | val font_73 = 73.sp
85 | val font_74 = 74.sp
86 | val font_75 = 75.sp
87 | val font_76 = 76.sp
88 | val font_77 = 77.sp
89 | val font_78 = 78.sp
90 | val font_79 = 79.sp
91 | val font_80 = 80.sp
92 | val font_81 = 81.sp
93 | val font_82 = 82.sp
94 | val font_83 = 83.sp
95 | val font_84 = 84.sp
96 | val font_85 = 85.sp
97 | val font_86 = 86.sp
98 | val font_87 = 87.sp
99 | val font_88 = 88.sp
100 | val font_89 = 89.sp
101 | val font_90 = 90.sp
102 | val font_91 = 91.sp
103 | val font_92 = 92.sp
104 | val font_93 = 93.sp
105 | val font_94 = 94.sp
106 | val font_95 = 95.sp
107 | val font_96 = 96.sp
108 | val font_97 = 97.sp
109 | val font_98 = 98.sp
110 | val font_99 = 99.sp
111 | val font_100 = 100.sp
112 | }
113 |
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/basic/BasicRadius.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.basic
2 |
3 | import androidx.compose.ui.unit.dp
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2025/3/31
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | object BasicRadius {
12 | val radius_0 = 0.dp
13 | val radius_1 = 1.dp
14 | val radius_2 = 2.dp
15 | val radius_3 = 3.dp
16 | val radius_4 = 4.dp
17 | val radius_5 = 5.dp
18 | val radius_6 = 6.dp
19 | val radius_7 = 7.dp
20 | val radius_8 = 8.dp
21 | val radius_9 = 9.dp
22 | val radius_10 = 10.dp
23 | val radius_11 = 11.dp
24 | val radius_12 = 12.dp
25 | val radius_larger = 888.dp
26 | val radius_circle = 999.dp
27 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/basic/BasicSize.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.basic
2 |
3 | import androidx.compose.ui.unit.dp
4 |
5 |
6 | object BasicSize {
7 | val size_0= 0.dp
8 | val size_0_5 = 0.5.dp
9 | val size_1 = 1.dp
10 | val size_2 = 2.dp
11 | val size_3 = 3.dp
12 | val size_4 = 4.dp
13 | val size_5 = 5.dp
14 | val size_6 = 6.dp
15 | val size_7 = 7.dp
16 | val size_8 = 8.dp
17 | val size_9 = 9.dp
18 | val size_10 = 10.dp
19 | val size_11 = 11.dp
20 | val size_12 = 12.dp
21 | val size_13 = 13.dp
22 | val size_14 = 14.dp
23 | val size_15 = 15.dp
24 | val size_16 = 16.dp
25 | val size_17 = 17.dp
26 | val size_18 = 18.dp
27 | val size_19 = 19.dp
28 | val size_20 = 20.dp
29 | val size_21 = 21.dp
30 | val size_22 = 22.dp
31 | val size_23 = 23.dp
32 | val size_24 = 24.dp
33 | val size_25 = 25.dp
34 | val size_26 = 26.dp
35 | val size_27 = 27.dp
36 | val size_28 = 28.dp
37 | val size_29 = 29.dp
38 | val size_30 = 30.dp
39 | val size_31 = 31.dp
40 | val size_32 = 32.dp
41 | val size_33 = 33.dp
42 | val size_34 = 34.dp
43 | val size_35 = 35.dp
44 | val size_36 = 36.dp
45 | val size_37 = 37.dp
46 | val size_38 = 38.dp
47 | val size_39 = 39.dp
48 | val size_40 = 40.dp
49 | val size_41 = 41.dp
50 | val size_42 = 42.dp
51 | val size_43 = 43.dp
52 | val size_44 = 44.dp
53 | val size_45 = 45.dp
54 | val size_46 = 46.dp
55 | val size_47 = 47.dp
56 | val size_48 = 48.dp
57 | val size_49 = 49.dp
58 | val size_50 = 50.dp
59 | val size_51 = 51.dp
60 | val size_52 = 52.dp
61 | val size_53 = 53.dp
62 | val size_54 = 54.dp
63 | val size_55 = 55.dp
64 | val size_56 = 56.dp
65 | val size_57 = 57.dp
66 | val size_58 = 58.dp
67 | val size_59 = 59.dp
68 | val size_60 = 60.dp
69 | val size_61 = 61.dp
70 | val size_62 = 62.dp
71 | val size_63 = 63.dp
72 | val size_64 = 64.dp
73 | val size_65 = 65.dp
74 | val size_66 = 66.dp
75 | val size_67 = 67.dp
76 | val size_68 = 68.dp
77 | val size_69 = 69.dp
78 | val size_70 = 70.dp
79 | val size_71 = 71.dp
80 | val size_72 = 72.dp
81 | val size_73 = 73.dp
82 | val size_74 = 74.dp
83 | val size_75 = 75.dp
84 | val size_76 = 76.dp
85 | val size_77 = 77.dp
86 | val size_78 = 78.dp
87 | val size_79 = 79.dp
88 | val size_80 = 80.dp
89 | val size_81 = 81.dp
90 | val size_82 = 82.dp
91 | val size_83 = 83.dp
92 | val size_84 = 84.dp
93 | val size_85 = 85.dp
94 | val size_86 = 86.dp
95 | val size_87 = 87.dp
96 | val size_88 = 88.dp
97 | val size_89 = 89.dp
98 | val size_90 = 90.dp
99 | val size_91 = 91.dp
100 | val size_92 = 92.dp
101 | val size_93 = 93.dp
102 | val size_94 = 94.dp
103 | val size_95 = 95.dp
104 | val size_96 = 96.dp
105 | val size_97 = 97.dp
106 | val size_98 = 98.dp
107 | val size_99 = 99.dp
108 | val size_100 = 100.dp
109 | }
110 |
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/basic/BasicSpace.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.basic
2 |
3 | import androidx.compose.ui.unit.dp
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2025/3/31
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | object BasicSpace {
12 | val space_neg_8 = (-8).dp
13 | val space_neg_7 = (-7).dp
14 | val space_neg_6 = (-6).dp
15 | val space_neg_5 = (-5).dp
16 | val space_neg_4 = (-4).dp
17 | val space_neg_3 = (-3).dp
18 | val space_neg_2 = (-2).dp
19 | val space_neg_1 = (-1).dp
20 | val space_0 = 0.dp
21 | val space_1 = 1.dp
22 | val space_2 = 2.dp
23 | val space_3 = 3.dp
24 | val space_4 = 4.dp
25 | val space_5 = 5.dp
26 | val space_6 = 6.dp
27 | val space_7 = 7.dp
28 | val space_8 = 8.dp
29 | val space_9 = 9.dp
30 | val space_10 = 10.dp
31 | val space_11 = 11.dp
32 | val space_12 = 12.dp
33 | val space_13 = 13.dp
34 | val space_14 = 14.dp
35 | val space_15 = 15.dp
36 | val space_16 = 16.dp
37 | val space_17 = 17.dp
38 | val space_18 = 18.dp
39 | val space_19 = 19.dp
40 | val space_20 = 20.dp
41 | val space_21 = 21.dp
42 | val space_22 = 22.dp
43 | val space_23 = 23.dp
44 | val space_24 = 24.dp
45 | val space_25 = 25.dp
46 | val space_26 = 26.dp
47 | val space_27 = 27.dp
48 | val space_28 = 28.dp
49 | val space_29 = 29.dp
50 | val space_30 = 30.dp
51 | val space_31 = 31.dp
52 | val space_32 = 32.dp
53 | val space_33 = 33.dp
54 | val space_34 = 34.dp
55 | val space_35 = 35.dp
56 | val space_36 = 36.dp
57 | val space_37 = 37.dp
58 | val space_38 = 38.dp
59 | val space_39 = 39.dp
60 | val space_40 = 40.dp
61 | val space_41 = 41.dp
62 | val space_42 = 42.dp
63 | val space_43 = 43.dp
64 | val space_44 = 44.dp
65 | val space_45 = 45.dp
66 | val space_46 = 46.dp
67 | val space_47 = 47.dp
68 | val space_48 = 48.dp
69 | val space_49 = 49.dp
70 | val space_50 = 50.dp
71 | val space_51 = 51.dp
72 | val space_52 = 52.dp
73 | val space_53 = 53.dp
74 | val space_54 = 54.dp
75 | val space_55 = 55.dp
76 | val space_56 = 56.dp
77 | val space_57 = 57.dp
78 | val space_58 = 58.dp
79 | val space_59 = 59.dp
80 | val space_60 = 60.dp
81 | val space_61 = 61.dp
82 | val space_62 = 62.dp
83 | val space_63 = 63.dp
84 | val space_64 = 64.dp
85 | val space_65 = 65.dp
86 | val space_66 = 66.dp
87 | val space_67 = 67.dp
88 | val space_68 = 68.dp
89 | val space_69 = 69.dp
90 | val space_70 = 70.dp
91 | val space_71 = 71.dp
92 | val space_72 = 72.dp
93 | val space_73 = 73.dp
94 | val space_74 = 74.dp
95 | val space_75 = 75.dp
96 | val space_76 = 76.dp
97 | val space_77 = 77.dp
98 | val space_78 = 78.dp
99 | val space_79 = 79.dp
100 | val space_80 = 80.dp
101 | val space_81 = 81.dp
102 | val space_82 = 82.dp
103 | val space_83 = 83.dp
104 | val space_84 = 84.dp
105 | val space_85 = 85.dp
106 | val space_86 = 86.dp
107 | val space_87 = 87.dp
108 | val space_88 = 88.dp
109 | val space_89 = 89.dp
110 | val space_90 = 90.dp
111 | val space_91 = 91.dp
112 | val space_92 = 92.dp
113 | val space_93 = 93.dp
114 | val space_94 = 94.dp
115 | val space_95 = 95.dp
116 | val space_96 = 96.dp
117 | val space_97 = 97.dp
118 | val space_98 = 98.dp
119 | val space_99 = 99.dp
120 | val space_100 = 100.dp
121 | }
122 |
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ext/IntExt.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ext
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2022/5/5
6 | * mail:2726449200@qq.com
7 | * describe:
8 | */
9 | fun Int.floorMod(other: Int): Int = when (other) {
10 | 0 -> this
11 | else -> this - floorDiv(other) * other
12 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ext/ListExt.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ext
2 |
3 |
4 | /**
5 | * author :Peakmain
6 | * createTime:2025/3/11
7 | * mail:2726449200@qq.com
8 | * describe:List扩展类
9 | */
10 | /**
11 | * 获取List的大小
12 | * ①、如果List为null,则返回0。
13 | * ②、如果List不为null,则返回size
14 | */
15 | fun List?.orSize(): Int {
16 | return this?.size ?: return 0
17 | }
18 | /**
19 | * 判断List大小是否大于0
20 | * ①、如果List为null,则返回false。
21 | * ②、如果List不为null,则判断大小是否大于0
22 | */
23 | fun List?.sizeBigZero(): Boolean {
24 | return (this?.size ?: 0) > 0
25 | }
26 |
27 | /**
28 | * List的大小是否为0
29 | * ①、如果List为null,则返回true。
30 | * ②、如果List不为null,则判断大小是否等于0
31 | */
32 | fun List?.sizeEqualZero(): Boolean {
33 | return (this?.size ?: 0) == 0
34 | }
35 |
36 | /**
37 | * 返回此列表中指定[fromIndex](包含)和[toIndex](不包含)之间部分的视图
38 | */
39 | fun List?.slice(fromIndex: Int, toIndex: Int): List? {
40 | return if (this.orSize() > (toIndex-fromIndex)) this?.subList(fromIndex, toIndex) else this
41 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ext/StringExt.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ext
2 |
3 | import android.text.TextUtils
4 | import androidx.compose.runtime.Composable
5 |
6 | /**
7 | * author :Peakmain
8 | * createTime:2025/4/29
9 | * mail:2726449200@qq.com
10 | * describe:字符串工具类
11 | */
12 | fun String?.isEmpty(): Boolean {
13 | return TextUtils.isEmpty(this)
14 | }
15 | fun String?.isEmpty(block: () -> Unit): String? {
16 | if(isEmpty()){
17 | block.invoke()
18 | }
19 | return this
20 | }
21 | fun String?.isNotEmpty(): Boolean {
22 | return !isEmpty()
23 | }
24 |
25 | fun String?.isNotEmpty(block: ((String)) -> Unit): String? {
26 | if (isNotEmpty()) {
27 | block.invoke(this!!)
28 | }
29 | return this
30 | }
31 | @Composable
32 | fun String?.isNotEmptyComposable(block: @Composable ((String)) -> Unit): String? {
33 | if (isNotEmpty()) {
34 | block.invoke(this!!)
35 | }
36 | return this
37 | }
38 |
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/library/TopAppBar.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.library
2 |
3 | import android.graphics.Color.luminance
4 | import androidx.compose.foundation.background
5 | import androidx.compose.foundation.layout.*
6 | import androidx.compose.material.*
7 | import androidx.compose.material3.CenterAlignedTopAppBar
8 | import androidx.compose.runtime.Composable
9 | import androidx.compose.runtime.CompositionLocalProvider
10 | import androidx.compose.runtime.SideEffect
11 | import androidx.compose.ui.Modifier
12 | import androidx.compose.ui.graphics.Color
13 | import androidx.compose.ui.graphics.luminance
14 | import androidx.compose.ui.layout.layoutId
15 | import androidx.compose.ui.platform.LocalContext
16 | import androidx.compose.ui.platform.LocalDensity
17 | import androidx.compose.ui.unit.Dp
18 | import androidx.compose.ui.unit.dp
19 | import androidx.constraintlayout.compose.ConstraintLayout
20 | import androidx.constraintlayout.compose.ConstraintSet
21 | import com.google.accompanist.systemuicontroller.rememberSystemUiController
22 |
23 | /**
24 | * author :Peakmain
25 | * createTime:2022/5/4
26 | * mail:2726449200@qq.com
27 | * describe:
28 | */
29 |
30 | /**
31 | * @param title 标题
32 | * @param modifier Modifier,设置后会和已经设置好Modifier进行合并
33 | * @param navigationIcon 左边图标
34 | * @param backgroundColor 背景颜色
35 | * @param actions 右边图标
36 | * @param isImmersive 是否是沉浸式
37 | * @param darkIcons 状态栏的文字图标颜色是黑色还是白色,默认是false(白色)
38 | * @param content 内容区域
39 | */
40 | @Composable
41 | fun TopAppBarCenter(
42 | title: @Composable () -> Unit,
43 | modifier: Modifier = Modifier,
44 | navigationIcon: @Composable (() -> Unit)? = null,
45 | backgroundColor: Color = MaterialTheme.colors.primarySurface,
46 | actions: @Composable RowScope.() -> Unit = {},
47 | isImmersive: Boolean = false,
48 | darkIcons: Boolean = false,
49 | content: @Composable (PaddingValues) -> Unit,
50 | ) {
51 | val topAppBarHeight = 44.dp
52 | if (isImmersive) {
53 | val systemUiController = rememberSystemUiController()
54 | SideEffect {
55 | systemUiController.setSystemBarsColor(
56 | color = Color.Transparent,
57 | darkIcons = darkIcons
58 | )
59 | }
60 | }
61 |
62 | Scaffold(topBar = {
63 | val constraintSet = ConstraintSet {
64 | val titleRef = createRefFor("title")
65 | val navigationIconRef = createRefFor("navigationIcon")
66 | val actionsRef = createRefFor("actions")
67 | constrain(titleRef) {
68 | start.linkTo(parent.start)
69 | end.linkTo(parent.end)
70 | top.linkTo(parent.top)
71 | bottom.linkTo(parent.bottom)
72 | }
73 | constrain(navigationIconRef) {
74 | top.linkTo(parent.top)
75 | bottom.linkTo(parent.bottom)
76 | }
77 | constrain(actionsRef) {
78 | top.linkTo(parent.top)
79 | bottom.linkTo(parent.bottom)
80 | end.linkTo(parent.end)
81 | }
82 | }
83 | ConstraintLayout(constraintSet, modifier = Modifier
84 | .fillMaxWidth()
85 | .background(backgroundColor)
86 | .then(modifier.statusBarsPadding())
87 | .height(topAppBarHeight)
88 | ) {
89 | Box(
90 | Modifier
91 | .layoutId("title")
92 | .padding(horizontal = 4.dp)
93 | ) {
94 | ProvideTextStyle(value = MaterialTheme.typography.h6) {
95 | CompositionLocalProvider(
96 | LocalContentAlpha provides ContentAlpha.high,
97 | content = title
98 | )
99 | }
100 | }
101 | if (navigationIcon != null) {
102 | Box(modifier = Modifier
103 | .layoutId("navigationIcon")
104 | .padding(start = 4.dp)) {
105 | CompositionLocalProvider(
106 | LocalContentAlpha provides ContentAlpha.high,
107 | content = navigationIcon
108 | )
109 | }
110 | }
111 | Row(
112 | Modifier
113 | .layoutId("actions")
114 | .padding(end = 4.dp),
115 | content = actions
116 | )
117 | }
118 | }) {
119 | content(it)
120 | }
121 |
122 | }
123 |
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/space/PkSpacer.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.space
2 |
3 | import androidx.compose.foundation.layout.Spacer
4 | import androidx.compose.foundation.layout.fillMaxHeight
5 | import androidx.compose.foundation.layout.fillMaxWidth
6 | import androidx.compose.foundation.layout.height
7 | import androidx.compose.foundation.layout.width
8 | import androidx.compose.runtime.Composable
9 | import androidx.compose.ui.Modifier
10 | import androidx.compose.ui.unit.Dp
11 | import androidx.compose.ui.unit.dp
12 |
13 | /**
14 | * author :Peakmain
15 | * createTime:2025/6/23
16 | * mail:2726449200@qq.com
17 | * describe:
18 | */
19 | @Composable
20 | fun PkSpacer(
21 | modifier: Modifier = Modifier,
22 | width: Dp = 10.dp,
23 | height: Dp = 10.dp,
24 | isHorizontal: Boolean = true
25 | ) {
26 | if (isHorizontal) {
27 | return PkHorizontalSpacer(modifier, height)
28 | } else {
29 | PkVerticalSpacer(modifier, width)
30 | }
31 | }
32 |
33 | @Composable
34 | fun PkVerticalSpacer(modifier: Modifier = Modifier, width: Dp) {
35 | Spacer(modifier
36 | .width(width)
37 | .fillMaxHeight())
38 | }
39 |
40 | @Composable
41 | fun PkHorizontalSpacer(modifier: Modifier = Modifier, height: Dp) {
42 | Spacer(modifier
43 | .height(height)
44 | .fillMaxWidth())
45 | }
46 |
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/theme/PkColors.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.theme
2 |
3 | import androidx.compose.material.Colors
4 | import androidx.compose.runtime.staticCompositionLocalOf
5 | import androidx.compose.ui.graphics.Color
6 |
7 | /**
8 | * author :Peakmain
9 | * createTime:2025/4/10
10 | * mail:2726449200@qq.com
11 | * describe:
12 | */
13 | val color_FFFEFA=Color(0xFFFFFEFA)
14 | val error_A5534D= Color(0xFFA5534D)
15 |
16 | fun pkColors(
17 | primary: Color = Color(0xFF1F401B),
18 | primaryVariant: Color = Color(0xB21F401B),
19 | secondary: Color = Color(0xFFB59E6D),//辅色
20 | secondaryVariant: Color = Color(0xFFDDCC9E),
21 | background: Color = Color(0xFFF8F9F3),
22 | surface: Color = color_FFFEFA,
23 | error: Color =error_A5534D,
24 | onPrimary: Color = color_FFFEFA,
25 | onSecondary: Color = Color(0xFF666666),//次要按钮上的文字颜色
26 | onBackground: Color =Color(0xFF333333),//背景颜色上的字体颜色
27 | onSurface: Color = Color(0xFF333333),//卡片上文字颜色
28 | onError: Color = color_FFFEFA,//错误上的文字颜色
29 | ): Colors = Colors(
30 | primary,
31 | primaryVariant,
32 | secondary,
33 | secondaryVariant,
34 | background,
35 | surface,
36 | error,
37 | onPrimary,
38 | onSecondary,
39 | onBackground,
40 | onSurface,
41 | onError,
42 | true
43 | )
44 | internal val LocalPkColors = staticCompositionLocalOf { pkColors() }
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/theme/PkIndication.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.theme
2 |
3 | import androidx.compose.foundation.Indication
4 | import androidx.compose.foundation.IndicationInstance
5 | import androidx.compose.foundation.interaction.InteractionSource
6 | import androidx.compose.foundation.interaction.collectIsFocusedAsState
7 | import androidx.compose.foundation.interaction.collectIsHoveredAsState
8 | import androidx.compose.foundation.interaction.collectIsPressedAsState
9 | import androidx.compose.runtime.Composable
10 | import androidx.compose.runtime.State
11 | import androidx.compose.runtime.remember
12 | import androidx.compose.ui.graphics.Color
13 | import androidx.compose.ui.graphics.drawscope.ContentDrawScope
14 |
15 | /**
16 | * author :Peakmain
17 | * createTime:2025/4/22
18 | * mail:2726449200@qq.com
19 | * describe:
20 | */
21 | open class PkIndication(private val drawColor: Color = Color.Black.copy(0.3f)) : Indication {
22 |
23 | private class DefaultDebugIndicationInstance(
24 | private val isPressed: State,
25 | private val isHovered: State,
26 | private val isFocused: State,
27 | private val drawColor: Color,
28 | ) : IndicationInstance {
29 | override fun ContentDrawScope.drawIndication() {
30 | drawContent()
31 | if (isPressed.value) {
32 | drawRect(color = drawColor, size = size)
33 | } else if (isHovered.value || isFocused.value) {
34 | drawRect(color = drawColor, size = size)
35 | }
36 | }
37 | }
38 |
39 | @Composable
40 | override fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance {
41 | val isPressed = interactionSource.collectIsPressedAsState()
42 | val isHovered = interactionSource.collectIsHoveredAsState()
43 | val isFocused = interactionSource.collectIsFocusedAsState()
44 | return remember(interactionSource) {
45 | DefaultDebugIndicationInstance(isPressed, isHovered, isFocused, drawColor)
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/theme/PkTheme.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.theme
2 |
3 | import androidx.compose.material.Colors
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.runtime.ReadOnlyComposable
6 | import com.peakmain.compose.ui.button.LocalPkShapes
7 | import com.peakmain.compose.ui.button.PkShapes
8 |
9 | /**
10 | * author :Peakmain
11 | * createTime:2025/4/10
12 | * mail:2726449200@qq.com
13 | * describe:
14 | */
15 | object PkTheme {
16 | val colors: Colors
17 | @Composable
18 | @ReadOnlyComposable
19 | get() = LocalPkColors.current
20 |
21 | val shapes: PkShapes
22 | @Composable
23 | @ReadOnlyComposable
24 | get() = LocalPkShapes.current
25 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/theme/PkTranslateIndication.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.theme
2 |
3 | import androidx.compose.foundation.IndicationInstance
4 | import androidx.compose.foundation.interaction.InteractionSource
5 | import androidx.compose.foundation.interaction.collectIsFocusedAsState
6 | import androidx.compose.foundation.interaction.collectIsHoveredAsState
7 | import androidx.compose.foundation.interaction.collectIsPressedAsState
8 | import androidx.compose.runtime.Composable
9 | import androidx.compose.runtime.State
10 | import androidx.compose.runtime.remember
11 | import androidx.compose.ui.graphics.Color
12 | import androidx.compose.ui.graphics.drawscope.ContentDrawScope
13 |
14 | /**
15 | * author :Peakmain
16 | * createTime:2025/4/22
17 | * mail:2726449200@qq.com
18 | * describe:透明
19 | */
20 | object PkTranslateIndication : PkIndication() {
21 |
22 | private class DefaultDebugIndicationInstance(
23 | private val isPressed: State,
24 | private val isHovered: State,
25 | private val isFocused: State,
26 | ) : IndicationInstance {
27 | override fun ContentDrawScope.drawIndication() {
28 | drawContent()
29 | if (isPressed.value) {
30 | drawRect(color = Color.Transparent, size = size)
31 | } else if (isHovered.value || isFocused.value) {
32 | drawRect(color = Color.Transparent, size = size)
33 | }
34 | }
35 | }
36 |
37 | @Composable
38 | override fun rememberUpdatedInstance(interactionSource: InteractionSource): IndicationInstance {
39 | val isPressed = interactionSource.collectIsPressedAsState()
40 | val isHovered = interactionSource.collectIsHoveredAsState()
41 | val isFocused = interactionSource.collectIsFocusedAsState()
42 | return remember(interactionSource) {
43 | DefaultDebugIndicationInstance(isPressed, isHovered, isFocused)
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ui/PkGridLayout.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ui
2 |
3 | import androidx.annotation.IntRange
4 | import androidx.compose.foundation.layout.Arrangement
5 | import androidx.compose.foundation.layout.Box
6 | import androidx.compose.foundation.layout.Column
7 | import androidx.compose.foundation.layout.Row
8 | import androidx.compose.foundation.layout.Spacer
9 | import androidx.compose.material.TabRowDefaults.Divider
10 | import androidx.compose.runtime.Composable
11 | import androidx.compose.ui.Modifier
12 | import androidx.compose.ui.unit.Dp
13 | import androidx.compose.ui.unit.dp
14 |
15 | /**
16 | * author :Peakmain
17 | * createTime:2022/2/9
18 | * mail:2726449200@qq.com
19 | * describe:GridLayout的实现
20 | */
21 | /**
22 | * @param columns 1行几个
23 | * @param data 源数据
24 | * @param isShowHorizontalDivider 是否显示水平分割线,默认不显示
25 | * @param content The content of the GridLayout
26 | */
27 | @Composable
28 | fun PkGridLayout(
29 | @IntRange(from = 1) columns: Int,
30 | data: MutableList,
31 | isShowHorizontalDivider: Boolean = false,
32 | divider: @Composable (() -> Unit)? = null,
33 | columnSpacing: Dp = 12.dp, // 新增参数,表示列间距,默认值为 8.dp
34 | content: @Composable (Int, E) -> Unit
35 | ) {
36 | val size = data.size
37 | val rows = (size + columns - 1) / columns
38 | Column {
39 | for (rowIndex in 0 until rows) {
40 | Row(horizontalArrangement = Arrangement.spacedBy(columnSpacing)) {
41 | for (columnIndex in 0 until columns) {
42 | val itemIndex = rowIndex * columns + columnIndex
43 | if (itemIndex < size) {
44 | Box(Modifier.weight(1f)) {
45 | content(itemIndex, data[itemIndex])
46 | }
47 | } else {
48 | Spacer(
49 | Modifier
50 | .weight(1f)
51 | )
52 | }
53 | }
54 | }
55 | if (isShowHorizontalDivider && rowIndex < (rows - 1)) {
56 | if (divider != null) {
57 | divider()
58 | } else {
59 | Divider(thickness = 0.5.dp)
60 | }
61 | }
62 | }
63 | }
64 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ui/basic/PkColumn.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ui.basic
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2025/6/4
6 | * mail:2726449200@qq.com
7 | * describe:
8 | */
9 | import androidx.compose.foundation.background
10 | import androidx.compose.foundation.layout.Arrangement
11 | import androidx.compose.foundation.layout.Column
12 | import androidx.compose.foundation.layout.ColumnScope
13 | import androidx.compose.runtime.Composable
14 | import androidx.compose.ui.Alignment
15 | import androidx.compose.ui.Modifier
16 | import androidx.compose.ui.graphics.Color
17 | import androidx.compose.ui.tooling.preview.Preview
18 |
19 | @Composable
20 | inline fun PkColumn(
21 | modifier: Modifier = Modifier,
22 | backgroundColor: Color = Color.White,
23 | verticalArrangement: Arrangement.Vertical = Arrangement.Top,
24 | horizontalAlignment: Alignment.Horizontal = Alignment.Start,
25 | content: @Composable ColumnScope.() -> Unit
26 | ) {
27 | Column(
28 | modifier
29 | .background(backgroundColor),
30 | verticalArrangement,
31 | horizontalAlignment,
32 | content
33 | )
34 | }
35 |
36 | @Preview
37 | @Composable
38 | fun PkColumnPreview() {
39 | PkColumn() {
40 |
41 | }
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ui/button/PkButton.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ui.button
2 |
3 | import androidx.compose.foundation.BorderStroke
4 | import androidx.compose.foundation.interaction.MutableInteractionSource
5 | import androidx.compose.foundation.layout.PaddingValues
6 | import androidx.compose.foundation.layout.RowScope
7 | import androidx.compose.material.Button
8 | import androidx.compose.material.ButtonColors
9 | import androidx.compose.material.ButtonDefaults
10 | import androidx.compose.material.ButtonElevation
11 | import androidx.compose.runtime.Composable
12 | import androidx.compose.runtime.remember
13 | import androidx.compose.ui.Modifier
14 | import androidx.compose.ui.graphics.Shape
15 | import com.peakmain.compose.theme.PkTheme
16 |
17 | /**
18 | * author :Peakmain
19 | * createTime:2025/4/10
20 | * mail:2726449200@qq.com
21 | * describe:
22 | */
23 | /**
24 | * 通用按钮组件,支持自定义样式、交互行为与内容布局。
25 | *
26 | * @param onClick 按钮点击事件回调(必填)
27 | * @param modifier 布局修饰符(如尺寸、边距、背景等),默认 [Modifier]
28 | * @param enabled 是否启用按钮,默认 true;禁用时自动降低透明度并屏蔽点击事件
29 | * @param interactionSource 按钮交互状态源(如按压、悬停),默认 `remember { MutableInteractionSource() }`
30 | * @param elevation 按钮阴影效果,默认 [ButtonDefaults.elevation];设置为 null 可移除阴影
31 | * @param shape 按钮形状,默认 [PkTheme.shapes.small],如 `RoundedCornerShape(4.dp)`
32 | * @param border 按钮边框,默认 null,如 `BorderStroke(1.dp, Color.Gray)`
33 | * @param colors 按钮颜色配置,默认 [PkButtonDefault.buttonColors],包含默认、禁用、按压等状态颜色
34 | * @param contentPadding 内容内边距,默认 [PkButtonDefault.BigContentPadding],即 `PaddingValues(horizontal = 16.dp, vertical = 8.dp)`
35 | * @param content 按钮内部内容(必填),支持 [RowScope],可自由组合文本、图标等
36 | */
37 | @Composable
38 | fun PkButton(
39 | onClick: () -> Unit,
40 | modifier: Modifier = Modifier,
41 | enabled: Boolean = true,
42 | interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
43 | elevation: ButtonElevation? = ButtonDefaults.elevation(),
44 | shape: Shape = PkTheme.shapes.small,
45 | border: BorderStroke? = null,
46 | colors: ButtonColors = PkButtonDefault.buttonColors(interactionSource),
47 | contentPadding: PaddingValues = PkButtonDefault.BigContentPadding,
48 | content: @Composable RowScope.() -> Unit
49 | ) {
50 | Button(
51 | onClick,
52 | modifier,
53 | enabled,
54 | interactionSource,
55 | elevation,
56 | shape,
57 | border,
58 | colors,
59 | contentPadding,
60 | ) {
61 | content()
62 | }
63 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ui/button/PkButtonDefault.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ui.button
2 |
3 | import androidx.compose.foundation.interaction.InteractionSource
4 | import androidx.compose.foundation.interaction.MutableInteractionSource
5 | import androidx.compose.foundation.interaction.collectIsPressedAsState
6 | import androidx.compose.foundation.layout.PaddingValues
7 | import androidx.compose.material.Button
8 | import androidx.compose.material.ButtonColors
9 | import androidx.compose.material.SnackbarDefaults.backgroundColor
10 | import androidx.compose.material.contentColorFor
11 | import androidx.compose.runtime.Composable
12 | import androidx.compose.runtime.Immutable
13 | import androidx.compose.runtime.State
14 | import androidx.compose.runtime.getValue
15 | import androidx.compose.runtime.remember
16 | import androidx.compose.runtime.rememberUpdatedState
17 | import androidx.compose.ui.graphics.Color
18 | import androidx.compose.ui.unit.dp
19 | import com.peakmain.compose.theme.PkTheme
20 |
21 | /**
22 | * author :Peakmain
23 | * createTime:2025/4/10
24 | * mail:2726449200@qq.com
25 | * describe:
26 | */
27 | object PkButtonDefault {
28 | private val ButtonBigHorizontalPadding = 24.dp
29 | private val ButtonBigVerticalPadding = 11.dp
30 |
31 | private val ButtonSmallHorizontalPadding = 12.dp
32 | private val ButtonSmallVerticalPadding = 5.dp
33 |
34 | /**
35 | * The default content padding used by [Button]
36 | */
37 | val BigContentPadding = PaddingValues(
38 | start = ButtonBigHorizontalPadding,
39 | top = ButtonBigVerticalPadding,
40 | end = ButtonBigHorizontalPadding,
41 | bottom = ButtonBigVerticalPadding
42 | )
43 |
44 | val smallContentPadding = PaddingValues(
45 | start = ButtonSmallHorizontalPadding,
46 | top = ButtonSmallVerticalPadding,
47 | end = ButtonSmallHorizontalPadding,
48 | bottom = ButtonSmallVerticalPadding
49 | )
50 |
51 | /**
52 | * 默认
53 | */
54 | @Composable
55 | fun buttonColors(
56 | interactionSource: InteractionSource = remember { MutableInteractionSource() },
57 | backgroundColor: Color = PkTheme.colors.primary,
58 | contentColor: Color = PkTheme.colors.contentColorFor(backgroundColor),
59 | disabledBackgroundColor: Color = Color(0xFFD4D4D5),
60 | disabledContentColor: Color = PkTheme.colors.onPrimary,
61 | pressedBackgroundColor: Color = backgroundColor,
62 | pressedContentColor: Color = contentColor
63 | ): ButtonColors = PkButtonColors(
64 | backgroundColor = backgroundColor,
65 | contentColor = contentColor,
66 | disabledBackgroundColor = disabledBackgroundColor,
67 | disabledContentColor = disabledContentColor,
68 | interactionSource = interactionSource,
69 | pressedBackgroundColor = pressedBackgroundColor,
70 | pressedContentColor = pressedContentColor
71 | )
72 |
73 | /**
74 | * 幽灵按钮
75 | */
76 | @Composable
77 | fun transparentColor(
78 | interactionSource: InteractionSource = remember { MutableInteractionSource() },
79 | backgroundColor: Color = Color.Transparent,
80 | contentColor: Color = Color(0xFF1F4D1B),
81 | disabledBackgroundColor: Color = Color(0xFFD4D4D5),
82 | disabledContentColor: Color = Color(0xFF677C64),
83 | pressedBackgroundColor: Color = backgroundColor,
84 | pressedContentColor: Color = contentColor
85 | ): ButtonColors = PkButtonColors(
86 | backgroundColor = backgroundColor,
87 | contentColor = contentColor,
88 | disabledBackgroundColor = disabledBackgroundColor,
89 | disabledContentColor = disabledContentColor,
90 | interactionSource = interactionSource,
91 | pressedBackgroundColor = pressedBackgroundColor,
92 | pressedContentColor = pressedContentColor
93 | )
94 |
95 | }
96 |
97 | @Immutable
98 | class PkButtonColors(
99 | private val backgroundColor: Color,
100 | private val contentColor: Color,
101 | private val pressedContentColor: Color = contentColor,
102 | private val disabledBackgroundColor: Color,
103 | private val disabledContentColor: Color,
104 | private val interactionSource: InteractionSource,
105 | private val pressedBackgroundColor: Color = backgroundColor.copy(0.8f),
106 | ) : ButtonColors {
107 | @Composable
108 | override fun backgroundColor(enabled: Boolean): State {
109 | val isPressed by interactionSource.collectIsPressedAsState()
110 | val color = when {
111 | !enabled -> disabledBackgroundColor
112 | isPressed -> pressedBackgroundColor
113 | else -> backgroundColor
114 | }
115 | return rememberUpdatedState(color)
116 | }
117 |
118 | @Composable
119 | override fun contentColor(enabled: Boolean): State {
120 | val isPressed by interactionSource.collectIsPressedAsState()
121 | val color = when {
122 | !enabled -> disabledContentColor
123 | isPressed -> pressedContentColor
124 | else -> contentColor
125 | }
126 | return rememberUpdatedState(color)
127 | }
128 |
129 | override fun equals(other: Any?): Boolean {
130 | if (this === other) return true
131 | if (other !is PkButtonColors) return false
132 |
133 | return backgroundColor == other.backgroundColor &&
134 | pressedBackgroundColor == other.pressedBackgroundColor &&
135 | contentColor == other.contentColor &&
136 | pressedContentColor == other.pressedContentColor &&
137 | disabledBackgroundColor == other.disabledBackgroundColor &&
138 | disabledContentColor == other.disabledContentColor
139 | }
140 |
141 | override fun hashCode(): Int {
142 | var result = backgroundColor.hashCode()
143 | result = 31 * result + pressedBackgroundColor.hashCode()
144 | result = 31 * result + contentColor.hashCode()
145 | result = 31 * result + pressedContentColor.hashCode()
146 | result = 31 * result + disabledBackgroundColor.hashCode()
147 | result = 31 * result + disabledContentColor.hashCode()
148 | return result
149 | }
150 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ui/button/PkShapes.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ui.button
2 |
3 | import androidx.compose.foundation.shape.CornerBasedShape
4 | import androidx.compose.foundation.shape.RoundedCornerShape
5 | import androidx.compose.material.Shapes
6 | import androidx.compose.runtime.Immutable
7 | import androidx.compose.runtime.staticCompositionLocalOf
8 | import androidx.compose.ui.unit.dp
9 |
10 | /**
11 | * author :Peakmain
12 | * createTime:2025/4/10
13 | * mail:2726449200@qq.com
14 | * describe:
15 | */
16 |
17 | @Immutable
18 | class PkShapes(
19 | val none: CornerBasedShape = RoundedCornerShape(0.dp),
20 | val small: CornerBasedShape = RoundedCornerShape(2.dp),
21 | val medium: CornerBasedShape = RoundedCornerShape(4.dp),
22 | val large: CornerBasedShape = RoundedCornerShape(8.dp),
23 | val extraLarge: CornerBasedShape = RoundedCornerShape(12.dp),
24 | val capsule: CornerBasedShape = RoundedCornerShape(percent = 50), // 胶囊型
25 | val circle: CornerBasedShape = RoundedCornerShape(percent = 50) // 圆形,默认是等宽等高的控件,圆形的效果
26 | ) {
27 |
28 | fun copy(
29 | none: CornerBasedShape = this.none,
30 | small: CornerBasedShape = this.small,
31 | medium: CornerBasedShape = this.medium,
32 | large: CornerBasedShape = this.large,
33 | extraLarge: CornerBasedShape = this.extraLarge,
34 | capsule: CornerBasedShape = this.capsule,
35 | circle: CornerBasedShape = this.circle
36 | ): PkShapes = PkShapes(
37 | none = none,
38 | small = small,
39 | medium = medium,
40 | large = large,
41 | extraLarge = extraLarge,
42 | capsule = capsule,
43 | circle = circle
44 | )
45 |
46 | override fun equals(other: Any?): Boolean {
47 | if (this === other) return true
48 | if (other !is PkShapes) return false
49 |
50 | if (none != other.none) return false
51 | if (small != other.small) return false
52 | if (medium != other.medium) return false
53 | if (large != other.large) return false
54 | if (extraLarge != other.extraLarge) return false
55 | if (capsule != other.capsule) return false
56 | if (circle != other.circle) return false
57 |
58 | return true
59 | }
60 |
61 | override fun hashCode(): Int {
62 | var result = none.hashCode()
63 | result = 31 * result + small.hashCode()
64 | result = 31 * result + medium.hashCode()
65 | result = 31 * result + large.hashCode()
66 | result = 31 * result + extraLarge.hashCode()
67 | result = 31 * result + capsule.hashCode()
68 | result = 31 * result + circle.hashCode()
69 | return result
70 | }
71 |
72 | override fun toString(): String {
73 | return "PkShapes(none=$none, small=$small, medium=$medium, large=$large, extraLarge=$extraLarge, capsule=$capsule, circle=$circle)"
74 | }
75 | }
76 |
77 | internal val LocalPkShapes = staticCompositionLocalOf { PkShapes() }
78 |
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ui/cell/PkCell.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ui.cell
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2025/4/17
6 | * mail:2726449200@qq.com
7 | * describe:单元格
8 | */
9 | import android.text.TextUtils
10 | import androidx.annotation.DrawableRes
11 | import androidx.compose.animation.core.LinearEasing
12 | import androidx.compose.animation.core.animateFloatAsState
13 | import androidx.compose.animation.core.tween
14 | import androidx.compose.foundation.Image
15 | import androidx.compose.foundation.background
16 | import androidx.compose.foundation.clickable
17 | import androidx.compose.foundation.layout.Arrangement
18 | import androidx.compose.foundation.layout.Column
19 | import androidx.compose.foundation.layout.IntrinsicSize
20 | import androidx.compose.foundation.layout.Row
21 | import androidx.compose.foundation.layout.RowScope
22 | import androidx.compose.foundation.layout.fillMaxHeight
23 | import androidx.compose.foundation.layout.fillMaxSize
24 | import androidx.compose.foundation.layout.fillMaxWidth
25 | import androidx.compose.foundation.layout.height
26 | import androidx.compose.foundation.layout.padding
27 | import androidx.compose.foundation.layout.size
28 | import androidx.compose.material3.LocalTextStyle
29 | import androidx.compose.material3.Text
30 | import androidx.compose.runtime.Composable
31 | import androidx.compose.runtime.getValue
32 | import androidx.compose.runtime.mutableStateOf
33 | import androidx.compose.runtime.remember
34 | import androidx.compose.runtime.setValue
35 | import androidx.compose.ui.Alignment
36 | import androidx.compose.ui.Modifier
37 | import androidx.compose.ui.draw.rotate
38 | import androidx.compose.ui.graphics.Color
39 | import androidx.compose.ui.graphics.ColorFilter
40 | import androidx.compose.ui.res.painterResource
41 | import androidx.compose.ui.text.TextStyle
42 | import androidx.compose.ui.text.font.FontStyle
43 | import androidx.compose.ui.text.style.TextAlign
44 | import androidx.compose.ui.text.style.TextOverflow
45 | import androidx.compose.ui.tooling.preview.Preview
46 | import androidx.compose.ui.unit.Dp
47 | import androidx.compose.ui.unit.TextUnit
48 | import androidx.compose.ui.unit.dp
49 | import androidx.compose.ui.unit.sp
50 | import com.peakmain.compose.basic.BasicFont
51 | import com.peakmain.compose.basic.BasicSize
52 | import com.peakmain.compose.library.R
53 | import com.peakmain.compose.ui.title.PkTitle
54 | import com.peakmain.compose.ui.title.PkTitleType
55 |
56 | /**
57 | * 通用可自定义右侧内容的标题组件。
58 | *
59 | * @param text 左侧显示的文本内容(必填)
60 | * @param type 标题样式类型(字体大小、字重等),默认 [PkTitleType.BigTitle1],详见 PkTitleType 文档
61 | * @param modifier 布局修饰符(如尺寸、边距等),作用于整个单元格容器,默认 [Modifier]
62 | * @param color 文本颜色,默认 Color(0xFF333333)
63 | * @param fontStyle 字体风格,如 [FontStyle.Italic],默认 null
64 | * @param textAlign 文本对齐方式,如 [TextAlign.End](右对齐),默认 null(跟随系统)
65 | * @param overflow 文本溢出处理方式,默认 [TextOverflow.Ellipsis]
66 | * @param maxLines 文本最大显示行数,默认 1
67 | * @param style 自定义文本样式,可覆盖 [type] 中的部分属性,默认 [LocalTextStyle.current]
68 | * @param rightContent 右侧自定义内容(必填),支持任意组合(图标、开关等),通过 [RowScope] 提供灵活布局能力
69 | */
70 | @Composable
71 | fun PkCell(
72 | text: String,
73 | type: PkTitleType = PkTitleType.BigTitle1(),
74 | modifier: Modifier = Modifier,
75 | color: Color = Color(0xFF333333),
76 | fontStyle: FontStyle? = null,
77 | textAlign: TextAlign? = null,
78 | overflow: TextOverflow = TextOverflow.Ellipsis,
79 | maxLines: Int = 1,
80 | style: TextStyle = LocalTextStyle.current,
81 | rightContent: @Composable RowScope.() -> Unit
82 | ) {
83 | Row(
84 | modifier
85 | .height(IntrinsicSize.Min)
86 | .fillMaxWidth(),
87 | horizontalArrangement = Arrangement.SpaceBetween,
88 | verticalAlignment = Alignment.CenterVertically
89 | ) {
90 | PkTitle(text, type, Modifier, color, fontStyle, textAlign, overflow, maxLines, style)
91 | Row(
92 | verticalAlignment = Alignment.CenterVertically,) {
93 | rightContent.invoke(this)
94 | }
95 | }
96 | }
97 |
98 | /**
99 | * 通用标题组件
100 | *
101 | * @param text 左侧主标题文本内容(必填)
102 | * @param type 标题样式类型(字体大小、字重),默认 [PkTitleType.BigTitle1],参考 PkTitleType 文档
103 | * @param modifier 整体容器修饰符(如边距、背景等),默认 [Modifier]
104 | * @param color 左侧标题文本颜色,默认 Color(0xFF333333)
105 | * @param fontStyle 字体风格,如 [FontStyle.Italic],默认 null
106 | * @param textAlign 文本对齐方式,默认 null(跟随系统)
107 | * @param overflow 文本溢出处理方式,默认 [TextOverflow.Ellipsis]
108 | * @param maxLines 文本最大显示行数,默认 1
109 | * @param style 自定义文本样式(覆盖 [type] 属性),默认 [LocalTextStyle.current]
110 | * @param rightText 右侧辅助文本内容(空字符串时不显示),默认 ""
111 | * @param rightTextColor 右侧辅助文本颜色,默认 Color(0xFF666666)
112 | * @param rightTextSize 右侧辅助文本字体大小,默认 12.sp
113 | * @param rightIcon 右侧图标资源 ID(设为 null 时不显示图标),默认 R.drawable.ic_right_arrow
114 | * @param rightIconSize 右侧图标尺寸,默认 12.dp
115 | * @param isRightIconRotated 是否启用图标旋转动画(用于展开/收起状态指示),默认 false
116 | * @param rightClick 点击右侧区域的回调(触发动画和自定义逻辑),默认 null
117 | */
118 |
119 | @Composable
120 | fun PkCell(
121 | text: String,
122 | type: PkTitleType = PkTitleType.BigTitle1(),
123 | modifier: Modifier = Modifier,
124 | color: Color = Color(0xFF333333),
125 | fontStyle: FontStyle? = null,
126 | textAlign: TextAlign? = null,
127 | overflow: TextOverflow = TextOverflow.Ellipsis,
128 | maxLines: Int = 1,
129 | style: TextStyle = LocalTextStyle.current,
130 | rightText: String = "",
131 | rightTextColor: Color = Color(0xFF666666),
132 | rightTextSize: TextUnit = BasicFont.font_12,
133 | @DrawableRes rightIcon: Int? = R.drawable.ic_right_arrow,
134 | rightIconSize: Dp = BasicSize.size_12,
135 | isRightIconRotated: Boolean = false,
136 | rightClick: (() -> Unit)? = null
137 | ) {
138 | var isRotated by remember { mutableStateOf(false) }
139 | // 创建一个浮动动画状态,从 0f 度旋转到 360f 度
140 | val rotation by animateFloatAsState(
141 | targetValue = if (isRotated) 180f else 0f,
142 | animationSpec = tween(
143 | durationMillis = 1000,
144 | easing = LinearEasing
145 | )
146 | )
147 | Row(
148 | modifier
149 | .height(IntrinsicSize.Min)
150 | .fillMaxWidth(),
151 | horizontalArrangement = Arrangement.SpaceBetween,
152 | verticalAlignment = Alignment.CenterVertically
153 | ) {
154 | PkTitle(text, type, Modifier, color, fontStyle, textAlign, overflow, maxLines, style)
155 | Row(verticalAlignment = Alignment.CenterVertically,
156 | modifier = Modifier
157 | .clickable {
158 | isRotated = !isRotated
159 | rightClick?.invoke()
160 | }
161 | .padding(start = BasicSize.size_25)
162 | .fillMaxHeight()
163 | ) {
164 | if (!TextUtils.isEmpty(rightText)) {
165 | Text(rightText, color = rightTextColor, fontSize = rightTextSize)
166 | }
167 | rightIcon?.let {
168 | Image(
169 | painter = painterResource(it),
170 | contentDescription = null,
171 | colorFilter = ColorFilter.tint(rightTextColor),
172 | modifier = Modifier
173 | .size(rightIconSize)
174 | .rotate(if (isRightIconRotated) rotation else 0f)
175 | )
176 | }
177 | }
178 | }
179 | }
180 |
181 | @Preview
182 | @Composable
183 | fun PkCellPreview() {
184 | Column(
185 | Modifier
186 | .background(Color.White)
187 | .fillMaxSize()
188 | ) {
189 | PkCell(
190 | "常用功能",
191 | PkTitleType.BigTitle3(),
192 | rightText = "展开",
193 | modifier = Modifier.padding(horizontal = 18.dp),
194 | color = Color(0xFF14401B)
195 | )
196 | }
197 |
198 |
199 | }
200 |
201 |
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ui/divier/PkDashDivider.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ui.divier
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2025/3/6
6 | * mail:2726449200@qq.com
7 | * describe:
8 | */
9 | import androidx.compose.foundation.layout.fillMaxWidth
10 | import androidx.compose.foundation.layout.height
11 | import androidx.compose.foundation.layout.width
12 | import androidx.compose.runtime.Composable
13 | import androidx.compose.ui.Modifier
14 | import androidx.compose.ui.geometry.Offset
15 | import androidx.compose.ui.graphics.Color
16 | import androidx.compose.ui.graphics.PathEffect
17 | import androidx.compose.ui.graphics.drawscope.Stroke
18 | import androidx.compose.ui.tooling.preview.Preview
19 | import androidx.compose.ui.unit.Dp
20 | import androidx.compose.ui.unit.dp
21 |
22 | /**
23 | * 虚线分隔线(支持水平/垂直)
24 | *
25 | * @param modifier 用于添加额外修饰符的 Modifier。
26 | * @param color 虚线的颜色,默认为 0x67272A2B。
27 | * @param height 分割线的高度,垂直方向生效
28 | * @param strokeWidth 虚线的宽度,默认为 0.5.dp。
29 | * @param dashLength 虚线的长度,默认为 2.dp。
30 | * @param gapLength 虚线之间的间隔长度,默认为 2.dp。
31 | * @param isHorizontal 水平分割线(true)/垂直分割线(false),默认是false
32 | */
33 | @Composable
34 | fun PkDashDivider(
35 | modifier: Modifier = Modifier,
36 | color: Color = Color(0x67272A2B),
37 | height:Dp=28.dp,
38 | strokeWidth: Dp = 0.5.dp,
39 | dashLength: Dp = 2.dp,
40 | gapLength: Dp = 2.dp,
41 | isHorizontal: Boolean = false,
42 | ) {
43 | val newModifier = if (isHorizontal) modifier
44 | .fillMaxWidth()
45 | .height(strokeWidth) else modifier
46 | .height(height)
47 | .width(strokeWidth)
48 | androidx.compose.foundation.Canvas(
49 | newModifier
50 | ) {
51 | val stroke = Stroke(
52 | width = strokeWidth.toPx(),
53 | pathEffect = PathEffect.dashPathEffect(
54 | intervals = floatArrayOf(dashLength.toPx(), gapLength.toPx())
55 | )
56 | )
57 | drawLine(
58 | color = color,
59 | start = Offset(0f, 0f),
60 | end = Offset(size.width, size.height),
61 | strokeWidth = stroke.width,
62 | pathEffect = stroke.pathEffect
63 | )
64 | }
65 |
66 | }
67 |
68 | @Preview
69 | @Composable
70 | fun DashDividerPreview() {
71 | PkDashDivider()
72 | }
73 |
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ui/divier/PkDivider.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ui.divier
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2025/3/15
6 | * mail:2726449200@qq.com
7 | * describe:分割线
8 | */
9 | import androidx.compose.runtime.Composable
10 | import androidx.compose.ui.Modifier
11 | import androidx.compose.ui.graphics.Color
12 | import androidx.compose.ui.tooling.preview.Preview
13 | import androidx.compose.ui.unit.Dp
14 | import androidx.compose.ui.unit.dp
15 |
16 | /**
17 | * 根据 isDash 参数绘制虚线或完整的分隔线。
18 | *
19 | * @param modifier 用于添加额外修饰符的 Modifier。
20 | * @param color 分隔线的颜色,默认为 0xFFF1EFE9。
21 | * @param height 分隔线的高度,仅在垂直分隔线时生效,默认为 28.dp。
22 | * @param thickness 分隔线的厚度,仅在非虚线时生效,默认为 1.dp。
23 | * @param startIndent 分隔线的起始缩进,仅在非虚线时生效,默认为 0.dp。
24 | * @param isHorizontal 是否为水平分隔线,默认为 false。
25 | * @param isDash 是否绘制虚线分隔线,默认为 false。
26 | * @param strokeWidth 虚线的宽度,仅在绘制虚线时生效,默认为 0.5.dp。
27 | * @param dashLength 虚线的线段长度,仅在绘制虚线时生效,默认为 2.dp。
28 | * @param gapLength 虚线的间隔长度,仅在绘制虚线时生效,默认为 2.dp。
29 | */
30 | @Composable
31 | fun PkDivider(
32 | modifier: Modifier = Modifier,
33 | color: Color = Color(0xFFF1EFE9),
34 | height: Dp = 28.dp,
35 | thickness: Dp = 1.dp,
36 | startIndent: Dp = 0.dp,
37 | isHorizontal: Boolean = false,
38 | isDash: Boolean = false,
39 | strokeWidth: Dp = 0.5.dp,
40 | dashLength: Dp = 2.dp,
41 | gapLength: Dp = 2.dp,
42 | ) {
43 | if (isDash) {
44 | PkDashDivider(
45 | modifier = modifier,
46 | color = color,
47 | height=height,
48 | strokeWidth = strokeWidth,
49 | dashLength = dashLength,
50 | gapLength = gapLength,
51 | isHorizontal = isHorizontal
52 | )
53 | } else {
54 | PkFullDivider(
55 | modifier = modifier,
56 | color = color,
57 | height = height,
58 | thickness = thickness,
59 | startIndent = startIndent,
60 | isHorizontal = isHorizontal
61 | )
62 | }
63 | }
64 |
65 | @Preview
66 | @Composable
67 | fun PkDividerPreview() {
68 | PkDivider()
69 | }
70 |
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ui/divier/PkFullDivider.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ui.divier
2 |
3 | import androidx.compose.foundation.background
4 | import androidx.compose.foundation.layout.Box
5 | import androidx.compose.foundation.layout.fillMaxWidth
6 | import androidx.compose.foundation.layout.height
7 | import androidx.compose.foundation.layout.padding
8 | import androidx.compose.foundation.layout.width
9 | import androidx.compose.runtime.Composable
10 | import androidx.compose.ui.Modifier
11 | import androidx.compose.ui.graphics.Color
12 | import androidx.compose.ui.platform.LocalDensity
13 | import androidx.compose.ui.unit.Dp
14 | import androidx.compose.ui.unit.dp
15 |
16 | /**
17 | * author :Peakmain
18 | * createTime:2025/3/7
19 | * mail:2726449200@qq.com
20 | * describe:垂直分割线
21 | */
22 |
23 |
24 | /**
25 | * 创建一个实线分隔线组件。
26 | *
27 | * @param modifier 用于添加额外修饰符的 Modifier。
28 | * @param color 分隔线的颜色,默认为 0xFFF1EFE9。
29 | * @param height 分隔线的高度,默认为 28.dp。
30 | * @param thickness 分隔线的厚度,默认为 1.dp。
31 | * @param startIndent 分隔线的起始缩进,默认为 0.dp。
32 | * @param isHorizontal 水平分割线(true)/垂直分割线(false),默认是false
33 | */
34 | @Composable
35 | fun PkFullDivider(
36 | modifier: Modifier = Modifier,
37 | color: Color = Color(0xFFF1EFE9),
38 | height:Dp=28.dp,
39 | thickness: Dp = 1.dp,
40 | startIndent: Dp = 0.dp,
41 | isHorizontal: Boolean=false
42 | ) {
43 | val indentMod = if (startIndent.value != 0f) {
44 | Modifier.padding(start = startIndent)
45 | } else {
46 | Modifier
47 | }
48 | val targetThickness = if (thickness == Dp.Hairline) {
49 | (1f / LocalDensity.current.density).dp
50 | } else {
51 | thickness
52 | }
53 | if(isHorizontal){
54 | Box(
55 | modifier.then(indentMod)
56 | .fillMaxWidth()
57 | .height(targetThickness)
58 | .background(color = color)
59 | )
60 | }else{
61 | Box(
62 | modifier.then(indentMod)
63 | .height(height)
64 | .width(targetThickness)
65 | .background(color = color)
66 | )
67 | }
68 |
69 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ui/flow/PkFlowRow.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ui.flow
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2025/3/20
6 | * mail:2726449200@qq.com
7 | * describe:限制行数的FlowRow
8 | */
9 | import androidx.compose.foundation.background
10 | import androidx.compose.foundation.layout.Arrangement
11 | import androidx.compose.foundation.layout.ExperimentalLayoutApi
12 | import androidx.compose.foundation.layout.FlowRow
13 | import androidx.compose.foundation.layout.fillMaxWidth
14 | import androidx.compose.foundation.layout.heightIn
15 | import androidx.compose.foundation.layout.padding
16 | import androidx.compose.foundation.shape.RoundedCornerShape
17 | import androidx.compose.material.Text
18 | import androidx.compose.runtime.Composable
19 | import androidx.compose.runtime.LaunchedEffect
20 | import androidx.compose.runtime.getValue
21 | import androidx.compose.runtime.mutableStateOf
22 | import androidx.compose.runtime.remember
23 | import androidx.compose.runtime.setValue
24 | import androidx.compose.ui.Alignment
25 | import androidx.compose.ui.Modifier
26 | import androidx.compose.ui.draw.clipToBounds
27 | import androidx.compose.ui.graphics.Color
28 | import androidx.compose.ui.layout.SubcomposeLayout
29 | import androidx.compose.ui.platform.LocalDensity
30 | import androidx.compose.ui.text.style.TextOverflow
31 | import androidx.compose.ui.tooling.preview.Preview
32 | import androidx.compose.ui.unit.Dp
33 | import androidx.compose.ui.unit.dp
34 | import androidx.compose.ui.unit.max
35 |
36 | @OptIn(ExperimentalLayoutApi::class)
37 | @Composable
38 | fun PkFlowRow(
39 | modifier: Modifier = Modifier, // 布局修饰符
40 | horizontalSpacing: Dp = 0.dp, // 子项水平间距
41 | verticalSpacing: Dp = 0.dp, // 行间垂直间距
42 | maxLine: Int = 2, // 最大显示行数
43 | onLineCountChanged: ((Int) -> Unit)? = null, // 行数变化回调
44 | content: @Composable () -> Unit // 子组件内容
45 | ) {
46 | val density = LocalDensity.current
47 | //当前行数的状态
48 | var lineCountState by remember { mutableStateOf(0) }
49 |
50 | //生命周期感知调用
51 | LaunchedEffect(lineCountState) {
52 | onLineCountChanged?.invoke(lineCountState)
53 | }
54 | SubcomposeLayout { constraints ->
55 | //测量所有的子View的测量数据
56 | val measurables = subcompose("measure", content)
57 | val hSpacingPx = with(density) { horizontalSpacing.roundToPx() }
58 | val vSpacingPx = with(density) { verticalSpacing.roundToPx() }
59 | //获取到所有测量结果
60 | val placeables =
61 | measurables.map { it.measure(constraints = constraints.copy(minWidth = 0)) }
62 | var currentLine = 0
63 | var currentRowWidth = 0
64 | var totalHeight = 0
65 | var currentRowHeight = 0
66 | placeables.forEachIndexed { index, placeable ->
67 | val itemWidth = placeable.width + if (index > 0) hSpacingPx else 0
68 |
69 | if (currentRowWidth + itemWidth > constraints.maxWidth) {
70 | currentLine++
71 | if (currentLine >= maxLine) return@forEachIndexed
72 | totalHeight += currentRowHeight + vSpacingPx
73 | currentRowWidth = 0
74 | currentRowHeight = 0
75 | }
76 | currentRowWidth += itemWidth
77 | currentRowHeight = maxOf(currentRowHeight, placeable.height)
78 | }
79 | lineCountState= if (currentRowWidth > 0) currentLine + 1 else currentLine
80 | //获取最大高度
81 | val maxHeight = totalHeight + currentRowHeight
82 |
83 | // 第二阶段:实际布局
84 | subcompose("content") {
85 | FlowRow(
86 | modifier = modifier
87 | .heightIn(max = with(density) { maxHeight.toDp() })
88 | .clipToBounds(),
89 | horizontalArrangement = Arrangement.spacedBy(horizontalSpacing),
90 | verticalArrangement = Arrangement.spacedBy(verticalSpacing)
91 | ) {
92 | content()
93 | }
94 | }.first().measure(constraints).let { placeable ->
95 | // 正确使用layout作用域
96 | layout(constraints.maxWidth, maxHeight) {
97 | placeable.place(0, 0)
98 | }
99 | }
100 | }
101 | }
102 |
103 | @Preview
104 | @Composable
105 | fun PkFlowRowPreview() {
106 | val tags = listOf("Android", "Kotlin", "Jetpack Compose", "KMP","Material Design", "UI", "Development")
107 |
108 | PkFlowRow(
109 | horizontalSpacing = 8.dp,
110 | verticalSpacing = 12.dp,
111 | maxLine = 2
112 | ) {
113 | tags.forEach { tag ->
114 | Text(
115 | text = tag,
116 | modifier = Modifier
117 | .background(Color.LightGray, RoundedCornerShape(16.dp))
118 | .padding(horizontal = 12.dp, vertical = 8.dp)
119 | )
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ui/grid/PkStaggeredVerticalGrid.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ui.grid
2 |
3 | import androidx.compose.foundation.layout.PaddingValues
4 | import androidx.compose.runtime.Composable
5 | import androidx.compose.ui.Modifier
6 | import androidx.compose.ui.layout.Layout
7 | import androidx.compose.ui.unit.Dp
8 | import androidx.compose.ui.unit.dp
9 |
10 | /**
11 | * author :Peakmain
12 | * createTime:2025/6/21
13 | * mail:2726449200@qq.com
14 | * describe:瀑布流,非懒加载版
15 | */
16 | /**
17 | * 适合中小数据(<50项),若超过50,请用LazyVerticalStaggeredGrid
18 | * @param columns 网格列数(必须 >0)
19 | * @param modifier 容器修饰符(背景、尺寸等)
20 | * @param contentPadding 内容区域的内边距
21 | * @param verticalItemSpacing 垂直方向(行间)间距,默认是8.dp
22 | * @param horizontalItemSpacing 水平方向(列间)间距,默认是8.dp
23 | * @param content 网格项内容(任意 Composable 组件)
24 | */
25 | @Composable
26 | fun PkStaggeredVerticalGrid(
27 | columns: Int,
28 | modifier: Modifier = Modifier,
29 | contentPadding: PaddingValues = PaddingValues(0.dp),
30 | verticalItemSpacing: Dp = 8.dp,
31 | horizontalItemSpacing: Dp = 8.dp,
32 | content: @Composable () -> Unit
33 | ) {
34 | require(columns > 0) { "列数必须大于0" }
35 |
36 | Layout(
37 | content = content,
38 | modifier = modifier
39 | ) { measurables, constraints ->
40 | // 计算内容区域宽度(减去内边距)
41 | val horizontalPadding = contentPadding.calculateLeftPadding(layoutDirection) +
42 | contentPadding.calculateRightPadding(layoutDirection)
43 | val contentWidth = (constraints.maxWidth - horizontalPadding.roundToPx()).coerceAtLeast(0)
44 |
45 | // 计算列宽(减去水平间距)
46 | val columnWidth = ((contentWidth - (columns - 1) * horizontalItemSpacing.roundToPx()) / columns)
47 | .coerceAtLeast(0)
48 |
49 | // 初始化列高度数组
50 | val columnHeights = IntArray(columns) { contentPadding.calculateTopPadding().roundToPx() }
51 |
52 | // 测量所有子项
53 | val placeables = measurables.map { measurable ->
54 | // 约束子项宽度为列宽
55 | val placeable = measurable.measure(
56 | constraints.copy(
57 | minWidth = columnWidth,
58 | maxWidth = columnWidth
59 | )
60 | )
61 | placeable
62 | }
63 |
64 | // 计算每个子项的位置
65 | val positions = mutableListOf>()
66 |
67 | placeables.forEach { placeable ->
68 | // 找到当前高度最小的列
69 | val minColumn = columnHeights.withIndex().minByOrNull { it.value }?.index ?: 0
70 | val x = contentPadding.calculateLeftPadding(layoutDirection).roundToPx() +
71 | minColumn * (columnWidth + horizontalItemSpacing.roundToPx())
72 | val y = columnHeights[minColumn]
73 |
74 | // 更新列高度(加上当前项高度和垂直间距)
75 | columnHeights[minColumn] = y + placeable.height + verticalItemSpacing.roundToPx()
76 |
77 | positions.add(x to y)
78 | }
79 |
80 | // 计算总高度(最高列的高度 + 底部内边距)
81 | val totalHeight = (columnHeights.maxOrNull() ?: 0) +
82 | contentPadding.calculateBottomPadding().roundToPx() -
83 | verticalItemSpacing.roundToPx() // 减去最后一项的额外间距
84 |
85 | layout(constraints.maxWidth, totalHeight) {
86 | placeables.forEachIndexed { index, placeable ->
87 | val (x, y) = positions[index]
88 | placeable.place(x, y)
89 | }
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ui/image/PkImageView.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ui.image
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2025/4/17
6 | * mail:2726449200@qq.com
7 | * describe:
8 | */
9 | import androidx.compose.foundation.Image
10 | import androidx.compose.runtime.Composable
11 | import androidx.compose.ui.Alignment
12 | import androidx.compose.ui.Modifier
13 | import androidx.compose.ui.graphics.Color
14 | import androidx.compose.ui.graphics.ColorFilter
15 | import androidx.compose.ui.graphics.DefaultAlpha
16 | import androidx.compose.ui.graphics.painter.Painter
17 | import androidx.compose.ui.layout.ContentScale
18 | import androidx.compose.ui.tooling.preview.Preview
19 |
20 |
21 | @Composable
22 | fun PkImageView(
23 | painter: Painter,
24 | modifier: Modifier = Modifier,
25 | alignment: Alignment = Alignment.Center,
26 | contentScale: ContentScale = ContentScale.Crop,
27 | alpha: Float = DefaultAlpha,
28 | tintColor: Color? = null
29 | ) {
30 | Image(
31 | painter = painter,
32 | contentDescription = null,
33 | modifier, alignment,
34 | contentScale = contentScale,
35 | alpha = alpha,
36 | colorFilter = if (tintColor != null) ColorFilter.tint(tintColor) else null,
37 | )
38 | }
39 |
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ui/progress/RoundedLinearProgressIndicator.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ui.progress
2 |
3 |
4 | import androidx.compose.foundation.Canvas
5 | import androidx.compose.foundation.layout.fillMaxWidth
6 | import androidx.compose.foundation.layout.height
7 | import androidx.compose.runtime.Composable
8 | import androidx.compose.ui.Modifier
9 | import androidx.compose.ui.geometry.Offset
10 | import androidx.compose.ui.geometry.Size
11 | import androidx.compose.ui.graphics.Color
12 | import androidx.compose.ui.graphics.drawscope.DrawScope
13 | import androidx.compose.ui.graphics.drawscope.Stroke
14 | import androidx.compose.ui.unit.Dp
15 | import androidx.compose.ui.unit.dp
16 | import com.peakmain.compose.basic.BasicColor
17 | /**
18 | * author :Peakmain
19 | * createTime:2025/6/11
20 | * mail:2726449200@qq.com
21 | * describe:圆角进度条
22 | */
23 | @Composable
24 | fun RoundedLinearProgressIndicator(
25 | progress: Float,
26 | modifier: Modifier = Modifier,
27 | color: Color = BasicColor.color_1F401B,
28 | backgroundColor: Color = BasicColor.color_EBEBF0,
29 | height: Dp = 4.dp,
30 | cornerRadius: Dp = 2.dp
31 | ) {
32 | Canvas(
33 | modifier = modifier
34 | .fillMaxWidth()
35 | .height(height)
36 | ) {
37 | // 绘制背景
38 | drawRoundedRect(
39 | color = backgroundColor,
40 | size = Size(size.width, size.height),
41 | cornerRadius = cornerRadius.toPx()
42 | )
43 |
44 | // 绘制进度条
45 | if (progress > 0) {
46 | val progressWidth = size.width * progress.coerceIn(0f, 1f)
47 | drawRoundedRect(
48 | color = color,
49 | topLeft = Offset(0f, 0f),
50 | size = Size(progressWidth, size.height),
51 | cornerRadius = cornerRadius.toPx()
52 | )
53 | }
54 | }
55 | }
56 |
57 | // 在 DrawScope 中扩展绘制圆角矩形的函数
58 | private fun DrawScope.drawRoundedRect(
59 | color: Color,
60 | topLeft: Offset = Offset.Zero,
61 | size: Size,
62 | cornerRadius: Float
63 | ) {
64 | drawRoundRect(
65 | color = color,
66 | topLeft = topLeft,
67 | size = size,
68 | cornerRadius = androidx.compose.ui.geometry.CornerRadius(cornerRadius, cornerRadius)
69 | )
70 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ui/text/PkHighlightText.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ui.text
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2025/4/25
6 | * mail:2726449200@qq.com
7 | * describe:高亮文本
8 | */
9 | import androidx.compose.foundation.background
10 | import androidx.compose.foundation.layout.Column
11 | import androidx.compose.material.MaterialTheme
12 | import androidx.compose.material.Text
13 | import androidx.compose.material3.LocalTextStyle
14 | import androidx.compose.runtime.Composable
15 | import androidx.compose.runtime.remember
16 | import androidx.compose.ui.Modifier
17 | import androidx.compose.ui.graphics.Color
18 | import androidx.compose.ui.text.SpanStyle
19 | import androidx.compose.ui.text.TextStyle
20 | import androidx.compose.ui.text.buildAnnotatedString
21 | import androidx.compose.ui.text.withStyle
22 | import androidx.compose.ui.tooling.preview.Preview
23 |
24 | /**
25 | * author :Peakmain
26 | * createTime:2025/4/25
27 | * mail:2726449200@qq.com
28 | * describe:高亮关键词的文本组件
29 | */
30 |
31 | /**
32 | * 高亮关键词的文本组件。
33 | *
34 | * @param text 需要处理的原始文本。
35 | * @param keywords 高亮关键字列表(为空时不进行高亮)。
36 | * @param highlightColor 高亮文本颜色,默认值为 [Color.Red]。
37 | * @param style 基础文本样式,默认值为 [LocalTextStyle.current],高亮部分继承此样式并叠加颜色。
38 | */
39 | @Composable
40 | fun PkHighlightText(
41 | text: String,
42 | keywords: List,
43 | highlightColor: Color = Color.Red,
44 | style: TextStyle = LocalTextStyle.current
45 | ) {
46 | val annotatedString = remember(text, keywords) {
47 | buildAnnotatedString {
48 | if (keywords.isEmpty()) {
49 | append(text) // 无关键字直接返回原文本
50 | return@buildAnnotatedString
51 | }
52 |
53 | // 1. 生成正则表达式模式(处理特殊字符)
54 | val pattern = keywords
55 | .filter { it.isNotEmpty() } // 过滤空关键字
56 | .distinct() // 去重
57 | .joinToString("|") { Regex.escape(it) } // 转义正则特殊字符
58 | .takeIf { it.isNotEmpty() } ?: run {
59 | append(text)
60 | return@buildAnnotatedString
61 | }
62 |
63 | // 2. 创建不区分大小写的正则表达式
64 | val regex = try {
65 | Regex(pattern, RegexOption.IGNORE_CASE)
66 | } catch (e: Exception) {
67 | // 处理非法正则表达式(如空模式)
68 | append(text)
69 | return@buildAnnotatedString
70 | }
71 |
72 | // 3. 查找所有匹配区间并合并重叠
73 | val matches = regex.findAll(text)
74 | .map { it.range.first to it.range.last + 1 } // 转换为前闭后开区间
75 | .toList()
76 |
77 | val mergedRanges = mergeIntervals(matches)
78 |
79 | // 4. 构建带高亮的字符串
80 | var currentIndex = 0
81 | for ((start, end) in mergedRanges) {
82 | if (start > currentIndex) {
83 | // 添加非高亮部分
84 | append(text.substring(currentIndex, start))
85 | }
86 | // 添加高亮部分(保留原文字大小写)
87 | withStyle(SpanStyle(color = highlightColor)) {
88 | append(text.substring(start, end))
89 | }
90 | currentIndex = end
91 | }
92 | // 添加剩余文本
93 | if (currentIndex < text.length) {
94 | append(text.substring(currentIndex))
95 | }
96 | }
97 | }
98 | Text(text = annotatedString, style = style)
99 | }
100 |
101 | /**
102 | * 合并重叠区间算法
103 | * 输入示例:[(0,3), (2,5), (6,7)] → 输出:[(0,5), (6,7)]
104 | */
105 | private fun mergeIntervals(intervals: List>): List> {
106 | if (intervals.isEmpty()) return emptyList()
107 |
108 | val sorted = intervals.sortedBy { it.first }
109 | val merged = mutableListOf>()
110 | var current = sorted.first()
111 |
112 | for (next in sorted) {
113 | if (next.first <= current.second) {
114 | // 区间重叠/相邻,合并
115 | current = current.first to maxOf(current.second, next.second)
116 | } else {
117 | merged.add(current)
118 | current = next
119 | }
120 | }
121 | merged.add(current)
122 |
123 | return merged
124 | }
125 |
126 | @Preview
127 | @Composable
128 | fun PkHighlightTextPreview() {
129 | Column(modifier = Modifier.background(Color.White)) {
130 | // 示例1:基本用法(多个关键字)
131 | PkHighlightText(
132 | text = "Jetpack Compose 是 Android 的现代 UI 工具包",
133 | keywords = listOf("compose", "android"),
134 | highlightColor = Color.Blue,
135 | style = MaterialTheme.typography.body1
136 | )
137 |
138 | // 示例2:含特殊字符的关键字
139 | PkHighlightText(
140 | text = "价格:$199 (限时优惠)",
141 | keywords = listOf("$199", "(限时优惠)"),
142 | highlightColor = Color(0xFF4CAF50)
143 | )
144 |
145 | // 示例3:无关键字/空列表
146 | PkHighlightText(
147 | text = "Hello World",
148 | keywords = emptyList() // 显示普通文本
149 | )
150 | }
151 | }
152 |
153 |
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ui/title/PkNavBar.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ui.title
2 |
3 | import android.app.Activity
4 | import androidx.annotation.DrawableRes
5 | import androidx.compose.foundation.background
6 | import androidx.compose.foundation.clickable
7 | import androidx.compose.foundation.layout.Box
8 | import androidx.compose.foundation.layout.fillMaxWidth
9 | import androidx.compose.foundation.layout.height
10 | import androidx.compose.foundation.layout.padding
11 | import androidx.compose.foundation.layout.size
12 | import androidx.compose.foundation.layout.statusBarsPadding
13 | import androidx.compose.material.Text
14 | import androidx.compose.runtime.Composable
15 | import androidx.compose.runtime.SideEffect
16 | import androidx.compose.ui.Alignment
17 | import androidx.compose.ui.Modifier
18 | import androidx.compose.ui.graphics.Color
19 | import androidx.compose.ui.platform.LocalConfiguration
20 | import androidx.compose.ui.platform.LocalContext
21 | import androidx.compose.ui.platform.LocalDensity
22 | import androidx.compose.ui.res.painterResource
23 | import androidx.compose.ui.text.font.FontWeight
24 | import androidx.compose.ui.tooling.preview.Preview
25 | import androidx.compose.ui.unit.Dp
26 | import androidx.compose.ui.unit.TextUnit
27 | import androidx.compose.ui.unit.dp
28 | import com.google.accompanist.systemuicontroller.rememberSystemUiController
29 | import com.peakmain.compose.basic.BasicFont
30 | import com.peakmain.compose.basic.BasicSize
31 | import com.peakmain.compose.basic.BasicSpace
32 | import com.peakmain.compose.library.R
33 | import com.peakmain.compose.ui.image.PkImageView
34 |
35 | /**
36 | * author :Peakmain
37 | * createTime:2025/6/26
38 | * mail:2726449200@qq.com
39 | * describe:自定义顶部标题栏
40 | */
41 |
42 | /**
43 | * 顶部导航栏组件,支持自定义标题、返回按钮、右侧按钮、沉浸式状态栏等功能。
44 | *
45 | * @param title 标题,必填,导航栏标题文本
46 | * @param backgroundColor 导航栏背景色,默认 #FFFFFEFA
47 | * @param horizontalContentPadding 水平方向内边距,默认 BasicSpace.space_18
48 | * @param verticalContentPadding 垂直方向内边距,默认 BasicSpace.space_10
49 | * @param backResource 返回图标资源 ID,默认 R.drawable.compose_icon_retrun
50 | * @param backResourceSize 返回图标尺寸,默认 BasicSize.size_24
51 | * @param showBack 是否显示返回按钮,默认 true
52 | * @param onBackClick 返回按钮点击事件,默认 null(null 时点击返回关闭当前 Activity)
53 | * @param titleFontSize 标题文字大小,默认 BasicFont.font_18
54 | * @param titleColor 标题文字颜色,默认 #1F401B
55 | * @param isImmersive 是否沉浸式状态栏,默认 true
56 | * @param darkIcons 状态栏图标是否使用深色,默认 true
57 | * @param rightResource 右侧图标资源 ID,默认为 null 表示不显示
58 | * @param onRightClick 右侧图标点击事件,默认 null(null 时不显示或不响应)
59 | */
60 | @Composable
61 | fun PkNavBar(
62 | title: String,
63 | backgroundColor: Color = Color(0xFFFFFEFA),
64 | horizontalContentPadding: Dp = BasicSpace.space_18,
65 | @DrawableRes backResource: Int = R.drawable.compose_icon_retrun,
66 | backResourceSize: Dp = BasicSize.size_24,
67 | showBack: Boolean = true,
68 | onBackClick: (() -> Unit)? = null,
69 | titleFontSize: TextUnit = BasicFont.font_18,
70 | titleColor: Color = Color(0xFF1F401B),
71 | isImmersive: Boolean = true,
72 | darkIcons: Boolean = true,
73 | @DrawableRes rightResource: Int? = null,
74 | onRightClick: (() -> Unit)? = null
75 | ) {
76 | val context = LocalContext.current
77 | if (isImmersive) {
78 | val systemUiController = rememberSystemUiController()
79 | SideEffect {
80 | systemUiController.setSystemBarsColor(
81 | color = backgroundColor,
82 | darkIcons = darkIcons
83 | )
84 | }
85 | }
86 | Box(
87 | modifier = Modifier
88 | .fillMaxWidth()
89 | .background(backgroundColor)
90 | .statusBarsPadding()
91 | .height(44.dp)
92 | .padding(horizontal = horizontalContentPadding),
93 | contentAlignment = Alignment.Center
94 | ) {
95 | if (showBack) {
96 | PkImageView(
97 | painter = painterResource(backResource),
98 | modifier = Modifier
99 | .size(backResourceSize)
100 | .align(Alignment.CenterStart)
101 | .clickable {
102 | if (onBackClick == null && context is Activity) {
103 | context.finish()
104 | } else {
105 | onBackClick?.invoke()
106 | }
107 | })
108 | }
109 |
110 | Text(
111 | text = title,
112 | fontSize = titleFontSize,
113 | fontWeight = FontWeight.W500,
114 | color = titleColor,
115 | modifier = Modifier
116 | .align(Alignment.Center)
117 | )
118 |
119 | if (rightResource != null) {
120 | PkImageView(
121 | painter = painterResource(rightResource),
122 | modifier = Modifier
123 | .size(24.dp)
124 | .align(Alignment.CenterEnd)
125 | .clickable { onRightClick?.invoke() })
126 | }
127 | }
128 | }
129 |
130 |
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/ui/title/PkTitle.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.ui.title
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2025/4/2
6 | * mail:2726449200@qq.com
7 | * describe:
8 | */
9 | import androidx.compose.foundation.layout.Column
10 | import androidx.compose.material3.LocalTextStyle
11 | import androidx.compose.material3.Text
12 | import androidx.compose.runtime.Composable
13 | import androidx.compose.ui.Modifier
14 | import androidx.compose.ui.graphics.Color
15 | import androidx.compose.ui.text.TextStyle
16 | import androidx.compose.ui.text.font.FontStyle
17 | import androidx.compose.ui.text.font.FontWeight
18 | import androidx.compose.ui.text.style.TextAlign
19 | import androidx.compose.ui.text.style.TextOverflow
20 | import androidx.compose.ui.tooling.preview.Preview
21 | import androidx.compose.ui.unit.TextUnit
22 | import androidx.compose.ui.unit.sp
23 |
24 | sealed class PkTitleType {
25 | abstract val fontSize: TextUnit
26 | abstract val fontWeight: FontWeight
27 |
28 | /**
29 | * 大标题1
30 | */
31 | data class BigTitle1(
32 | override val fontSize: TextUnit = 24.sp,
33 | override val fontWeight: FontWeight = FontWeight.W500
34 | ) : PkTitleType()
35 |
36 | /**
37 | * 大标题2
38 | */
39 | data class BigTitle2(
40 | override val fontSize: TextUnit = 22.sp,
41 | override val fontWeight: FontWeight = FontWeight.W500
42 | ) : PkTitleType()
43 |
44 | /**
45 | * 大标题3
46 | */
47 | data class BigTitle3(
48 | override val fontSize: TextUnit = 18.sp,
49 | override val fontWeight: FontWeight = FontWeight.W500
50 | ) : PkTitleType()
51 |
52 | /**
53 | * 标题1 加粗
54 | */
55 | data class TitleBold1(
56 | override val fontSize: TextUnit = 16.sp,
57 | override val fontWeight: FontWeight = FontWeight.W500
58 | ) : PkTitleType()
59 |
60 | /**
61 | * 标题1 常规
62 | */
63 | data class TitleNormal1(
64 | override val fontSize: TextUnit = 16.sp,
65 | override val fontWeight: FontWeight = FontWeight.W400
66 | ) : PkTitleType()
67 |
68 | /**
69 | * 标题2 加粗
70 | */
71 | data class TitleBold2(
72 | override val fontSize: TextUnit = 15.sp,
73 | override val fontWeight: FontWeight = FontWeight.W500
74 | ) : PkTitleType()
75 |
76 | /**
77 | * 标题2 常规
78 | */
79 | data class TitleNormal2(
80 | override val fontSize: TextUnit = 15.sp,
81 | override val fontWeight: FontWeight = FontWeight.W400
82 | ) : PkTitleType()
83 |
84 | /**
85 | * 小标题 加粗
86 | */
87 | data class SmallTitleBold(
88 | override val fontSize: TextUnit = 14.sp,
89 | override val fontWeight: FontWeight = FontWeight.W500
90 | ) : PkTitleType()
91 |
92 | /**
93 | * 小标题 常规
94 | */
95 | data class SmallTitleNormal(
96 | override val fontSize: TextUnit = 14.sp,
97 | override val fontWeight: FontWeight = FontWeight.W400
98 | ) : PkTitleType()
99 |
100 | /**
101 | * 内文1加粗
102 | */
103 | data class TextBold1(
104 | override val fontSize: TextUnit = 12.sp,
105 | override val fontWeight: FontWeight = FontWeight.W500
106 | ) : PkTitleType()
107 | /**
108 | * 内文1常规
109 | */
110 | data class TextNormal1(
111 | override val fontSize: TextUnit = 12.sp,
112 | override val fontWeight: FontWeight = FontWeight.W400
113 | ) : PkTitleType()
114 | /**
115 | * 内文2加粗
116 | */
117 | data class TextBold2(
118 | override val fontSize: TextUnit = 11.sp,
119 | override val fontWeight: FontWeight = FontWeight.W500
120 | ) : PkTitleType()
121 |
122 | /**
123 | * 内文2常规
124 | */
125 | data class TextNormal2(
126 | override val fontSize: TextUnit = 11.sp,
127 | override val fontWeight: FontWeight = FontWeight.W400
128 | ) : PkTitleType()
129 | }
130 | @Composable
131 | fun PkTitle(
132 | text: String,
133 | type: PkTitleType = PkTitleType.BigTitle1(),
134 | modifier: Modifier = Modifier,
135 | color: Color = Color(0xFF333333),
136 | fontStyle: FontStyle? = null,
137 | textAlign: TextAlign? = null,
138 | overflow: TextOverflow = TextOverflow.Ellipsis,
139 | maxLines: Int =1,
140 | style: TextStyle = LocalTextStyle.current
141 | ) {
142 | Text(
143 | text,
144 | modifier,
145 | color,
146 | type.fontSize,
147 | fontStyle,
148 | type.fontWeight,
149 | textAlign = textAlign,
150 | overflow = overflow,
151 | maxLines = maxLines,
152 | style = style
153 | )
154 | }
155 |
156 | @Preview
157 | @Composable
158 | fun PkTitleComposablePreview() {
159 | Column {
160 | PkTitle("大标题1",PkTitleType.BigTitle1())
161 | PkTitle("大标题2",PkTitleType.BigTitle2())
162 | PkTitle("大标题3",PkTitleType.BigTitle3())
163 | PkTitle("标题1加粗",PkTitleType.TitleBold1())
164 | PkTitle("标题1常规",PkTitleType.TitleNormal1())
165 | PkTitle("标题2加粗",PkTitleType.TitleBold2())
166 | PkTitle("标题2常规",PkTitleType.TitleNormal2())
167 | PkTitle("小标题加粗",PkTitleType.SmallTitleBold())
168 | PkTitle("小标题常规",PkTitleType.SmallTitleNormal())
169 | PkTitle("内文1加粗",PkTitleType.TextBold1())
170 | PkTitle("内文1正常",PkTitleType.TextNormal1())
171 | PkTitle("内文2加粗",PkTitleType.TextBold2())
172 | PkTitle("内文2正常",PkTitleType.TextNormal2())
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/library/src/main/java/com/peakmain/compose/utils/ImagePainterUtils.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.utils
2 |
3 | import android.content.Context
4 | import android.graphics.Insets.add
5 | import android.os.Build.VERSION.SDK_INT
6 | import android.text.TextUtils
7 | import androidx.annotation.DrawableRes
8 | import androidx.compose.foundation.Image
9 | import androidx.compose.foundation.lazy.rememberLazyListState
10 | import androidx.compose.runtime.Composable
11 | import androidx.compose.runtime.derivedStateOf
12 | import androidx.compose.runtime.mutableStateOf
13 | import androidx.compose.runtime.remember
14 | import androidx.compose.ui.platform.LocalContext
15 | import coil.ImageLoader
16 | import coil.compose.AsyncImagePainter
17 | import coil.compose.rememberAsyncImagePainter
18 | import coil.decode.ImageDecoderDecoder
19 | import coil.decode.SvgDecoder
20 | import coil.request.ImageRequest
21 | import com.peakmain.compose.library.R
22 |
23 | /**
24 | * author :Peakmain
25 | * createTime:2025/3/6
26 | * mail:2726449200@qq.com
27 | * describe:图片加载工具类
28 | */
29 | object ImagePainterUtils {
30 | /**
31 | * 根据图片 URL 获取 AsyncImagePainter 对象。
32 | *
33 | * @param imageUrl 图片的 URL,如果为空则显示占位图。
34 | * @param errorDrawableResId 图片加载失败时显示的 Drawable 资源 ID,默认为 R.drawable.icon_loading。
35 | * @param placeDrawableResId 图片加载过程中显示的占位图 Drawable 资源 ID,默认为 R.drawable.icon_loading。
36 | * @return 返回一个 AsyncImagePainter 对象。
37 | */
38 | @Composable
39 | fun getPainter(
40 | imageUrl: String?,
41 | @DrawableRes errorDrawableResId: Int = R.drawable.icon_loading,
42 | @DrawableRes placeDrawableResId: Int = R.drawable.icon_loading,
43 | imageLoader: ImageLoader = getImageLoader(LocalContext.current)
44 | ): AsyncImagePainter {
45 |
46 | return if (!TextUtils.isEmpty(imageUrl))
47 | rememberAsyncImagePainter(
48 | model = ImageRequest.Builder(LocalContext.current)
49 | .data(imageUrl)
50 | .error(errorDrawableResId)
51 | .placeholder(placeDrawableResId)
52 | .build(),
53 | imageLoader =imageLoader
54 | ) else
55 | rememberAsyncImagePainter(
56 | model = ImageRequest.Builder(LocalContext.current)
57 | .data(placeDrawableResId)
58 | .build(),
59 | imageLoader =imageLoader
60 | )
61 |
62 | }
63 |
64 | private fun getImageLoader(context: Context): ImageLoader {
65 | return ImageLoader.Builder(context).components {
66 | if (SDK_INT > 28) {
67 | add(ImageDecoderDecoder.Factory())
68 | } else {
69 | add(coil.decode.GifDecoder.Factory())
70 | }
71 | add(SvgDecoder.Factory())
72 | }.build()
73 | }
74 | }
--------------------------------------------------------------------------------
/library/src/main/res/drawable/compose_icon_retrun.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable/ic_right_arrow.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable/icon_loading.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/library/src/test/java/com/peakmain/compose/library/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.compose.library
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 | }
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | dependencyResolutionManagement {
2 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
3 | repositories {
4 | mavenCentral()
5 | google()
6 | jcenter() // Warning: this repository is going to shut down soon
7 | }
8 | }
9 | rootProject.name = "ComposeUI"
10 | include ':app'
11 | include ':library'
12 |
--------------------------------------------------------------------------------