├── .gitignore ├── .idea ├── .gitignore ├── .name ├── AndroidProjectSystem.xml ├── compiler.xml ├── deploymentTargetSelector.xml ├── gradle.xml ├── inspectionProfiles │ └── Project_Default.xml ├── kotlinc.xml ├── migrations.xml ├── misc.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE ├── README.md ├── WX-Compose-IPlugin ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── wx │ │ └── compose │ │ └── plugin │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── wx │ │ └── compose │ │ └── plugin │ │ └── ICompose.kt │ └── test │ └── java │ └── com │ └── wx │ └── compose │ └── plugin │ └── ExampleUnitTest.kt ├── WX-Compose-PluginImpl ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── wx │ │ └── compose │ │ └── plugin │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── wx │ │ └── compose │ │ └── plugin │ │ ├── compose │ │ └── PluginComposeImpl.kt │ │ └── theme │ │ ├── Color.kt │ │ ├── Theme.kt │ │ └── Type.kt │ └── test │ └── java │ └── com │ └── wx │ └── compose │ └── plugin │ └── ExampleUnitTest.kt ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro ├── src │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── wx │ │ │ └── compose │ │ │ └── plugin │ │ │ └── ExampleInstrumentedTest.kt │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── assets │ │ │ └── vv.mp3 │ │ ├── java │ │ │ └── com │ │ │ │ └── wx │ │ │ │ └── compose │ │ │ │ └── plugin │ │ │ │ ├── MyApp.kt │ │ │ │ ├── activity │ │ │ │ ├── BottomNavigationActivity.kt │ │ │ │ ├── CollapsableActivity.kt │ │ │ │ ├── ComposeDHListActivity.kt │ │ │ │ ├── ComposeHListActivity.kt │ │ │ │ ├── ComposeLayoutActivity.kt │ │ │ │ ├── ComposeListActivity.kt │ │ │ │ ├── ComposePluginActivity.kt │ │ │ │ ├── GirdLayoutActivity.kt │ │ │ │ ├── HorizontalPagerLayoutActivity.kt │ │ │ │ ├── MainActivity.kt │ │ │ │ ├── ModalDrawerActivity.kt │ │ │ │ ├── MutilGirdLayoutActivity.kt │ │ │ │ ├── MutilHGirdLayoutActivity.kt │ │ │ │ ├── NavHostActivity.kt │ │ │ │ ├── PullToRefreshActivity.kt │ │ │ │ ├── PullToRefreshActivity2.kt │ │ │ │ ├── PullToRefreshActivity3.kt │ │ │ │ ├── PullToRefreshActivity4.kt │ │ │ │ ├── PullToRefreshActivity5.kt │ │ │ │ ├── PullToRefreshActivity6.kt │ │ │ │ ├── SnckbarActivity.kt │ │ │ │ ├── StickListActivity.kt │ │ │ │ ├── SubCActivity.kt │ │ │ │ ├── TabHorizontalPagerActivity.kt │ │ │ │ ├── TabLayoutActivity.kt │ │ │ │ ├── ViewPageLayoutActivity.kt │ │ │ │ └── WebViewActivity.kt │ │ │ │ ├── classloader │ │ │ │ └── WXClassLoader.java │ │ │ │ ├── composable │ │ │ │ └── BaseComposable.kt │ │ │ │ ├── data │ │ │ │ ├── DataBean.kt │ │ │ │ ├── MainUIItem.kt │ │ │ │ └── TopDataSource.kt │ │ │ │ ├── theme │ │ │ │ ├── Color.kt │ │ │ │ ├── Theme.kt │ │ │ │ └── Type.kt │ │ │ │ └── viewmodel │ │ │ │ ├── ComposeViewModel.kt │ │ │ │ └── DhListViewModel.kt │ │ └── res │ │ │ ├── drawable-nodpi │ │ │ ├── ava1.jpg │ │ │ ├── ava2.jpg │ │ │ ├── ava3.jpg │ │ │ └── people_4.jpg │ │ │ ├── drawable │ │ │ ├── ic_dashboard_black_24dp.xml │ │ │ ├── ic_home_black_24dp.xml │ │ │ ├── ic_launcher_background.xml │ │ │ ├── ic_launcher_foreground.xml │ │ │ └── ic_notifications_black_24dp.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── 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-night │ │ │ └── themes.xml │ │ │ ├── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── themes.xml │ │ │ └── xml │ │ │ ├── backup_rules.xml │ │ │ └── data_extraction_rules.xml │ └── test │ │ └── java │ │ └── com │ │ └── wx │ │ └── compose │ │ └── plugin │ │ └── ExampleUnitTest.kt └── wx_compose_plugin.jks ├── build.gradle ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── pic ├── 641.webp ├── Screenshot_20241014_122121.png ├── Screenshot_20241014_122227.png ├── Screenshot_20241014_122254.png ├── Screenshot_20241014_122311.png ├── Screenshot_20241014_122332.png ├── Screenshot_20241014_122347.png ├── Screenshot_20241014_122408.png ├── Screenshot_20241014_122426.png ├── Screenshot_20241014_122437.png ├── Screenshot_20241014_122452.png ├── Screenshot_20241014_122505.png ├── Screenshot_20241014_122529.png ├── Screenshot_20241014_122546.png ├── Screenshot_20241014_122608.png ├── Screenshot_20241014_122629.png ├── Screenshot_20241014_122639.png ├── Screenshot_20241014_122702.png ├── Screenshot_20241014_122728.png ├── Screenshot_20241014_125657.png ├── Sheet1.png ├── img_v3_02fl_39e304ea-9574-4555-91b6-c67fa63c47bg.jpg ├── img_v3_02fl_70eb77d1-2529-4f7c-8034-60a4df1072eg.jpg └── img_v3_02fl_a5f9ebc8-9e0b-4ed3-a194-c12b3cae9fbg.jpg └── 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 | WX-Compose-Plugin -------------------------------------------------------------------------------- /.idea/AndroidProjectSystem.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/deploymentTargetSelector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 16 | 17 | 19 | 20 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 59 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/migrations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 木兰宽松许可证,第2版 2 | 3 | 木兰宽松许可证,第2版 4 | 5 | 2020年1月 http://license.coscl.org.cn/MulanPSL2 6 | 7 | 您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束: 8 | 9 | 0. 定义 10 | 11 | “软件” 是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。 12 | 13 | “贡献” 是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。 14 | 15 | “贡献者” 是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。 16 | 17 | “法人实体” 是指提交贡献的机构及其“关联实体”。 18 | 19 | “关联实体” 是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是 20 | 指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。 21 | 22 | 1. 授予版权许可 23 | 24 | 每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可 25 | 以复制、使用、修改、分发其“贡献”,不论修改与否。 26 | 27 | 2. 授予专利许可 28 | 29 | 每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定 30 | 撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡 31 | 献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软 32 | 件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“ 33 | 关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或 34 | 其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权 35 | 行动之日终止。 36 | 37 | 3. 无商标许可 38 | 39 | “本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定 40 | 的声明义务而必须使用除外。 41 | 42 | 4. 分发限制 43 | 44 | 您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“ 45 | 本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。 46 | 47 | 5. 免责声明与责任限制 48 | 49 | “软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对 50 | 任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于 51 | 何种法律理论,即使其曾被建议有此种损失的可能性。 52 | 53 | 6. 语言 54 | 55 | “本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文 56 | 版为准。 57 | 58 | 条款结束 59 | 60 | 如何将木兰宽松许可证,第2版,应用到您的软件 61 | 62 | 如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步: 63 | 64 | 1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字; 65 | 66 | 2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中; 67 | 68 | 3, 请将如下声明文本放入每个源文件的头部注释中。 69 | 70 | Copyright (c) [Year] [name of copyright holder] 71 | [Software Name] is licensed under Mulan PSL v2. 72 | You can use this software according to the terms and conditions of the Mulan 73 | PSL v2. 74 | You may obtain a copy of Mulan PSL v2 at: 75 | http://license.coscl.org.cn/MulanPSL2 76 | THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY 77 | KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 78 | NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 79 | See the Mulan PSL v2 for more details. 80 | 81 | Mulan Permissive Software License,Version 2 82 | 83 | Mulan Permissive Software License,Version 2 (Mulan PSL v2) 84 | 85 | January 2020 http://license.coscl.org.cn/MulanPSL2 86 | 87 | Your reproduction, use, modification and distribution of the Software shall 88 | be subject to Mulan PSL v2 (this License) with the following terms and 89 | conditions: 90 | 91 | 0. Definition 92 | 93 | Software means the program and related documents which are licensed under 94 | this License and comprise all Contribution(s). 95 | 96 | Contribution means the copyrightable work licensed by a particular 97 | Contributor under this License. 98 | 99 | Contributor means the Individual or Legal Entity who licenses its 100 | copyrightable work under this License. 101 | 102 | Legal Entity means the entity making a Contribution and all its 103 | Affiliates. 104 | 105 | Affiliates means entities that control, are controlled by, or are under 106 | common control with the acting entity under this License, ‘control’ means 107 | direct or indirect ownership of at least fifty percent (50%) of the voting 108 | power, capital or other securities of controlled or commonly controlled 109 | entity. 110 | 111 | 1. Grant of Copyright License 112 | 113 | Subject to the terms and conditions of this License, each Contributor hereby 114 | grants to you a perpetual, worldwide, royalty-free, non-exclusive, 115 | irrevocable copyright license to reproduce, use, modify, or distribute its 116 | Contribution, with modification or not. 117 | 118 | 2. Grant of Patent License 119 | 120 | Subject to the terms and conditions of this License, each Contributor hereby 121 | grants to you a perpetual, worldwide, royalty-free, non-exclusive, 122 | irrevocable (except for revocation under this Section) patent license to 123 | make, have made, use, offer for sale, sell, import or otherwise transfer its 124 | Contribution, where such patent license is only limited to the patent claims 125 | owned or controlled by such Contributor now or in future which will be 126 | necessarily infringed by its Contribution alone, or by combination of the 127 | Contribution with the Software to which the Contribution was contributed. 128 | The patent license shall not apply to any modification of the Contribution, 129 | and any other combination which includes the Contribution. If you or your 130 | Affiliates directly or indirectly institute patent litigation (including a 131 | cross claim or counterclaim in a litigation) or other patent enforcement 132 | activities against any individual or entity by alleging that the Software or 133 | any Contribution in it infringes patents, then any patent license granted to 134 | you under this License for the Software shall terminate as of the date such 135 | litigation or activity is filed or taken. 136 | 137 | 3. No Trademark License 138 | 139 | No trademark license is granted to use the trade names, trademarks, service 140 | marks, or product names of Contributor, except as required to fulfill notice 141 | requirements in section 4. 142 | 143 | 4. Distribution Restriction 144 | 145 | You may distribute the Software in any medium with or without modification, 146 | whether in source or executable forms, provided that you provide recipients 147 | with a copy of this License and retain copyright, patent, trademark and 148 | disclaimer statements in the Software. 149 | 150 | 5. Disclaimer of Warranty and Limitation of Liability 151 | 152 | THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY 153 | KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR 154 | COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT 155 | LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING 156 | FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO 157 | MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF 158 | THE POSSIBILITY OF SUCH DAMAGES. 159 | 160 | 6. Language 161 | 162 | THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION 163 | AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF 164 | DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION 165 | SHALL PREVAIL. 166 | 167 | END OF THE TERMS AND CONDITIONS 168 | 169 | How to Apply the Mulan Permissive Software License,Version 2 170 | (Mulan PSL v2) to Your Software 171 | 172 | To apply the Mulan PSL v2 to your work, for easy identification by 173 | recipients, you are suggested to complete following three steps: 174 | 175 | i. Fill in the blanks in following statement, including insert your software 176 | name, the year of the first publication of your software, and your name 177 | identified as the copyright owner; 178 | 179 | ii. Create a file named "LICENSE" which contains the whole context of this 180 | License in the first directory of your software package; 181 | 182 | iii. Attach the statement to the appropriate annotated syntax at the 183 | beginning of each source file. 184 | 185 | Copyright (c) [Year] [name of copyright holder] 186 | [Software Name] is licensed under Mulan PSL v2. 187 | You can use this software according to the terms and conditions of the Mulan 188 | PSL v2. 189 | You may obtain a copy of Mulan PSL v2 at: 190 | http://license.coscl.org.cn/MulanPSL2 191 | THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY 192 | KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 193 | NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 194 | See the Mulan PSL v2 for more details. 195 | -------------------------------------------------------------------------------- /WX-Compose-IPlugin/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /WX-Compose-IPlugin/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.android.library) 3 | alias(libs.plugins.jetbrains.kotlin.android) 4 | // alias(libs.plugins.compose.compiler) 5 | } 6 | 7 | android { 8 | namespace 'com.wx.compose.iplugin' 9 | compileSdk 34 10 | 11 | defaultConfig { 12 | minSdk 24 13 | targetSdk 34 14 | versionCode 1 15 | versionName "1.0" 16 | 17 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 18 | } 19 | 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | compileOptions { 27 | sourceCompatibility JavaVersion.VERSION_1_8 28 | targetCompatibility JavaVersion.VERSION_1_8 29 | } 30 | kotlinOptions { 31 | jvmTarget = '1.8' 32 | } 33 | } 34 | 35 | dependencies { 36 | 37 | implementation libs.androidx.core.ktx 38 | implementation libs.androidx.appcompat 39 | 40 | // implementation libs.material 41 | // testImplementation libs.junit 42 | // androidTestImplementation libs.androidx.junit 43 | // androidTestImplementation libs.androidx.espresso.core 44 | } -------------------------------------------------------------------------------- /WX-Compose-IPlugin/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 -------------------------------------------------------------------------------- /WX-Compose-IPlugin/src/androidTest/java/com/wx/compose/plugin/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin 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.wx.compose.iplugin", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /WX-Compose-IPlugin/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /WX-Compose-IPlugin/src/main/java/com/wx/compose/plugin/ICompose.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin 2 | 3 | import androidx.activity.ComponentActivity 4 | 5 | interface ICompose { 6 | 7 | fun setComposeContent(activity: ComponentActivity) 8 | 9 | } -------------------------------------------------------------------------------- /WX-Compose-IPlugin/src/test/java/com/wx/compose/plugin/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin 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 | } -------------------------------------------------------------------------------- /WX-Compose-PluginImpl/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /WX-Compose-PluginImpl/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.android.library) 3 | alias(libs.plugins.jetbrains.kotlin.android) 4 | alias(libs.plugins.compose.compiler) 5 | } 6 | 7 | android { 8 | namespace 'com.wx.compose.iplugin' 9 | compileSdk 34 10 | 11 | defaultConfig { 12 | minSdk 24 13 | targetSdk 34 14 | versionCode 1 15 | versionName "1.0" 16 | 17 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 18 | } 19 | 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | compileOptions { 27 | sourceCompatibility JavaVersion.VERSION_1_8 28 | targetCompatibility JavaVersion.VERSION_1_8 29 | } 30 | kotlinOptions { 31 | jvmTarget = '1.8' 32 | } 33 | buildFeatures { 34 | compose = true 35 | } 36 | composeOptions { 37 | kotlinCompilerExtensionVersion = "1.7.0" 38 | } 39 | } 40 | 41 | dependencies { 42 | implementation project(path: ':WX-Compose-IPlugin') 43 | 44 | implementation(libs.androidx.core.ktx) 45 | implementation(libs.androidx.lifecycle.runtime.ktx) 46 | implementation(libs.androidx.activity.compose) 47 | implementation(platform(libs.androidx.compose.bom)) 48 | implementation(libs.androidx.ui) 49 | implementation(libs.androidx.ui.graphics) 50 | implementation(libs.androidx.ui.tooling.preview) 51 | implementation(libs.androidx.material3) 52 | // implementation(libs.androidx.constraintlayout) 53 | implementation libs.androidx.constraintlayout.compose 54 | implementation libs.androidx.runtime.livedata 55 | implementation libs.coil.compose 56 | // implementation libs.material 57 | // testImplementation libs.junit 58 | // androidTestImplementation libs.androidx.junit 59 | // androidTestImplementation libs.androidx.espresso.core 60 | } 61 | 62 | 63 | def createCopyTask(buildType) { 64 | def workingDirPath = rootProject.ext.workingDirPath 65 | def outputFile = file("${workingDirPath}compose_plugin_lib.jar") 66 | def outputDexFile = file("${workingDirPath}compose_plugin_lib_dex.jar") 67 | def lastOutputDexFile = file("${rootProject.getBuildDir()}/compose_plugin_lib_dex") 68 | if (lastOutputDexFile.exists()) { 69 | lastOutputDexFile.delete() 70 | } 71 | if (outputDexFile.exists()) { 72 | outputDexFile.delete() 73 | } 74 | if (outputFile.exists()) { 75 | outputFile.delete() 76 | } 77 | def inputFile = file("${getProject().getBuildDir()}/intermediates/aar_main_jar/${buildType}/sync${buildType}LibJars/classes.jar") 78 | def copyTask = tasks.create("assembleCopy${buildType.capitalize()}", Copy) { 79 | group = 'other' 80 | description = "复制${name}到dx环境中." 81 | from(inputFile.getParent()) { 82 | include(inputFile.name) 83 | rename { outputFile.name } 84 | } 85 | into(outputFile.getParent()) 86 | }.dependsOn("assemble${buildType.capitalize()}") 87 | 88 | def assembleDxCommand = tasks.create("assembleDxCommand", Exec) { 89 | group = 'other' 90 | description = "${name}到dx执行中..." 91 | workingDir workingDirPath 92 | if (System.getProperty('os.name').toLowerCase(Locale.ROOT).contains('windows')) { 93 | it.commandLine 'cmd', '/c', "d8 --output ${outputDexFile.name} ${outputFile.name}" 94 | } else { 95 | it.commandLine bash, '-c ', "d8 --output ${outputDexFile.name} ${outputFile.name}" 96 | } 97 | }.dependsOn(copyTask.name) 98 | return tasks.create("assembleDxCommandAndCopy") { 99 | doLast { 100 | copy { 101 | from(outputDexFile.getParent()) { 102 | include(outputDexFile.name) 103 | rename { lastOutputDexFile.name } 104 | } 105 | into(lastOutputDexFile.getParent()) 106 | } 107 | } 108 | }.dependsOn(assembleDxCommand.name) 109 | } 110 | 111 | tasks.whenTaskAdded { task -> 112 | if (task.name == "assembleRelease") { 113 | createCopyTask("Release") 114 | } 115 | } -------------------------------------------------------------------------------- /WX-Compose-PluginImpl/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 -------------------------------------------------------------------------------- /WX-Compose-PluginImpl/src/androidTest/java/com/wx/compose/plugin/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin 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.wx.compose.iplugin", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /WX-Compose-PluginImpl/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /WX-Compose-PluginImpl/src/main/java/com/wx/compose/plugin/theme/Color.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.theme 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | val Purple80 = Color(0xFFD0BCFF) 6 | val PurpleGrey80 = Color(0xFFCCC2DC) 7 | val Pink80 = Color(0xFFEFB8C8) 8 | 9 | val Purple40 = Color(0xFF6650a4) 10 | val PurpleGrey40 = Color(0xFF625b71) 11 | val Pink40 = Color(0xFF7D5260) -------------------------------------------------------------------------------- /WX-Compose-PluginImpl/src/main/java/com/wx/compose/plugin/theme/Theme.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose1.ui.ui.theme 2 | 3 | import android.os.Build 4 | import androidx.compose.foundation.isSystemInDarkTheme 5 | import androidx.compose.material3.MaterialTheme 6 | import androidx.compose.material3.darkColorScheme 7 | import androidx.compose.material3.dynamicDarkColorScheme 8 | import androidx.compose.material3.dynamicLightColorScheme 9 | import androidx.compose.material3.lightColorScheme 10 | import androidx.compose.runtime.Composable 11 | import androidx.compose.ui.platform.LocalContext 12 | import com.wx.compose.plugin.theme.Pink40 13 | import com.wx.compose.plugin.theme.Pink80 14 | import com.wx.compose.plugin.theme.Purple40 15 | import com.wx.compose.plugin.theme.Purple80 16 | import com.wx.compose.plugin.theme.PurpleGrey40 17 | import com.wx.compose.plugin.theme.PurpleGrey80 18 | import com.wx.compose.plugin.theme.Typography 19 | 20 | private val DarkColorScheme = darkColorScheme( 21 | primary = Purple80, 22 | secondary = PurpleGrey80, 23 | tertiary = Pink80 24 | ) 25 | 26 | private val LightColorScheme = lightColorScheme( 27 | primary = Purple40, 28 | secondary = PurpleGrey40, 29 | tertiary = Pink40 30 | 31 | /* Other default colors to override 32 | background = Color(0xFFFFFBFE), 33 | surface = Color(0xFFFFFBFE), 34 | onPrimary = Color.White, 35 | onSecondary = Color.White, 36 | onTertiary = Color.White, 37 | onBackground = Color(0xFF1C1B1F), 38 | onSurface = Color(0xFF1C1B1F), 39 | */ 40 | ) 41 | 42 | @Composable 43 | fun WXComposeXXXTheme( 44 | darkTheme: Boolean = isSystemInDarkTheme(), 45 | // Dynamic color is available on Android 12+ 46 | dynamicColor: Boolean = true, 47 | content: @Composable () -> Unit 48 | ) { 49 | val colorScheme = when { 50 | dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { 51 | val context = LocalContext.current 52 | if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) 53 | } 54 | 55 | darkTheme -> DarkColorScheme 56 | else -> LightColorScheme 57 | } 58 | 59 | MaterialTheme( 60 | colorScheme = colorScheme, 61 | typography = Typography, 62 | content = content 63 | ) 64 | } -------------------------------------------------------------------------------- /WX-Compose-PluginImpl/src/main/java/com/wx/compose/plugin/theme/Type.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.theme 2 | 3 | import androidx.compose.material3.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 | bodyLarge = TextStyle( 12 | fontFamily = FontFamily.Default, 13 | fontWeight = FontWeight.Normal, 14 | fontSize = 16.sp, 15 | lineHeight = 24.sp, 16 | letterSpacing = 0.5.sp 17 | ) 18 | /* Other default text styles to override 19 | titleLarge = TextStyle( 20 | fontFamily = FontFamily.Default, 21 | fontWeight = FontWeight.Normal, 22 | fontSize = 22.sp, 23 | lineHeight = 28.sp, 24 | letterSpacing = 0.sp 25 | ), 26 | labelSmall = TextStyle( 27 | fontFamily = FontFamily.Default, 28 | fontWeight = FontWeight.Medium, 29 | fontSize = 11.sp, 30 | lineHeight = 16.sp, 31 | letterSpacing = 0.5.sp 32 | ) 33 | */ 34 | ) -------------------------------------------------------------------------------- /WX-Compose-PluginImpl/src/test/java/com/wx/compose/plugin/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin 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 | } -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.android.application) 3 | alias(libs.plugins.jetbrains.kotlin.android) 4 | alias(libs.plugins.compose.compiler) 5 | } 6 | 7 | android { 8 | namespace 'com.wx.compose.plugin' 9 | compileSdk 34 10 | 11 | defaultConfig { 12 | applicationId "com.wx.compose.plugin" 13 | minSdk 24 14 | targetSdk 34 15 | versionCode 1 16 | versionName "1.0" 17 | 18 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 19 | } 20 | signingConfigs { 21 | create("release") { 22 | storeFile = file("./wx_compose_plugin.jks") 23 | storePassword = "123456" 24 | keyAlias = "wx_compose_plugin" 25 | keyPassword = "123456" 26 | } 27 | } 28 | 29 | buildTypes { 30 | release { 31 | shrinkResources true 32 | minifyEnabled true 33 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 34 | 'proguard-rules.pro' 35 | signingConfig = signingConfigs.getByName("release") 36 | } 37 | 38 | applicationVariants.all { variant -> 39 | variant.outputs.all { 40 | outputFileName = "wx_compose_plugin${variant.buildType.name}.apk" 41 | } 42 | } 43 | } 44 | compileOptions { 45 | sourceCompatibility JavaVersion.VERSION_1_8 46 | targetCompatibility JavaVersion.VERSION_1_8 47 | } 48 | kotlinOptions { 49 | jvmTarget = '1.8' 50 | } 51 | buildFeatures { 52 | compose = true 53 | } 54 | composeOptions { 55 | kotlinCompilerExtensionVersion = "1.7.0" 56 | } 57 | } 58 | 59 | dependencies { 60 | 61 | implementation(libs.androidx.core.ktx) 62 | implementation(libs.androidx.lifecycle.runtime.ktx) 63 | implementation(libs.androidx.activity.compose) 64 | implementation(platform(libs.androidx.compose.bom)) 65 | implementation(libs.androidx.ui) 66 | implementation(libs.androidx.ui.graphics) 67 | implementation(libs.androidx.ui.tooling.preview) 68 | implementation(libs.androidx.material3) 69 | // implementation(libs.androidx.constraintlayout) 70 | implementation libs.androidx.constraintlayout.compose 71 | implementation libs.androidx.runtime.livedata 72 | implementation libs.coil.compose 73 | implementation libs.androidx.navigation.compose 74 | implementation libs.androidx.navigation.runtime.ktx 75 | implementation libs.androidx.compose.material3.adaptive.navigation 76 | implementation libs.androidx.compose.material3.adaptive 77 | implementation libs.androidx.compose.material3.adaptive.layout 78 | implementation libs.androidx.compose.material3.navigationSuite 79 | implementation libs.androidx.compose.material3.windowSizeClass 80 | implementation(libs.glide) 81 | implementation libs.collapsing.toolbar.scaffold 82 | 83 | implementation project(path: ':WX-Compose-IPlugin') 84 | 85 | implementation(libs.wgllss.scroll.view)//自动滚动视图 86 | 87 | // implementation libs.constraintlayout 88 | 89 | 90 | // testImplementation(libs.junit) 91 | // androidTestImplementation(libs.androidx.junit) 92 | // androidTestImplementation(libs.androidx.espresso.core) 93 | // androidTestImplementation(platform(libs.androidx.compose.bom)) 94 | // androidTestImplementation(libs.androidx.ui.test.junit4) 95 | // debugImplementation(libs.androidx.ui.tooling) 96 | // debugImplementation(libs.androidx.ui.test.manifest) 97 | } -------------------------------------------------------------------------------- /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/wx/compose/plugin/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin 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.wx.compose.plugin", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 24 | 25 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 39 | 42 | 43 | 46 | 49 | 52 | 55 | 58 | 61 | 64 | 67 | 70 | 73 | 76 | 79 | 82 | 85 | 88 | 91 | 94 | 97 | 100 | 103 | 106 | 109 | 112 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /app/src/main/assets/vv.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wgllss/WX-Compose-Plugin/f6d693f1a5b1d34cb5b3972c27e0b68101953a69/app/src/main/assets/vv.mp3 -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/MyApp.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin 2 | 3 | import android.app.Application 4 | 5 | class MyApp : Application() { 6 | 7 | companion object { 8 | lateinit var application: Application 9 | } 10 | 11 | override fun onCreate() { 12 | super.onCreate() 13 | application = this 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/CollapsableActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.enableEdgeToEdge 7 | import androidx.activity.viewModels 8 | import androidx.compose.foundation.ExperimentalFoundationApi 9 | import androidx.compose.foundation.Image 10 | import androidx.compose.foundation.background 11 | import androidx.compose.foundation.layout.Box 12 | import androidx.compose.foundation.layout.Column 13 | import androidx.compose.foundation.layout.PaddingValues 14 | import androidx.compose.foundation.layout.Row 15 | import androidx.compose.foundation.layout.Spacer 16 | import androidx.compose.foundation.layout.fillMaxSize 17 | import androidx.compose.foundation.layout.fillMaxWidth 18 | import androidx.compose.foundation.layout.height 19 | import androidx.compose.foundation.layout.padding 20 | import androidx.compose.foundation.lazy.LazyColumn 21 | import androidx.compose.foundation.lazy.items 22 | import androidx.compose.foundation.lazy.rememberLazyListState 23 | import androidx.compose.foundation.rememberScrollState 24 | import androidx.compose.foundation.verticalScroll 25 | import androidx.compose.material3.Button 26 | import androidx.compose.material3.Checkbox 27 | import androidx.compose.material3.MaterialTheme 28 | import androidx.compose.material3.Surface 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.alpha 38 | import androidx.compose.ui.graphics.Color 39 | import androidx.compose.ui.graphics.graphicsLayer 40 | import androidx.compose.ui.layout.ContentScale 41 | import androidx.compose.ui.res.painterResource 42 | import androidx.compose.ui.text.font.FontWeight 43 | import androidx.compose.ui.text.style.TextAlign 44 | import androidx.compose.ui.unit.dp 45 | import androidx.compose.ui.unit.sp 46 | import androidx.compose.ui.viewinterop.AndroidView 47 | import androidx.lifecycle.lifecycleScope 48 | import com.wx.compose.plugin.R 49 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 50 | import com.wx.compose1.ui.composable.baseUI 51 | import com.wx.compose1.ui.theme.WXComposePlugin 52 | import kotlinx.coroutines.launch 53 | import me.onebone.toolbar.CollapsingToolbarScaffold 54 | import me.onebone.toolbar.ExperimentalToolbarApi 55 | import me.onebone.toolbar.ScrollStrategy 56 | import me.onebone.toolbar.rememberCollapsingToolbarScaffoldState 57 | 58 | class CollapsableActivity : ComponentActivity() { 59 | 60 | val viewModel by viewModels() 61 | 62 | override fun onCreate(savedInstanceState: Bundle?) { 63 | super.onCreate(savedInstanceState) 64 | enableEdgeToEdge() 65 | lifecycleScope.launch { 66 | setContent { 67 | WXComposePlugin { 68 | // Surface(color = MaterialTheme.colorScheme.background) { 69 | // ParallaxEffect() 70 | // } 71 | MainScreen() 72 | // ParallaxEffect() 73 | } 74 | } 75 | } 76 | } 77 | } 78 | 79 | @Composable 80 | fun MainScreen() { 81 | val state = rememberCollapsingToolbarScaffoldState() 82 | CollapsingToolbarScaffold(modifier = Modifier.fillMaxSize(), state = state, scrollStrategy = ScrollStrategy.ExitUntilCollapsed, toolbar = { 83 | val textSize = (18 + (30 - 18) * state.toolbarState.progress).sp 84 | Box( 85 | modifier = Modifier 86 | .background(MaterialTheme.colorScheme.primary) 87 | .fillMaxWidth() 88 | .height(150.dp) 89 | .pin() 90 | ) 91 | Image( 92 | modifier = Modifier 93 | .parallax(0.5f) 94 | .height(300.dp) 95 | .fillMaxWidth() 96 | .pin() 97 | // .padding(16.dp) 98 | .graphicsLayer { 99 | // change alpha of Image as the toolbar expands 100 | alpha = state.toolbarState.progress 101 | }, contentScale = ContentScale.Crop, painter = painterResource(id = R.drawable.ava2), contentDescription = null 102 | ) 103 | Text( 104 | text = "Title", modifier = Modifier 105 | // .height(81.dp) 106 | .road(Alignment.CenterStart, Alignment.BottomEnd) 107 | .padding(60.dp, 36.dp, 16.dp, 16.dp), textAlign = TextAlign.Center, color = Color.White, fontSize = textSize 108 | ) 109 | }) { 110 | LazyColumn( 111 | modifier = Modifier.fillMaxWidth() 112 | ) { 113 | items(100) { 114 | Text( 115 | text = "Item $it", modifier = Modifier.padding(8.dp) 116 | ) 117 | } 118 | } 119 | 120 | // Box(modifier = Modifier 121 | // .fillMaxWidth() 122 | // .alpha(0.5f) 123 | //// .background(MaterialTheme.colorScheme.secondary) 124 | // .graphicsLayer { 125 | // // change alpha of Image as the toolbar expands 126 | // alpha = state.toolbarState.progress 127 | // } 128 | // .height(40.dp)) 129 | } 130 | } 131 | 132 | 133 | @OptIn(ExperimentalFoundationApi::class) 134 | @Composable 135 | fun ParallaxEffect() { 136 | val state = rememberCollapsingToolbarScaffoldState() 137 | 138 | var enabled by remember { mutableStateOf(true) } 139 | 140 | Box { 141 | CollapsingToolbarScaffold(modifier = Modifier.fillMaxSize(), state = state, scrollStrategy = ScrollStrategy.ExitUntilCollapsed, toolbarModifier = Modifier.background(MaterialTheme.colorScheme.primary), enabled = enabled, toolbar = { 142 | // Collapsing toolbar collapses its size as small as the that of 143 | // a smallest child. To make the toolbar collapse to 50dp, we create 144 | // a dummy Spacer composable. 145 | // You may replace it with TopAppBar or other preferred composable. 146 | Spacer( 147 | modifier = Modifier 148 | .fillMaxWidth() 149 | .background(Color.Red) 150 | .height(50.dp) 151 | ) 152 | 153 | Image( 154 | painter = painterResource(id = R.drawable.ava2), modifier = Modifier 155 | .parallax(0.5f) 156 | .height(300.dp) 157 | .fillMaxWidth() 158 | .graphicsLayer { 159 | // change alpha of Image as the toolbar expands 160 | alpha = state.toolbarState.progress 161 | }, contentScale = ContentScale.Crop, contentDescription = null 162 | ) 163 | }) { 164 | LazyColumn( 165 | modifier = Modifier.fillMaxSize() 166 | ) { 167 | stickyHeader { 168 | Text( 169 | modifier = Modifier 170 | .fillMaxWidth() 171 | .height(81.dp) 172 | .align(Alignment.Center) 173 | // .background(Color.Red) 174 | , text = "吸顶标题栏", fontWeight = FontWeight.Bold 175 | ) 176 | } 177 | items(List(100) { "Hello World!! $it" }) { 178 | Text( 179 | text = it, modifier = Modifier 180 | .fillMaxWidth() 181 | .padding(4.dp) 182 | ) 183 | } 184 | } 185 | 186 | @OptIn(ExperimentalToolbarApi::class) Button(modifier = Modifier 187 | .padding(16.dp) 188 | .align(Alignment.BottomEnd), onClick = { }) { 189 | Text(text = "Floating Button!") 190 | } 191 | } 192 | 193 | // Row( 194 | // verticalAlignment = Alignment.CenterVertically 195 | // ) { 196 | //// Checkbox(checked = enabled, onCheckedChange = { enabled = !enabled }) 197 | // 198 | // Text( 199 | // modifier = Modifier 200 | // .fillMaxWidth() 201 | // .height(50.dp) 202 | // .align(Alignment.CenterVertically) 203 | //// .background(Color.Red) 204 | // , text = "Enable collapse/expand", fontWeight = FontWeight.Bold 205 | // ) 206 | // } 207 | } 208 | } 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/ComposeDHListActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.enableEdgeToEdge 7 | import androidx.activity.viewModels 8 | import androidx.compose.runtime.Composable 9 | import androidx.compose.runtime.getValue 10 | import androidx.compose.runtime.livedata.observeAsState 11 | import androidx.lifecycle.lifecycleScope 12 | import com.wx.compose.plugin.viewmodel.DhListViewModel 13 | import com.wx.compose1.ui.theme.WXComposePlugin 14 | import com.wx.view.HorizontalScroll 15 | import kotlinx.coroutines.launch 16 | 17 | class ComposeDHListActivity : ComponentActivity() { 18 | 19 | val viewModel by viewModels() 20 | 21 | override fun onCreate(savedInstanceState: Bundle?) { 22 | super.onCreate(savedInstanceState) 23 | enableEdgeToEdge() 24 | lifecycleScope.launch { 25 | setContent { 26 | WXComposePlugin { 27 | HorizontalScrollView(viewModel = viewModel) 28 | } 29 | } 30 | } 31 | viewModel.add() 32 | } 33 | } 34 | 35 | @Composable 36 | fun HorizontalScrollView(viewModel: DhListViewModel) { 37 | val datas by viewModel.datas.observeAsState() 38 | datas?.let { 39 | HorizontalScroll(it, it.list) 40 | // HorizontalScroll(it, it.list, onPlayComplete = { 41 | // //滚动到右边,背景音乐播放结束 42 | // }) { data: TopDataSource, index: Int, size: Int -> 43 | // //真正itemView 布局compose,可自定义 44 | // RealItemView(data, it.itemWidth, index, size, it) 45 | // } 46 | } 47 | } 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/ComposeHListActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.enableEdgeToEdge 7 | import androidx.activity.viewModels 8 | import androidx.compose.foundation.Image 9 | import androidx.compose.foundation.background 10 | import androidx.compose.foundation.border 11 | import androidx.compose.foundation.horizontalScroll 12 | import androidx.compose.foundation.layout.Column 13 | import androidx.compose.foundation.layout.PaddingValues 14 | import androidx.compose.foundation.layout.Row 15 | import androidx.compose.foundation.layout.fillMaxHeight 16 | import androidx.compose.foundation.layout.fillMaxWidth 17 | import androidx.compose.foundation.layout.height 18 | import androidx.compose.foundation.layout.padding 19 | import androidx.compose.foundation.layout.size 20 | import androidx.compose.foundation.layout.width 21 | import androidx.compose.foundation.layout.wrapContentHeight 22 | import androidx.compose.foundation.layout.wrapContentWidth 23 | import androidx.compose.foundation.lazy.LazyColumn 24 | import androidx.compose.foundation.lazy.LazyRow 25 | import androidx.compose.foundation.lazy.items 26 | import androidx.compose.foundation.rememberScrollState 27 | import androidx.compose.foundation.shape.RoundedCornerShape 28 | import androidx.compose.foundation.verticalScroll 29 | import androidx.compose.material3.Text 30 | import androidx.compose.runtime.Composable 31 | import androidx.compose.runtime.getValue 32 | import androidx.compose.runtime.livedata.observeAsState 33 | import androidx.compose.ui.Alignment 34 | import androidx.compose.ui.Modifier 35 | import androidx.compose.ui.graphics.Color 36 | import androidx.compose.ui.graphics.SolidColor 37 | import androidx.compose.ui.layout.ContentScale 38 | import androidx.compose.ui.platform.LocalContext 39 | import androidx.compose.ui.res.painterResource 40 | import androidx.compose.ui.text.style.TextAlign 41 | import androidx.compose.ui.unit.dp 42 | import androidx.compose.ui.unit.sp 43 | import androidx.lifecycle.lifecycleScope 44 | import coil.compose.AsyncImage 45 | import coil.compose.rememberAsyncImagePainter 46 | import coil.request.ImageRequest 47 | import com.wx.compose1.ui.composable.baseUI 48 | import com.wx.compose1.ui.theme.WXComposePlugin 49 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 50 | import kotlinx.coroutines.launch 51 | 52 | class ComposeHListActivity : ComponentActivity() { 53 | 54 | val viewModel by viewModels() 55 | 56 | override fun onCreate(savedInstanceState: Bundle?) { 57 | super.onCreate(savedInstanceState) 58 | enableEdgeToEdge() 59 | lifecycleScope.launch { 60 | setContent { 61 | WXComposePlugin { 62 | baseUI(content = { paddingvalues -> 63 | ListExample2(paddingvalues, viewModel) 64 | }, onClick = { 65 | finish() 66 | }) 67 | } 68 | } 69 | } 70 | viewModel.add() 71 | } 72 | } 73 | 74 | @Composable 75 | fun ListExample2(innerPadding: PaddingValues, viewModel: ComposeViewModel) { 76 | val datas by viewModel.datas.observeAsState(initial = emptyList()) 77 | LazyRow( 78 | modifier = Modifier 79 | .fillMaxWidth() 80 | .wrapContentHeight() 81 | .padding(innerPadding) 82 | .background(Color.Red) 83 | ) { 84 | items(datas) { data -> 85 | Column( 86 | modifier = Modifier 87 | .width(80.dp) 88 | .verticalScroll(rememberScrollState()) 89 | .fillMaxHeight(), horizontalAlignment = Alignment.CenterHorizontally 90 | ) { 91 | Image( 92 | painter = painterResource(id = data.resID), contentDescription = "小姐姐", modifier = Modifier 93 | .wrapContentWidth() 94 | .size(80.dp) 95 | .padding(5.dp), contentScale = ContentScale.Fit 96 | ) 97 | AsyncImage( 98 | modifier = Modifier.wrapContentWidth(), model = data.imgUrl, contentDescription = "", contentScale = ContentScale.Crop 99 | ) 100 | val modelBuilder = ImageRequest.Builder(LocalContext.current).data(data.imgUrl ?: "").crossfade(false).allowHardware(true).build() 101 | Image( 102 | painter = rememberAsyncImagePainter(model = modelBuilder), contentDescription = "小姐姐", modifier = Modifier 103 | .wrapContentWidth() 104 | .size(80.dp) 105 | .padding(5.dp), contentScale = ContentScale.Crop 106 | ) 107 | Text( 108 | modifier = Modifier 109 | .wrapContentWidth() 110 | .fillMaxHeight() 111 | .background(Color.Yellow) 112 | .border(2.dp, SolidColor(Color.Green), RoundedCornerShape(20.dp)) 113 | .padding(0.dp, 5.dp, 0.dp, 0.dp), 114 | fontSize = 16.sp, 115 | text = data.title, 116 | textAlign = TextAlign.Center, 117 | color = Color.Magenta, 118 | softWrap = true 119 | ) 120 | Text( 121 | modifier = Modifier 122 | .wrapContentWidth() 123 | .fillMaxHeight() 124 | .background(Color.Yellow) 125 | .border(2.dp, SolidColor(Color.Green), RoundedCornerShape(20.dp)) 126 | .padding(0.dp, 5.dp, 0.dp, 0.dp), fontSize = 16.sp, text = data.title, textAlign = TextAlign.Center, color = Color.Magenta 127 | ) 128 | } 129 | } 130 | } 131 | } 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/ComposeListActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.enableEdgeToEdge 7 | import androidx.activity.viewModels 8 | import androidx.compose.foundation.Image 9 | import androidx.compose.foundation.background 10 | import androidx.compose.foundation.border 11 | import androidx.compose.foundation.horizontalScroll 12 | import androidx.compose.foundation.layout.PaddingValues 13 | import androidx.compose.foundation.layout.Row 14 | import androidx.compose.foundation.layout.fillMaxHeight 15 | import androidx.compose.foundation.layout.fillMaxWidth 16 | import androidx.compose.foundation.layout.height 17 | import androidx.compose.foundation.layout.padding 18 | import androidx.compose.foundation.layout.size 19 | import androidx.compose.foundation.layout.wrapContentWidth 20 | import androidx.compose.foundation.lazy.LazyColumn 21 | import androidx.compose.foundation.lazy.items 22 | import androidx.compose.foundation.rememberScrollState 23 | import androidx.compose.foundation.shape.RoundedCornerShape 24 | import androidx.compose.material3.Text 25 | import androidx.compose.runtime.Composable 26 | import androidx.compose.runtime.getValue 27 | import androidx.compose.runtime.livedata.observeAsState 28 | import androidx.compose.ui.Alignment 29 | import androidx.compose.ui.Modifier 30 | import androidx.compose.ui.graphics.Color 31 | import androidx.compose.ui.graphics.ImageBitmap 32 | import androidx.compose.ui.graphics.SolidColor 33 | import androidx.compose.ui.layout.ContentScale 34 | import androidx.compose.ui.platform.LocalContext 35 | import androidx.compose.ui.res.imageResource 36 | import androidx.compose.ui.res.painterResource 37 | import androidx.compose.ui.text.style.TextAlign 38 | import androidx.compose.ui.unit.dp 39 | import androidx.compose.ui.unit.sp 40 | import androidx.lifecycle.lifecycleScope 41 | import coil.compose.AsyncImage 42 | import coil.compose.rememberAsyncImagePainter 43 | import coil.request.ImageRequest 44 | import com.wx.compose1.ui.composable.baseUI 45 | import com.wx.compose1.ui.theme.WXComposePlugin 46 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 47 | import kotlinx.coroutines.launch 48 | 49 | class ComposeListActivity : ComponentActivity() { 50 | 51 | val viewModel by viewModels() 52 | 53 | override fun onCreate(savedInstanceState: Bundle?) { 54 | super.onCreate(savedInstanceState) 55 | enableEdgeToEdge() 56 | lifecycleScope.launch { 57 | setContent { 58 | WXComposePlugin { 59 | baseUI( content = { paddingvalues -> 60 | ListExample(paddingvalues, viewModel) 61 | }, onClick = { 62 | viewModel.add() 63 | }) 64 | } 65 | } 66 | } 67 | viewModel.add() 68 | } 69 | } 70 | 71 | @Composable 72 | fun ListExample(innerPadding: PaddingValues, viewModel: ComposeViewModel) { 73 | val datas by viewModel.datas.observeAsState(initial = emptyList()) 74 | LazyColumn( 75 | modifier = Modifier 76 | .fillMaxWidth() 77 | .fillMaxHeight() 78 | .padding(innerPadding) 79 | .background(Color.Red) 80 | ) { 81 | items(datas) { data -> 82 | Row( 83 | modifier = Modifier 84 | .fillMaxWidth() 85 | .horizontalScroll(rememberScrollState()) 86 | .height(80.dp), verticalAlignment = Alignment.CenterVertically 87 | ) { 88 | Image( 89 | painter = painterResource(id = data.resID), contentDescription = "小姐姐", modifier = Modifier 90 | .size(80.dp) 91 | .padding(5.dp), contentScale = ContentScale.Fit 92 | ) 93 | AsyncImage( 94 | model = data.imgUrl, contentDescription = "", contentScale = ContentScale.Crop 95 | ) 96 | val modelBuilder = ImageRequest.Builder(LocalContext.current).data(data.imgUrl ?: "").crossfade(false).allowHardware(true).build() 97 | Image( 98 | painter = rememberAsyncImagePainter(model = modelBuilder), contentDescription = "小姐姐", modifier = Modifier 99 | .size(80.dp) 100 | .padding(5.dp), contentScale = ContentScale.Crop 101 | ) 102 | Text( 103 | modifier = Modifier 104 | .wrapContentWidth() 105 | .height(60.dp) 106 | .background(Color.Yellow) 107 | .border(2.dp, SolidColor(Color.Green), RoundedCornerShape(20.dp)) 108 | .padding(0.dp, 5.dp, 0.dp, 0.dp), fontSize = 16.sp, text = data.title, textAlign = TextAlign.Center, color = Color.Magenta 109 | ) 110 | Text( 111 | modifier = Modifier 112 | .wrapContentWidth() 113 | .height(60.dp) 114 | .background(Color.Yellow) 115 | .border(2.dp, SolidColor(Color.Green), RoundedCornerShape(20.dp)) 116 | .padding(0.dp, 5.dp, 0.dp, 0.dp), fontSize = 16.sp, text = data.title, textAlign = TextAlign.Center, color = Color.Magenta 117 | ) 118 | } 119 | } 120 | } 121 | } 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/ComposePluginActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.enableEdgeToEdge 7 | import androidx.activity.viewModels 8 | import androidx.compose.foundation.Image 9 | import androidx.compose.foundation.background 10 | import androidx.compose.foundation.layout.Box 11 | import androidx.compose.foundation.layout.Column 12 | import androidx.compose.foundation.layout.Row 13 | import androidx.compose.foundation.layout.Spacer 14 | import androidx.compose.foundation.layout.fillMaxSize 15 | import androidx.compose.foundation.layout.fillMaxWidth 16 | import androidx.compose.foundation.layout.height 17 | import androidx.compose.foundation.layout.padding 18 | import androidx.compose.foundation.lazy.LazyColumn 19 | import androidx.compose.foundation.lazy.items 20 | import androidx.compose.foundation.lazy.rememberLazyListState 21 | import androidx.compose.foundation.rememberScrollState 22 | import androidx.compose.foundation.verticalScroll 23 | import androidx.compose.material3.Button 24 | import androidx.compose.material3.Checkbox 25 | import androidx.compose.material3.MaterialTheme 26 | import androidx.compose.material3.Text 27 | import androidx.compose.runtime.Composable 28 | import androidx.compose.runtime.getValue 29 | import androidx.compose.runtime.mutableStateOf 30 | import androidx.compose.runtime.remember 31 | import androidx.compose.runtime.setValue 32 | import androidx.compose.ui.Alignment 33 | import androidx.compose.ui.Modifier 34 | import androidx.compose.ui.draw.alpha 35 | import androidx.compose.ui.graphics.Color 36 | import androidx.compose.ui.graphics.graphicsLayer 37 | import androidx.compose.ui.layout.ContentScale 38 | import androidx.compose.ui.res.painterResource 39 | import androidx.compose.ui.text.font.FontWeight 40 | import androidx.compose.ui.unit.dp 41 | import androidx.compose.ui.unit.sp 42 | import androidx.lifecycle.lifecycleScope 43 | import com.wx.compose.plugin.ICompose 44 | import com.wx.compose.plugin.R 45 | import com.wx.compose.plugin.classloader.WXClassLoader 46 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 47 | import com.wx.compose1.ui.theme.WXComposePlugin 48 | import kotlinx.coroutines.launch 49 | import me.onebone.toolbar.CollapsingToolbarScaffold 50 | import me.onebone.toolbar.ExperimentalToolbarApi 51 | import me.onebone.toolbar.ScrollStrategy 52 | import me.onebone.toolbar.rememberCollapsingToolbarScaffoldState 53 | import java.io.File 54 | 55 | class ComposePluginActivity : ComponentActivity() { 56 | 57 | val viewModel by viewModels() 58 | 59 | override fun onCreate(savedInstanceState: Bundle?) { 60 | super.onCreate(savedInstanceState) 61 | enableEdgeToEdge() 62 | getPluginPath()?.let { 63 | WXClassLoader(it, null, classLoader).getInterface( 64 | ICompose::class.java, "com.wx.compose.plugin.compose.PluginComposeImpl" 65 | ).setComposeContent(this@ComposePluginActivity) 66 | } 67 | } 68 | 69 | private fun getPluginPath(): String? { 70 | val sb = StringBuilder(filesDir.absolutePath).append(File.separator).append("d_dex").append(File.separator).append("compose_plugin_lib_dex") 71 | val file = File(sb.toString()) 72 | if (!file.exists()) { 73 | val fileDir = File(file.parent) 74 | if (!fileDir.exists()) { 75 | fileDir.mkdirs() 76 | } 77 | return null 78 | } 79 | return sb.toString() 80 | } 81 | } 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/GirdLayoutActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import android.widget.Toast 5 | import androidx.activity.ComponentActivity 6 | import androidx.activity.compose.setContent 7 | import androidx.activity.enableEdgeToEdge 8 | import androidx.activity.viewModels 9 | import androidx.compose.foundation.Image 10 | import androidx.compose.foundation.background 11 | import androidx.compose.foundation.border 12 | import androidx.compose.foundation.clickable 13 | import androidx.compose.foundation.horizontalScroll 14 | import androidx.compose.foundation.layout.Box 15 | import androidx.compose.foundation.layout.Column 16 | import androidx.compose.foundation.layout.ExperimentalLayoutApi 17 | import androidx.compose.foundation.layout.FlowColumn 18 | import androidx.compose.foundation.layout.PaddingValues 19 | import androidx.compose.foundation.layout.Row 20 | import androidx.compose.foundation.layout.fillMaxHeight 21 | import androidx.compose.foundation.layout.fillMaxWidth 22 | import androidx.compose.foundation.layout.height 23 | import androidx.compose.foundation.layout.offset 24 | import androidx.compose.foundation.layout.padding 25 | import androidx.compose.foundation.layout.size 26 | import androidx.compose.foundation.layout.wrapContentHeight 27 | import androidx.compose.foundation.layout.wrapContentWidth 28 | import androidx.compose.foundation.lazy.grid.GridCells 29 | import androidx.compose.foundation.lazy.grid.LazyVerticalGrid 30 | import androidx.compose.foundation.lazy.grid.items 31 | import androidx.compose.foundation.rememberScrollState 32 | import androidx.compose.foundation.shape.RoundedCornerShape 33 | import androidx.compose.foundation.verticalScroll 34 | import androidx.compose.material3.Button 35 | import androidx.compose.material3.Icon 36 | import androidx.compose.material3.Text 37 | import androidx.compose.runtime.Composable 38 | import androidx.compose.runtime.getValue 39 | import androidx.compose.runtime.livedata.observeAsState 40 | import androidx.compose.runtime.mutableStateOf 41 | import androidx.compose.runtime.remember 42 | import androidx.compose.runtime.setValue 43 | import androidx.compose.ui.Alignment 44 | import androidx.compose.ui.Modifier 45 | import androidx.compose.ui.graphics.Color 46 | import androidx.compose.ui.graphics.SolidColor 47 | import androidx.compose.ui.layout.ContentScale 48 | import androidx.compose.ui.platform.LocalContext 49 | import androidx.compose.ui.res.painterResource 50 | import androidx.compose.ui.text.TextStyle 51 | import androidx.compose.ui.text.style.TextAlign 52 | import androidx.compose.ui.tooling.preview.Preview 53 | import androidx.compose.ui.unit.dp 54 | import androidx.compose.ui.unit.sp 55 | import androidx.constraintlayout.compose.ConstraintLayout 56 | import androidx.lifecycle.lifecycleScope 57 | import coil.compose.AsyncImage 58 | import coil.compose.rememberAsyncImagePainter 59 | import coil.request.ImageRequest 60 | import com.wx.compose.plugin.R 61 | import com.wx.compose1.ui.composable.baseUI 62 | import com.wx.compose1.ui.theme.WXComposePlugin 63 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 64 | import kotlinx.coroutines.launch 65 | 66 | class GirdLayoutActivity : ComponentActivity() { 67 | 68 | val viewModel by viewModels() 69 | 70 | override fun onCreate(savedInstanceState: Bundle?) { 71 | super.onCreate(savedInstanceState) 72 | enableEdgeToEdge() 73 | lifecycleScope.launch { 74 | setContent { 75 | WXComposePlugin { 76 | baseUI(content = { paddingvalues -> 77 | girdLayoutExample(paddingvalues, viewModel) 78 | }, onClick = { 79 | viewModel.add() 80 | }) 81 | } 82 | } 83 | } 84 | viewModel.add() 85 | } 86 | } 87 | 88 | 89 | @Composable 90 | fun girdLayoutExample(innerPadding: PaddingValues, viewModel: ComposeViewModel) { 91 | val datas by viewModel.datas.observeAsState(initial = emptyList()) 92 | LazyVerticalGrid( 93 | modifier = Modifier 94 | .fillMaxWidth() 95 | .fillMaxHeight() 96 | // .verticalScroll(rememberScrollState()) 97 | , columns = GridCells.Fixed(2) 98 | ) { 99 | items(datas) { data -> 100 | Row( 101 | modifier = Modifier 102 | .fillMaxWidth() 103 | .horizontalScroll(rememberScrollState()) 104 | .height(80.dp), verticalAlignment = Alignment.CenterVertically 105 | ) { 106 | Image( 107 | painter = painterResource(id = data.resID), contentDescription = "小姐姐", modifier = Modifier 108 | .size(80.dp) 109 | .padding(5.dp), contentScale = ContentScale.Fit 110 | ) 111 | AsyncImage( 112 | model = data.imgUrl, contentDescription = "", contentScale = ContentScale.Crop 113 | ) 114 | val modelBuilder = ImageRequest.Builder(LocalContext.current).data(data.imgUrl ?: "").crossfade(false).allowHardware(true).build() 115 | Image( 116 | painter = rememberAsyncImagePainter(model = modelBuilder), contentDescription = "小姐姐", modifier = Modifier 117 | .size(80.dp) 118 | .padding(5.dp), contentScale = ContentScale.Crop 119 | ) 120 | } 121 | } 122 | } 123 | } 124 | 125 | //@Preview 126 | //@Composable 127 | //fun girdLayoutPreview(innerPadding: PaddingValues = PaddingValues(0.dp)) { 128 | // WXComposePlugin { 129 | // girdLayoutExample(innerPadding) 130 | // } 131 | //} -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/HorizontalPagerLayoutActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.enableEdgeToEdge 7 | import androidx.activity.viewModels 8 | import androidx.compose.foundation.background 9 | import androidx.compose.foundation.layout.Box 10 | import androidx.compose.foundation.layout.PaddingValues 11 | import androidx.compose.foundation.layout.aspectRatio 12 | import androidx.compose.foundation.layout.fillMaxHeight 13 | import androidx.compose.foundation.layout.fillMaxWidth 14 | import androidx.compose.foundation.layout.padding 15 | import androidx.compose.foundation.pager.HorizontalPager 16 | import androidx.compose.foundation.pager.rememberPagerState 17 | import androidx.compose.material3.Text 18 | import androidx.compose.runtime.Composable 19 | import androidx.compose.ui.Alignment 20 | import androidx.compose.ui.Modifier 21 | import androidx.compose.ui.graphics.Color 22 | import androidx.compose.ui.unit.dp 23 | import androidx.compose.ui.unit.sp 24 | import androidx.lifecycle.lifecycleScope 25 | import com.wx.compose1.ui.composable.baseUI 26 | import com.wx.compose1.ui.theme.WXComposePlugin 27 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 28 | import kotlinx.coroutines.launch 29 | 30 | class HorizontalPagerLayoutActivity : ComponentActivity() { 31 | 32 | val viewModel by viewModels() 33 | 34 | override fun onCreate(savedInstanceState: Bundle?) { 35 | super.onCreate(savedInstanceState) 36 | enableEdgeToEdge() 37 | lifecycleScope.launch { 38 | setContent { 39 | WXComposePlugin { 40 | baseUI( content = { paddingvalues -> 41 | ViewPageLayout2Example(paddingvalues, viewModel) 42 | }, onClick = { 43 | viewModel.add() 44 | }) 45 | } 46 | } 47 | } 48 | viewModel.add() 49 | } 50 | } 51 | 52 | 53 | @Composable 54 | fun ViewPageLayout2Example(innerPadding: PaddingValues, viewModel: ComposeViewModel) { 55 | val state = rememberPagerState(initialPage = 1) { 5 } 56 | HorizontalPager( 57 | state = state, modifier = Modifier 58 | .fillMaxWidth() 59 | .fillMaxHeight() 60 | ) { page -> 61 | Box( 62 | modifier = Modifier 63 | .padding(10.dp) 64 | .background(Color.Red) 65 | .fillMaxWidth() 66 | .fillMaxHeight() 67 | .aspectRatio(1f), contentAlignment = Alignment.Center 68 | ) { 69 | Text(text = page.toString(), fontSize = 32.sp) 70 | } 71 | } 72 | } 73 | 74 | //@Preview 75 | //@Composable 76 | //fun girdLayoutPreview(innerPadding: PaddingValues = PaddingValues(0.dp)) { 77 | // WXComposePlugin { 78 | // girdLayoutExample(innerPadding) 79 | // } 80 | //} -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import android.widget.Toast 6 | import androidx.activity.ComponentActivity 7 | import androidx.activity.compose.setContent 8 | import androidx.activity.enableEdgeToEdge 9 | import androidx.activity.viewModels 10 | import androidx.compose.foundation.background 11 | import androidx.compose.foundation.layout.PaddingValues 12 | import androidx.compose.foundation.layout.fillMaxHeight 13 | import androidx.compose.foundation.layout.fillMaxWidth 14 | import androidx.compose.foundation.layout.height 15 | import androidx.compose.foundation.layout.padding 16 | import androidx.compose.foundation.lazy.grid.GridCells 17 | import androidx.compose.foundation.lazy.grid.LazyVerticalGrid 18 | import androidx.compose.foundation.lazy.grid.items 19 | import androidx.compose.material3.Button 20 | import androidx.compose.material3.Text 21 | import androidx.compose.runtime.Composable 22 | import androidx.compose.runtime.getValue 23 | import androidx.compose.runtime.livedata.observeAsState 24 | import androidx.compose.ui.Modifier 25 | import androidx.compose.ui.graphics.Color 26 | import androidx.compose.ui.platform.LocalContext 27 | import androidx.compose.ui.unit.dp 28 | import androidx.lifecycle.lifecycleScope 29 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 30 | import com.wx.compose1.ui.composable.baseUI 31 | import com.wx.compose1.ui.theme.WXComposePlugin 32 | import kotlinx.coroutines.launch 33 | 34 | class MainActivity : ComponentActivity() { 35 | val viewModel by viewModels() 36 | 37 | override fun onCreate(savedInstanceState: Bundle?) { 38 | super.onCreate(savedInstanceState) 39 | enableEdgeToEdge() 40 | lifecycleScope.launch { 41 | setContent { 42 | WXComposePlugin { 43 | baseUI(content = { paddingvalues -> 44 | mainUI(paddingvalues, viewModel) 45 | }, onClick = { 46 | Toast.makeText(this@MainActivity, "点击我干嘛", Toast.LENGTH_SHORT).show() 47 | }) 48 | } 49 | } 50 | } 51 | viewModel.initUIData() 52 | } 53 | } 54 | 55 | @Composable 56 | fun mainUI(innerPadding: PaddingValues, viewModel: ComposeViewModel) { 57 | val context = LocalContext.current 58 | val mainItmes by viewModel.mainItmes.observeAsState(initial = emptyList()) 59 | LazyVerticalGrid( 60 | modifier = Modifier 61 | .padding(innerPadding) 62 | .background(Color.Yellow) 63 | // .verticalScroll(rememberScrollState()) 64 | // .padding(5.dp) 65 | .fillMaxWidth() 66 | .fillMaxHeight() 67 | // verticalArrangement = Arrangement.spacedBy(16.dp), 68 | , columns = GridCells.Fixed(2) 69 | ) { 70 | items(mainItmes) { item -> 71 | Button( 72 | onClick = { 73 | context.startActivity(Intent(context, item.clazz)) 74 | }, modifier = Modifier 75 | .fillMaxWidth() 76 | .height(50.dp) 77 | .padding(5.dp) 78 | ) { 79 | Text(item.title) 80 | } 81 | 82 | // Button( 83 | // onClick = { 84 | // context.startActivity(Intent(context, ComposeListActivity::class.java)) 85 | // }, modifier = Modifier 86 | // .padding(0.dp, 8.dp, 0.dp, 0.dp) 87 | // .fillMaxWidth() 88 | // .height(50.dp) 89 | // ) { 90 | // Text("compose 动态列表") 91 | // } 92 | // 93 | // Button( 94 | // onClick = { 95 | // context.startActivity(Intent(context, GirdLayoutActivity::class.java)) 96 | // }, modifier = Modifier 97 | // .padding(0.dp, 8.dp, 0.dp, 0.dp) 98 | // .fillMaxWidth() 99 | // .height(50.dp) 100 | // ) { 101 | // Text("compose girdLayout") 102 | // } 103 | // 104 | // Button( 105 | // onClick = { 106 | // context.startActivity(Intent(context, ViewPageLayoutActivity::class.java)) 107 | // }, modifier = Modifier 108 | // .padding(0.dp, 8.dp, 0.dp, 0.dp) 109 | // .fillMaxWidth() 110 | // .height(50.dp) 111 | // ) { 112 | // Text("compose VerticalPager") 113 | // } 114 | // 115 | // Button( 116 | // onClick = { 117 | // context.startActivity(Intent(context, HorizontalPagerLayoutActivity::class.java)) 118 | // }, modifier = Modifier 119 | // .padding(0.dp, 8.dp, 0.dp, 0.dp) 120 | // .fillMaxWidth() 121 | // .height(50.dp) 122 | // ) { 123 | // Text("compose HorizontalPager") 124 | // } 125 | // 126 | // Button( 127 | // onClick = { 128 | // context.startActivity(Intent(context, TabLayoutActivity::class.java)) 129 | // }, modifier = Modifier 130 | // .padding(0.dp, 8.dp, 0.dp, 0.dp) 131 | // .fillMaxWidth() 132 | // .height(50.dp) 133 | // ) { 134 | // Text("compose TabLayout") 135 | // } 136 | // 137 | // Button( 138 | // onClick = { 139 | // context.startActivity(Intent(context, BottomNavigationActivity::class.java)) 140 | // }, modifier = Modifier 141 | // .padding(0.dp, 8.dp, 0.dp, 0.dp) 142 | // .fillMaxWidth() 143 | // .height(50.dp) 144 | // ) { 145 | // Text("compose BottomNavigationView") 146 | // } 147 | // 148 | // Button( 149 | // onClick = { 150 | // context.startActivity(Intent(context, BottomNavigationActivity::class.java)) 151 | // }, modifier = Modifier 152 | // .padding(0.dp, 8.dp, 0.dp, 0.dp) 153 | // .fillMaxWidth() 154 | // .height(50.dp) 155 | // ) { 156 | // Text("compose BottomNavigationView") 157 | // } 158 | } 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/ModalDrawerActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import android.webkit.WebView 5 | import androidx.activity.ComponentActivity 6 | import androidx.activity.compose.setContent 7 | import androidx.activity.enableEdgeToEdge 8 | import androidx.activity.viewModels 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.Row 13 | import androidx.compose.foundation.layout.Spacer 14 | import androidx.compose.foundation.layout.fillMaxHeight 15 | import androidx.compose.foundation.layout.fillMaxSize 16 | import androidx.compose.foundation.layout.fillMaxWidth 17 | import androidx.compose.foundation.layout.height 18 | import androidx.compose.foundation.layout.padding 19 | import androidx.compose.foundation.rememberScrollState 20 | import androidx.compose.foundation.verticalScroll 21 | import androidx.compose.material.icons.Icons 22 | import androidx.compose.material.icons.filled.AccountBox 23 | import androidx.compose.material.icons.filled.AccountCircle 24 | import androidx.compose.material.icons.filled.AddCircle 25 | import androidx.compose.material.icons.filled.ArrowBack 26 | import androidx.compose.material.icons.filled.Build 27 | import androidx.compose.material.icons.filled.CheckCircle 28 | import androidx.compose.material.icons.filled.Email 29 | import androidx.compose.material.icons.filled.ExitToApp 30 | import androidx.compose.material.icons.filled.Favorite 31 | import androidx.compose.material.icons.filled.LocationOn 32 | import androidx.compose.material.icons.filled.Lock 33 | import androidx.compose.material.icons.filled.MailOutline 34 | import androidx.compose.material.icons.filled.Menu 35 | import androidx.compose.material3.Button 36 | import androidx.compose.material3.DrawerValue 37 | import androidx.compose.material3.ExperimentalMaterial3Api 38 | import androidx.compose.material3.FloatingActionButton 39 | import androidx.compose.material3.Icon 40 | import androidx.compose.material3.IconButton 41 | import androidx.compose.material3.MaterialTheme 42 | import androidx.compose.material3.ModalDrawerSheet 43 | import androidx.compose.material3.ModalNavigationDrawer 44 | import androidx.compose.material3.NavigationBar 45 | import androidx.compose.material3.NavigationBarItem 46 | import androidx.compose.material3.NavigationDrawerItem 47 | import androidx.compose.material3.NavigationDrawerItemDefaults 48 | import androidx.compose.material3.Scaffold 49 | import androidx.compose.material3.Text 50 | import androidx.compose.material3.TopAppBar 51 | import androidx.compose.material3.TopAppBarDefaults 52 | import androidx.compose.material3.TopAppBarDefaults.mediumTopAppBarColors 53 | import androidx.compose.material3.rememberDrawerState 54 | import androidx.compose.runtime.Composable 55 | import androidx.compose.runtime.getValue 56 | import androidx.compose.runtime.mutableIntStateOf 57 | import androidx.compose.runtime.mutableStateOf 58 | import androidx.compose.runtime.remember 59 | import androidx.compose.runtime.rememberCoroutineScope 60 | import androidx.compose.runtime.setValue 61 | import androidx.compose.ui.Alignment 62 | import androidx.compose.ui.Modifier 63 | import androidx.compose.ui.graphics.Color 64 | import androidx.compose.ui.text.TextStyle 65 | import androidx.compose.ui.unit.dp 66 | import androidx.compose.ui.unit.sp 67 | import androidx.compose.ui.viewinterop.AndroidView 68 | import androidx.lifecycle.lifecycleScope 69 | import com.wx.compose1.ui.theme.WXComposePlugin 70 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 71 | import kotlinx.coroutines.launch 72 | 73 | class ModalDrawerActivity : ComponentActivity() { 74 | 75 | val viewModel by viewModels() 76 | 77 | override fun onCreate(savedInstanceState: Bundle?) { 78 | super.onCreate(savedInstanceState) 79 | enableEdgeToEdge() 80 | lifecycleScope.launch { 81 | setContent { 82 | WXComposePlugin { 83 | ModalDrawerExample() 84 | } 85 | } 86 | } 87 | // viewModel.add() 88 | } 89 | } 90 | 91 | @OptIn(ExperimentalMaterial3Api::class) 92 | @Composable 93 | fun ModalDrawerExample() { 94 | val drawerState = rememberDrawerState(DrawerValue.Closed) 95 | val scope = rememberCoroutineScope() 96 | // icons to mimic drawer destinations 97 | val items = listOf( 98 | Icons.Default.AccountCircle, 99 | Icons.Default.Email, 100 | Icons.Default.Favorite, 101 | Icons.Default.AccountBox, 102 | Icons.Default.Build, 103 | Icons.Default.LocationOn, 104 | Icons.Default.Lock, 105 | Icons.Default.CheckCircle, 106 | Icons.Default.AddCircle, 107 | Icons.Default.MailOutline, 108 | ) 109 | val selectedItem = remember { mutableStateOf(items[0]) } 110 | val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior() 111 | Scaffold(topBar = { 112 | TopAppBar(modifier = Modifier 113 | .fillMaxWidth() 114 | .background(Color.Blue) 115 | .height(81.dp), colors = mediumTopAppBarColors( 116 | containerColor = Color.Blue, 117 | titleContentColor = MaterialTheme.colorScheme.primary, 118 | ), title = { 119 | Row( 120 | modifier = Modifier 121 | .fillMaxWidth() 122 | .fillMaxHeight(), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center 123 | ) { 124 | Text(text = "compose navigation题栏", fontSize = 18.sp, color = Color.Red, style = TextStyle.Default) 125 | } 126 | }, navigationIcon = { 127 | IconButton(onClick = { 128 | scope.launch { 129 | if (drawerState.isClosed) { 130 | drawerState.open() 131 | } else { 132 | drawerState.close() 133 | } 134 | 135 | } 136 | }) { 137 | Icon( 138 | imageVector = Icons.Filled.Menu, contentDescription = "Localized description" 139 | ) 140 | } 141 | }, actions = { 142 | IconButton(onClick = { 143 | /* doSomething() */ 144 | }) { 145 | Icon(imageVector = Icons.Filled.Favorite, contentDescription = "Localized description") 146 | } 147 | }, scrollBehavior = scrollBehavior 148 | ) 149 | 150 | }) { innerPadding -> 151 | ModalNavigationDrawer(modifier = Modifier.padding(innerPadding), drawerState = drawerState, drawerContent = { 152 | ModalDrawerSheet(drawerState) { 153 | Column(Modifier.verticalScroll(rememberScrollState())) { 154 | Spacer(Modifier.height(12.dp)) 155 | items.forEach { item -> 156 | NavigationDrawerItem(icon = { 157 | Icon(item, contentDescription = null) 158 | }, label = { 159 | Text(item.name.substringAfterLast(".")) 160 | }, selected = item == selectedItem.value, onClick = { 161 | scope.launch { 162 | drawerState.close() 163 | } 164 | selectedItem.value = item 165 | }, modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding) 166 | ) 167 | } 168 | } 169 | } 170 | }, content = { 171 | Column( 172 | modifier = Modifier 173 | .fillMaxSize() 174 | .padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally 175 | ) { 176 | Text(text = if (drawerState.isClosed) ">>> Swipe >>>" else "<<< Swipe <<<") 177 | Spacer(Modifier.height(20.dp)) 178 | Button(onClick = { scope.launch { drawerState.open() } }) { Text("Click to open") } 179 | } 180 | }) 181 | } 182 | } 183 | 184 | 185 | 186 | 187 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/MutilGirdLayoutActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.enableEdgeToEdge 7 | import androidx.activity.viewModels 8 | import androidx.compose.foundation.background 9 | import androidx.compose.foundation.border 10 | import androidx.compose.foundation.layout.Arrangement 11 | import androidx.compose.foundation.layout.Box 12 | import androidx.compose.foundation.layout.PaddingValues 13 | import androidx.compose.foundation.layout.fillMaxWidth 14 | import androidx.compose.foundation.layout.height 15 | import androidx.compose.foundation.layout.padding 16 | import androidx.compose.foundation.layout.width 17 | import androidx.compose.foundation.layout.wrapContentSize 18 | import androidx.compose.foundation.lazy.LazyRow 19 | import androidx.compose.foundation.lazy.grid.GridCells 20 | import androidx.compose.foundation.lazy.grid.GridItemSpan 21 | import androidx.compose.foundation.lazy.grid.LazyVerticalGrid 22 | import androidx.compose.foundation.lazy.grid.items 23 | import androidx.compose.foundation.lazy.items 24 | import androidx.compose.material3.MaterialTheme 25 | import androidx.compose.material3.Text 26 | import androidx.compose.runtime.Composable 27 | import androidx.compose.runtime.getValue 28 | import androidx.compose.runtime.remember 29 | import androidx.compose.ui.Alignment 30 | import androidx.compose.ui.Modifier 31 | import androidx.compose.ui.graphics.Color 32 | import androidx.compose.ui.unit.dp 33 | import androidx.lifecycle.lifecycleScope 34 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 35 | import com.wx.compose1.ui.composable.baseUI 36 | import com.wx.compose1.ui.theme.WXComposePlugin 37 | import kotlinx.coroutines.launch 38 | 39 | class MutilGirdLayoutActivity : ComponentActivity() { 40 | 41 | val viewModel by viewModels() 42 | 43 | override fun onCreate(savedInstanceState: Bundle?) { 44 | super.onCreate(savedInstanceState) 45 | enableEdgeToEdge() 46 | lifecycleScope.launch { 47 | setContent { 48 | WXComposePlugin { 49 | baseUI(content = { paddingvalues -> 50 | LazyVerticalGridSpanSample(paddingvalues) 51 | }, onClick = { 52 | finish() 53 | }) 54 | } 55 | } 56 | } 57 | viewModel.add() 58 | } 59 | } 60 | 61 | @Composable 62 | fun LazyVerticalGridSpanSample(paddingValues: PaddingValues) { 63 | val sections = (0 until 25).toList().chunked(6) 64 | val items22 = remember { listOf("Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6") } 65 | 66 | LazyVerticalGrid( 67 | modifier = Modifier.padding(paddingValues), columns = GridCells.Fixed(3), horizontalArrangement = Arrangement.spacedBy(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp) 68 | ) { 69 | sections.forEachIndexed { index, items -> 70 | item(span = { GridItemSpan(maxLineSpan) }) { 71 | Text( 72 | "This is section $index", 73 | Modifier 74 | .border(1.dp, Color.Gray) 75 | .height(80.dp) 76 | .wrapContentSize() 77 | ) 78 | } 79 | items(items, span = { GridItemSpan(1) }) { 80 | Text( 81 | "Item $it", 82 | Modifier 83 | .border(1.dp, Color.Blue) 84 | .height(80.dp) 85 | .wrapContentSize() 86 | ) 87 | } 88 | 89 | item(span = { GridItemSpan(3) }) { 90 | LazyRow( 91 | modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp), contentPadding = PaddingValues(8.dp) 92 | ) { 93 | items(items22) { item -> 94 | Box( 95 | modifier = Modifier 96 | .background(Color.Green) 97 | .padding(16.dp) 98 | .width(120.dp) 99 | .height(120.dp), contentAlignment = Alignment.Center 100 | ) { 101 | Text(text = "AAA $item", color = Color.White) 102 | } 103 | } 104 | } 105 | } 106 | } 107 | } 108 | } 109 | 110 | 111 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/MutilHGirdLayoutActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.enableEdgeToEdge 7 | import androidx.activity.viewModels 8 | import androidx.compose.foundation.background 9 | import androidx.compose.foundation.border 10 | import androidx.compose.foundation.layout.Arrangement 11 | import androidx.compose.foundation.layout.Box 12 | import androidx.compose.foundation.layout.PaddingValues 13 | import androidx.compose.foundation.layout.fillMaxWidth 14 | import androidx.compose.foundation.layout.height 15 | import androidx.compose.foundation.layout.padding 16 | import androidx.compose.foundation.layout.width 17 | import androidx.compose.foundation.layout.wrapContentSize 18 | import androidx.compose.foundation.lazy.LazyColumn 19 | import androidx.compose.foundation.lazy.LazyRow 20 | import androidx.compose.foundation.lazy.grid.GridCells 21 | import androidx.compose.foundation.lazy.grid.GridItemSpan 22 | import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid 23 | import androidx.compose.foundation.lazy.grid.LazyVerticalGrid 24 | import androidx.compose.foundation.lazy.grid.items 25 | import androidx.compose.foundation.lazy.items 26 | import androidx.compose.material3.MaterialTheme 27 | import androidx.compose.material3.Text 28 | import androidx.compose.runtime.Composable 29 | import androidx.compose.runtime.getValue 30 | import androidx.compose.runtime.remember 31 | import androidx.compose.ui.Alignment 32 | import androidx.compose.ui.Modifier 33 | import androidx.compose.ui.graphics.Color 34 | import androidx.compose.ui.unit.dp 35 | import androidx.lifecycle.lifecycleScope 36 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 37 | import com.wx.compose1.ui.composable.baseUI 38 | import com.wx.compose1.ui.theme.WXComposePlugin 39 | import kotlinx.coroutines.launch 40 | 41 | class MutilHGirdLayoutActivity : ComponentActivity() { 42 | 43 | val viewModel by viewModels() 44 | 45 | override fun onCreate(savedInstanceState: Bundle?) { 46 | super.onCreate(savedInstanceState) 47 | enableEdgeToEdge() 48 | lifecycleScope.launch { 49 | setContent { 50 | WXComposePlugin { 51 | baseUI(content = { paddingvalues -> 52 | LazyVerticalGridSpanSample2(paddingvalues) 53 | }, onClick = { 54 | finish() 55 | }) 56 | } 57 | } 58 | } 59 | viewModel.add() 60 | } 61 | } 62 | 63 | @Composable 64 | fun LazyVerticalGridSpanSample2(paddingValues: PaddingValues) { 65 | val sections = (0 until 25).toList().chunked(6) 66 | val items22 = remember { listOf("Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6") } 67 | 68 | LazyHorizontalGrid( 69 | modifier = Modifier.padding(paddingValues), rows = GridCells.Fixed(3), horizontalArrangement = Arrangement.spacedBy(16.dp), verticalArrangement = Arrangement.spacedBy(16.dp) 70 | ) { 71 | sections.forEachIndexed { index, items -> 72 | item(span = { GridItemSpan(maxLineSpan) }) { 73 | Text( 74 | "This is section $index", 75 | Modifier 76 | .border(1.dp, Color.Gray) 77 | .height(80.dp) 78 | .wrapContentSize() 79 | ) 80 | } 81 | items(items, span = { GridItemSpan(1) }) { 82 | Text( 83 | "Item $it", 84 | Modifier 85 | .border(1.dp, Color.Blue) 86 | .height(80.dp) 87 | .wrapContentSize() 88 | ) 89 | } 90 | 91 | item(span = { GridItemSpan(3) }) { 92 | LazyColumn( 93 | modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(8.dp), contentPadding = PaddingValues(8.dp) 94 | ) { 95 | items(items22) { item -> 96 | Box( 97 | modifier = Modifier 98 | .background(Color.Green) 99 | .padding(16.dp) 100 | .width(120.dp) 101 | .height(120.dp), contentAlignment = Alignment.Center 102 | ) { 103 | Text(text = "AAA $item", color = Color.White) 104 | } 105 | } 106 | } 107 | } 108 | } 109 | } 110 | } 111 | 112 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/PullToRefreshActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.enableEdgeToEdge 7 | import androidx.activity.viewModels 8 | import androidx.compose.animation.core.LinearOutSlowInEasing 9 | import androidx.compose.foundation.ScrollState 10 | import androidx.compose.foundation.background 11 | import androidx.compose.foundation.layout.Arrangement 12 | import androidx.compose.foundation.layout.Box 13 | import androidx.compose.foundation.layout.Column 14 | import androidx.compose.foundation.layout.Row 15 | import androidx.compose.foundation.layout.fillMaxHeight 16 | import androidx.compose.foundation.layout.fillMaxSize 17 | import androidx.compose.foundation.layout.fillMaxWidth 18 | import androidx.compose.foundation.layout.height 19 | import androidx.compose.foundation.layout.padding 20 | import androidx.compose.foundation.lazy.LazyColumn 21 | import androidx.compose.foundation.rememberScrollState 22 | import androidx.compose.foundation.verticalScroll 23 | import androidx.compose.material.icons.Icons 24 | import androidx.compose.material.icons.filled.ArrowBack 25 | import androidx.compose.material.icons.filled.Favorite 26 | import androidx.compose.material.icons.filled.Menu 27 | import androidx.compose.material.icons.filled.Refresh 28 | import androidx.compose.material3.Button 29 | import androidx.compose.material3.ExperimentalMaterial3Api 30 | import androidx.compose.material3.FloatingActionButton 31 | import androidx.compose.material3.Icon 32 | import androidx.compose.material3.IconButton 33 | import androidx.compose.material3.ListItem 34 | import androidx.compose.material3.MaterialTheme 35 | import androidx.compose.material3.NavigationBar 36 | import androidx.compose.material3.NavigationBarItem 37 | import androidx.compose.material3.Scaffold 38 | import androidx.compose.material3.Text 39 | import androidx.compose.material3.TopAppBar 40 | import androidx.compose.material3.TopAppBarDefaults 41 | import androidx.compose.material3.TopAppBarDefaults.mediumTopAppBarColors 42 | import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults 43 | import androidx.compose.material3.pulltorefresh.pullToRefresh 44 | import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState 45 | import androidx.compose.runtime.Composable 46 | import androidx.compose.runtime.getValue 47 | import androidx.compose.runtime.mutableIntStateOf 48 | import androidx.compose.runtime.mutableStateOf 49 | import androidx.compose.runtime.remember 50 | import androidx.compose.runtime.rememberCoroutineScope 51 | import androidx.compose.runtime.setValue 52 | import androidx.compose.ui.Alignment 53 | import androidx.compose.ui.Modifier 54 | import androidx.compose.ui.graphics.Color 55 | import androidx.compose.ui.graphics.graphicsLayer 56 | import androidx.compose.ui.text.TextStyle 57 | import androidx.compose.ui.unit.dp 58 | import androidx.compose.ui.unit.sp 59 | import androidx.lifecycle.lifecycleScope 60 | import androidx.navigation.NavHostController 61 | import androidx.navigation.compose.NavHost 62 | import androidx.navigation.compose.composable 63 | import androidx.navigation.compose.rememberNavController 64 | import com.wx.compose1.ui.theme.WXComposePlugin 65 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 66 | import kotlinx.coroutines.delay 67 | import kotlinx.coroutines.launch 68 | 69 | class PullToRefreshActivity : ComponentActivity() { 70 | 71 | val viewModel by viewModels() 72 | 73 | override fun onCreate(savedInstanceState: Bundle?) { 74 | super.onCreate(savedInstanceState) 75 | enableEdgeToEdge() 76 | lifecycleScope.launch { 77 | setContent { 78 | WXComposePlugin { 79 | PullToRefreshScalingSample(onClick = { 80 | finish() 81 | }) 82 | } 83 | } 84 | } 85 | } 86 | } 87 | 88 | @OptIn(ExperimentalMaterial3Api::class) 89 | @Composable 90 | fun PullToRefreshScalingSample(onClick: () -> Unit) { 91 | var itemCount by remember { mutableStateOf(15) } 92 | var isRefreshing by remember { mutableStateOf(false) } 93 | val state = rememberPullToRefreshState() 94 | val coroutineScope = rememberCoroutineScope() 95 | 96 | 97 | val onRefresh: () -> Unit = { 98 | isRefreshing = true 99 | coroutineScope.launch { 100 | // fetch something 101 | delay(1500) 102 | itemCount += 5 103 | isRefreshing = false 104 | } 105 | } 106 | 107 | val scaleFraction = { 108 | if (isRefreshing) 1f 109 | else LinearOutSlowInEasing.transform(state.distanceFraction).coerceIn(0f, 1f) 110 | } 111 | 112 | Scaffold(modifier = Modifier.pullToRefresh( 113 | state = state, isRefreshing = isRefreshing, onRefresh = onRefresh 114 | ), topBar = { 115 | TopAppBar(title = { Text("TopAppBar") }, 116 | // Provide an accessible alternative to trigger refresh. 117 | actions = { 118 | IconButton(onClick = onRefresh) { 119 | Icon(Icons.Filled.Refresh, "Trigger Refresh") 120 | } 121 | }) 122 | }, floatingActionButton = { 123 | FloatingActionButton(onClick = onClick) { 124 | Icon( 125 | Icons.Default.ArrowBack, contentDescription = "Add", tint = Color.Red 126 | ) 127 | } 128 | }) { 129 | Box(Modifier.padding(it)) { 130 | LazyColumn(Modifier.fillMaxSize()) { 131 | if (!isRefreshing) { 132 | items(itemCount) { ListItem({ Text(text = "Item ${itemCount - it}") }) } 133 | } 134 | } 135 | Box( 136 | Modifier 137 | .align(Alignment.TopCenter) 138 | .graphicsLayer { 139 | scaleX = scaleFraction() 140 | scaleY = scaleFraction() 141 | }) { 142 | PullToRefreshDefaults.Indicator(state = state, isRefreshing = isRefreshing) 143 | } 144 | } 145 | } 146 | } 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/PullToRefreshActivity2.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.enableEdgeToEdge 7 | import androidx.activity.viewModels 8 | import androidx.compose.animation.core.LinearOutSlowInEasing 9 | import androidx.compose.foundation.ScrollState 10 | import androidx.compose.foundation.background 11 | import androidx.compose.foundation.layout.Arrangement 12 | import androidx.compose.foundation.layout.Box 13 | import androidx.compose.foundation.layout.Column 14 | import androidx.compose.foundation.layout.Row 15 | import androidx.compose.foundation.layout.fillMaxHeight 16 | import androidx.compose.foundation.layout.fillMaxSize 17 | import androidx.compose.foundation.layout.fillMaxWidth 18 | import androidx.compose.foundation.layout.height 19 | import androidx.compose.foundation.layout.padding 20 | import androidx.compose.foundation.lazy.LazyColumn 21 | import androidx.compose.foundation.rememberScrollState 22 | import androidx.compose.foundation.verticalScroll 23 | import androidx.compose.material.icons.Icons 24 | import androidx.compose.material.icons.filled.ArrowBack 25 | import androidx.compose.material.icons.filled.Favorite 26 | import androidx.compose.material.icons.filled.Menu 27 | import androidx.compose.material.icons.filled.Refresh 28 | import androidx.compose.material3.Button 29 | import androidx.compose.material3.ExperimentalMaterial3Api 30 | import androidx.compose.material3.FloatingActionButton 31 | import androidx.compose.material3.Icon 32 | import androidx.compose.material3.IconButton 33 | import androidx.compose.material3.ListItem 34 | import androidx.compose.material3.MaterialTheme 35 | import androidx.compose.material3.NavigationBar 36 | import androidx.compose.material3.NavigationBarItem 37 | import androidx.compose.material3.Scaffold 38 | import androidx.compose.material3.Text 39 | import androidx.compose.material3.TopAppBar 40 | import androidx.compose.material3.TopAppBarDefaults 41 | import androidx.compose.material3.TopAppBarDefaults.mediumTopAppBarColors 42 | import androidx.compose.material3.pulltorefresh.PullToRefreshBox 43 | import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults 44 | import androidx.compose.material3.pulltorefresh.pullToRefresh 45 | import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState 46 | import androidx.compose.runtime.Composable 47 | import androidx.compose.runtime.getValue 48 | import androidx.compose.runtime.mutableIntStateOf 49 | import androidx.compose.runtime.mutableStateOf 50 | import androidx.compose.runtime.remember 51 | import androidx.compose.runtime.rememberCoroutineScope 52 | import androidx.compose.runtime.setValue 53 | import androidx.compose.ui.Alignment 54 | import androidx.compose.ui.Modifier 55 | import androidx.compose.ui.graphics.Color 56 | import androidx.compose.ui.graphics.graphicsLayer 57 | import androidx.compose.ui.text.TextStyle 58 | import androidx.compose.ui.tooling.preview.Preview 59 | import androidx.compose.ui.unit.dp 60 | import androidx.compose.ui.unit.sp 61 | import androidx.lifecycle.lifecycleScope 62 | import androidx.navigation.NavHostController 63 | import androidx.navigation.compose.NavHost 64 | import androidx.navigation.compose.composable 65 | import androidx.navigation.compose.rememberNavController 66 | import com.wx.compose1.ui.theme.WXComposePlugin 67 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 68 | import kotlinx.coroutines.delay 69 | import kotlinx.coroutines.launch 70 | 71 | class PullToRefreshActivity2 : ComponentActivity() { 72 | 73 | val viewModel by viewModels() 74 | 75 | override fun onCreate(savedInstanceState: Bundle?) { 76 | super.onCreate(savedInstanceState) 77 | enableEdgeToEdge() 78 | lifecycleScope.launch { 79 | setContent { 80 | WXComposePlugin { 81 | PullToRefreshSample(onClick = { 82 | finish() 83 | }) 84 | } 85 | } 86 | } 87 | } 88 | } 89 | 90 | @Composable 91 | @OptIn(ExperimentalMaterial3Api::class) 92 | fun PullToRefreshSample(onClick: () -> Unit) { 93 | var itemCount by remember { mutableIntStateOf(15) } 94 | var isRefreshing by remember { mutableStateOf(false) } 95 | val state = rememberPullToRefreshState() 96 | val coroutineScope = rememberCoroutineScope() 97 | val onRefresh: () -> Unit = { 98 | isRefreshing = true 99 | coroutineScope.launch { 100 | delay(1500) 101 | itemCount += 5 102 | isRefreshing = false 103 | } 104 | } 105 | 106 | Scaffold(topBar = { 107 | TopAppBar(title = { Text("Title") }, 108 | // Provide an accessible alternative to trigger refresh. 109 | actions = { 110 | IconButton(onClick = onRefresh) { 111 | Icon(Icons.Filled.Refresh, "Trigger Refresh") 112 | } 113 | }) 114 | }, floatingActionButton = { 115 | FloatingActionButton(onClick = onClick) { 116 | Icon( 117 | Icons.Default.ArrowBack, contentDescription = "Add", tint = Color.Red 118 | ) 119 | } 120 | }) { 121 | PullToRefreshBox( 122 | modifier = Modifier.padding(it), 123 | state = state, 124 | isRefreshing = isRefreshing, 125 | onRefresh = onRefresh, 126 | ) { 127 | LazyColumn(Modifier.fillMaxSize()) { 128 | items(itemCount) { ListItem({ Text(text = "Item ${itemCount - it}") }) } 129 | } 130 | } 131 | } 132 | } 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/PullToRefreshActivity3.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.enableEdgeToEdge 7 | import androidx.activity.viewModels 8 | import androidx.compose.animation.core.LinearOutSlowInEasing 9 | import androidx.compose.foundation.ScrollState 10 | import androidx.compose.foundation.background 11 | import androidx.compose.foundation.layout.Arrangement 12 | import androidx.compose.foundation.layout.Box 13 | import androidx.compose.foundation.layout.Column 14 | import androidx.compose.foundation.layout.Row 15 | import androidx.compose.foundation.layout.fillMaxHeight 16 | import androidx.compose.foundation.layout.fillMaxSize 17 | import androidx.compose.foundation.layout.fillMaxWidth 18 | import androidx.compose.foundation.layout.height 19 | import androidx.compose.foundation.layout.padding 20 | import androidx.compose.foundation.lazy.LazyColumn 21 | import androidx.compose.foundation.rememberScrollState 22 | import androidx.compose.foundation.verticalScroll 23 | import androidx.compose.material.icons.Icons 24 | import androidx.compose.material.icons.filled.ArrowBack 25 | import androidx.compose.material.icons.filled.Favorite 26 | import androidx.compose.material.icons.filled.Menu 27 | import androidx.compose.material.icons.filled.Refresh 28 | import androidx.compose.material3.Button 29 | import androidx.compose.material3.ExperimentalMaterial3Api 30 | import androidx.compose.material3.FloatingActionButton 31 | import androidx.compose.material3.Icon 32 | import androidx.compose.material3.IconButton 33 | import androidx.compose.material3.ListItem 34 | import androidx.compose.material3.MaterialTheme 35 | import androidx.compose.material3.NavigationBar 36 | import androidx.compose.material3.NavigationBarItem 37 | import androidx.compose.material3.Scaffold 38 | import androidx.compose.material3.Text 39 | import androidx.compose.material3.TopAppBar 40 | import androidx.compose.material3.TopAppBarDefaults 41 | import androidx.compose.material3.TopAppBarDefaults.mediumTopAppBarColors 42 | import androidx.compose.material3.pulltorefresh.PullToRefreshBox 43 | import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults 44 | import androidx.compose.material3.pulltorefresh.pullToRefresh 45 | import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState 46 | import androidx.compose.runtime.Composable 47 | import androidx.compose.runtime.getValue 48 | import androidx.compose.runtime.mutableIntStateOf 49 | import androidx.compose.runtime.mutableStateOf 50 | import androidx.compose.runtime.remember 51 | import androidx.compose.runtime.rememberCoroutineScope 52 | import androidx.compose.runtime.setValue 53 | import androidx.compose.ui.Alignment 54 | import androidx.compose.ui.Modifier 55 | import androidx.compose.ui.graphics.Color 56 | import androidx.compose.ui.graphics.graphicsLayer 57 | import androidx.compose.ui.text.TextStyle 58 | import androidx.compose.ui.tooling.preview.Preview 59 | import androidx.compose.ui.unit.dp 60 | import androidx.compose.ui.unit.sp 61 | import androidx.lifecycle.ViewModel 62 | import androidx.lifecycle.lifecycleScope 63 | import androidx.lifecycle.viewModelScope 64 | import androidx.navigation.NavHostController 65 | import androidx.navigation.compose.NavHost 66 | import androidx.navigation.compose.composable 67 | import androidx.navigation.compose.rememberNavController 68 | import com.wx.compose1.ui.theme.WXComposePlugin 69 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 70 | import kotlinx.coroutines.channels.Channel 71 | import kotlinx.coroutines.delay 72 | import kotlinx.coroutines.launch 73 | 74 | class PullToRefreshActivity3 : ComponentActivity() { 75 | 76 | val viewModel by viewModels() 77 | 78 | override fun onCreate(savedInstanceState: Bundle?) { 79 | super.onCreate(savedInstanceState) 80 | enableEdgeToEdge() 81 | lifecycleScope.launch { 82 | setContent { 83 | WXComposePlugin { 84 | PullToRefreshViewModelSample(onClick = { 85 | finish() 86 | }) 87 | } 88 | } 89 | } 90 | } 91 | } 92 | 93 | @Composable 94 | @OptIn(ExperimentalMaterial3Api::class) 95 | fun PullToRefreshViewModelSample(onClick: () -> Unit) { 96 | val viewModel = remember { 97 | object : ViewModel() { 98 | private val refreshRequests = Channel(1) 99 | var isRefreshing by mutableStateOf(false) 100 | private set 101 | 102 | var itemCount by mutableStateOf(15) 103 | private set 104 | 105 | init { 106 | viewModelScope.launch { 107 | for (r in refreshRequests) { 108 | isRefreshing = true 109 | try { 110 | itemCount += 5 111 | delay(1000) // simulate doing real work 112 | } finally { 113 | isRefreshing = false 114 | } 115 | } 116 | } 117 | } 118 | 119 | fun refresh() { 120 | refreshRequests.trySend(Unit) 121 | } 122 | } 123 | } 124 | 125 | Scaffold(topBar = { 126 | TopAppBar(title = { Text("Title") }, 127 | // Provide an accessible alternative to trigger refresh. 128 | actions = { 129 | IconButton(enabled = !viewModel.isRefreshing, onClick = { viewModel.refresh() }) { 130 | Icon(Icons.Filled.Refresh, "Trigger Refresh") 131 | } 132 | }) 133 | }, floatingActionButton = { 134 | FloatingActionButton(onClick = onClick) { 135 | Icon( 136 | Icons.Default.ArrowBack, contentDescription = "Add", tint = Color.Red 137 | ) 138 | } 139 | }) { 140 | PullToRefreshBox(modifier = Modifier.padding(it), isRefreshing = viewModel.isRefreshing, onRefresh = { viewModel.refresh() }) { 141 | LazyColumn(Modifier.fillMaxSize()) { 142 | if (!viewModel.isRefreshing) { 143 | items(viewModel.itemCount) { 144 | ListItem({ Text(text = "Item ${viewModel.itemCount - it}") }) 145 | } 146 | } 147 | } 148 | } 149 | } 150 | } 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/PullToRefreshActivity4.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.enableEdgeToEdge 7 | import androidx.activity.viewModels 8 | import androidx.compose.animation.core.LinearOutSlowInEasing 9 | import androidx.compose.foundation.ScrollState 10 | import androidx.compose.foundation.background 11 | import androidx.compose.foundation.layout.Arrangement 12 | import androidx.compose.foundation.layout.Box 13 | import androidx.compose.foundation.layout.Column 14 | import androidx.compose.foundation.layout.Row 15 | import androidx.compose.foundation.layout.fillMaxHeight 16 | import androidx.compose.foundation.layout.fillMaxSize 17 | import androidx.compose.foundation.layout.fillMaxWidth 18 | import androidx.compose.foundation.layout.height 19 | import androidx.compose.foundation.layout.padding 20 | import androidx.compose.foundation.lazy.LazyColumn 21 | import androidx.compose.foundation.rememberScrollState 22 | import androidx.compose.foundation.verticalScroll 23 | import androidx.compose.material.icons.Icons 24 | import androidx.compose.material.icons.filled.ArrowBack 25 | import androidx.compose.material.icons.filled.Favorite 26 | import androidx.compose.material.icons.filled.Menu 27 | import androidx.compose.material.icons.filled.Refresh 28 | import androidx.compose.material3.Button 29 | import androidx.compose.material3.ExperimentalMaterial3Api 30 | import androidx.compose.material3.FloatingActionButton 31 | import androidx.compose.material3.Icon 32 | import androidx.compose.material3.IconButton 33 | import androidx.compose.material3.LinearProgressIndicator 34 | import androidx.compose.material3.ListItem 35 | import androidx.compose.material3.MaterialTheme 36 | import androidx.compose.material3.NavigationBar 37 | import androidx.compose.material3.NavigationBarItem 38 | import androidx.compose.material3.Scaffold 39 | import androidx.compose.material3.Text 40 | import androidx.compose.material3.TopAppBar 41 | import androidx.compose.material3.TopAppBarDefaults 42 | import androidx.compose.material3.TopAppBarDefaults.mediumTopAppBarColors 43 | import androidx.compose.material3.pulltorefresh.PullToRefreshBox 44 | import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults 45 | import androidx.compose.material3.pulltorefresh.pullToRefresh 46 | import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState 47 | import androidx.compose.runtime.Composable 48 | import androidx.compose.runtime.getValue 49 | import androidx.compose.runtime.mutableIntStateOf 50 | import androidx.compose.runtime.mutableStateOf 51 | import androidx.compose.runtime.remember 52 | import androidx.compose.runtime.rememberCoroutineScope 53 | import androidx.compose.runtime.setValue 54 | import androidx.compose.ui.Alignment 55 | import androidx.compose.ui.Modifier 56 | import androidx.compose.ui.graphics.Color 57 | import androidx.compose.ui.graphics.graphicsLayer 58 | import androidx.compose.ui.text.TextStyle 59 | import androidx.compose.ui.tooling.preview.Preview 60 | import androidx.compose.ui.unit.dp 61 | import androidx.compose.ui.unit.sp 62 | import androidx.lifecycle.ViewModel 63 | import androidx.lifecycle.lifecycleScope 64 | import androidx.lifecycle.viewModelScope 65 | import androidx.navigation.NavHostController 66 | import androidx.navigation.compose.NavHost 67 | import androidx.navigation.compose.composable 68 | import androidx.navigation.compose.rememberNavController 69 | import com.wx.compose1.ui.theme.WXComposePlugin 70 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 71 | import kotlinx.coroutines.channels.Channel 72 | import kotlinx.coroutines.delay 73 | import kotlinx.coroutines.launch 74 | 75 | class PullToRefreshActivity4 : ComponentActivity() { 76 | 77 | val viewModel by viewModels() 78 | 79 | override fun onCreate(savedInstanceState: Bundle?) { 80 | super.onCreate(savedInstanceState) 81 | enableEdgeToEdge() 82 | lifecycleScope.launch { 83 | setContent { 84 | WXComposePlugin { 85 | PullToRefreshLinearProgressIndicatorSample(onClick = { 86 | finish() 87 | }) 88 | } 89 | } 90 | } 91 | } 92 | } 93 | 94 | @Composable 95 | @OptIn(ExperimentalMaterial3Api::class) 96 | fun PullToRefreshLinearProgressIndicatorSample(onClick: () -> Unit) { 97 | var itemCount by remember { mutableIntStateOf(15) } 98 | var isRefreshing by remember { mutableStateOf(false) } 99 | val state = rememberPullToRefreshState() 100 | val coroutineScope = rememberCoroutineScope() 101 | val onRefresh: () -> Unit = { 102 | isRefreshing = true 103 | coroutineScope.launch { 104 | // fetch something 105 | delay(1500) 106 | itemCount += 5 107 | isRefreshing = false 108 | } 109 | } 110 | 111 | Scaffold( 112 | modifier = 113 | Modifier.pullToRefresh( 114 | state = state, 115 | isRefreshing = isRefreshing, 116 | onRefresh = onRefresh 117 | ), 118 | topBar = { 119 | TopAppBar( 120 | title = { Text("TopAppBar") }, 121 | // Provide an accessible alternative to trigger refresh. 122 | actions = { 123 | IconButton(onClick = onRefresh) { 124 | Icon(Icons.Filled.Refresh, "Trigger Refresh") 125 | } 126 | } 127 | ) 128 | }, floatingActionButton = { 129 | FloatingActionButton(onClick = onClick) { 130 | Icon( 131 | Icons.Default.ArrowBack, contentDescription = "Add", tint = Color.Red 132 | ) 133 | } 134 | } 135 | ) { 136 | Box(Modifier.padding(it)) { 137 | LazyColumn(Modifier.fillMaxSize()) { 138 | if (!isRefreshing) { 139 | items(itemCount) { ListItem({ Text(text = "Item ${itemCount - it}") }) } 140 | } 141 | } 142 | if (isRefreshing) { 143 | LinearProgressIndicator(modifier = Modifier.fillMaxWidth()) 144 | } else { 145 | LinearProgressIndicator( 146 | modifier = Modifier.fillMaxWidth(), 147 | progress = { state.distanceFraction } 148 | ) 149 | } 150 | } 151 | } 152 | } 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/PullToRefreshActivity5.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.enableEdgeToEdge 7 | import androidx.activity.viewModels 8 | import androidx.compose.animation.core.Animatable 9 | import androidx.compose.animation.core.LinearOutSlowInEasing 10 | import androidx.compose.animation.core.Spring 11 | import androidx.compose.animation.core.VectorConverter 12 | import androidx.compose.animation.core.spring 13 | import androidx.compose.foundation.ScrollState 14 | import androidx.compose.foundation.background 15 | import androidx.compose.foundation.layout.Arrangement 16 | import androidx.compose.foundation.layout.Box 17 | import androidx.compose.foundation.layout.Column 18 | import androidx.compose.foundation.layout.Row 19 | import androidx.compose.foundation.layout.fillMaxHeight 20 | import androidx.compose.foundation.layout.fillMaxSize 21 | import androidx.compose.foundation.layout.fillMaxWidth 22 | import androidx.compose.foundation.layout.height 23 | import androidx.compose.foundation.layout.padding 24 | import androidx.compose.foundation.lazy.LazyColumn 25 | import androidx.compose.foundation.rememberScrollState 26 | import androidx.compose.foundation.verticalScroll 27 | import androidx.compose.material.icons.Icons 28 | import androidx.compose.material.icons.filled.ArrowBack 29 | import androidx.compose.material.icons.filled.Favorite 30 | import androidx.compose.material.icons.filled.Menu 31 | import androidx.compose.material.icons.filled.Refresh 32 | import androidx.compose.material3.Button 33 | import androidx.compose.material3.ExperimentalMaterial3Api 34 | import androidx.compose.material3.FloatingActionButton 35 | import androidx.compose.material3.Icon 36 | import androidx.compose.material3.IconButton 37 | import androidx.compose.material3.LinearProgressIndicator 38 | import androidx.compose.material3.ListItem 39 | import androidx.compose.material3.MaterialTheme 40 | import androidx.compose.material3.NavigationBar 41 | import androidx.compose.material3.NavigationBarItem 42 | import androidx.compose.material3.Scaffold 43 | import androidx.compose.material3.Text 44 | import androidx.compose.material3.TopAppBar 45 | import androidx.compose.material3.TopAppBarDefaults 46 | import androidx.compose.material3.TopAppBarDefaults.mediumTopAppBarColors 47 | import androidx.compose.material3.pulltorefresh.PullToRefreshBox 48 | import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults 49 | import androidx.compose.material3.pulltorefresh.PullToRefreshState 50 | import androidx.compose.material3.pulltorefresh.pullToRefresh 51 | import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState 52 | import androidx.compose.runtime.Composable 53 | import androidx.compose.runtime.getValue 54 | import androidx.compose.runtime.mutableIntStateOf 55 | import androidx.compose.runtime.mutableStateOf 56 | import androidx.compose.runtime.remember 57 | import androidx.compose.runtime.rememberCoroutineScope 58 | import androidx.compose.runtime.setValue 59 | import androidx.compose.ui.Alignment 60 | import androidx.compose.ui.Modifier 61 | import androidx.compose.ui.graphics.Color 62 | import androidx.compose.ui.graphics.graphicsLayer 63 | import androidx.compose.ui.text.TextStyle 64 | import androidx.compose.ui.tooling.preview.Preview 65 | import androidx.compose.ui.unit.dp 66 | import androidx.compose.ui.unit.sp 67 | import androidx.lifecycle.ViewModel 68 | import androidx.lifecycle.lifecycleScope 69 | import androidx.lifecycle.viewModelScope 70 | import androidx.navigation.NavHostController 71 | import androidx.navigation.compose.NavHost 72 | import androidx.navigation.compose.composable 73 | import androidx.navigation.compose.rememberNavController 74 | import com.wx.compose1.ui.theme.WXComposePlugin 75 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 76 | import kotlinx.coroutines.channels.Channel 77 | import kotlinx.coroutines.delay 78 | import kotlinx.coroutines.launch 79 | 80 | class PullToRefreshActivity5 : ComponentActivity() { 81 | 82 | val viewModel by viewModels() 83 | 84 | override fun onCreate(savedInstanceState: Bundle?) { 85 | super.onCreate(savedInstanceState) 86 | enableEdgeToEdge() 87 | lifecycleScope.launch { 88 | setContent { 89 | WXComposePlugin { 90 | PullToRefreshSampleCustomState(onClick = { 91 | finish() 92 | }) 93 | } 94 | } 95 | } 96 | } 97 | } 98 | 99 | @Composable 100 | @OptIn(ExperimentalMaterial3Api::class) 101 | fun PullToRefreshSampleCustomState(onClick: () -> Unit) { 102 | var itemCount by remember { mutableIntStateOf(15) } 103 | var isRefreshing by remember { mutableStateOf(false) } 104 | val coroutineScope = rememberCoroutineScope() 105 | val onRefresh: () -> Unit = { 106 | isRefreshing = true 107 | coroutineScope.launch { 108 | // fetch something 109 | delay(1500) 110 | itemCount += 5 111 | isRefreshing = false 112 | } 113 | } 114 | 115 | val state = remember { 116 | object : PullToRefreshState { 117 | private val anim = Animatable(0f, Float.VectorConverter) 118 | 119 | override val distanceFraction 120 | get() = anim.value 121 | 122 | override suspend fun animateToThreshold() { 123 | anim.animateTo(1f, spring(dampingRatio = Spring.DampingRatioHighBouncy)) 124 | } 125 | 126 | override suspend fun animateToHidden() { 127 | anim.animateTo(0f) 128 | } 129 | 130 | override suspend fun snapTo(targetValue: Float) { 131 | anim.snapTo(targetValue) 132 | } 133 | } 134 | } 135 | 136 | Scaffold( 137 | topBar = { 138 | TopAppBar( 139 | title = { Text("TopAppBar") }, 140 | // Provide an accessible alternative to trigger refresh. 141 | actions = { 142 | IconButton(onClick = onRefresh) { 143 | Icon(Icons.Filled.Refresh, "Trigger Refresh") 144 | } 145 | } 146 | ) 147 | }, floatingActionButton = { 148 | FloatingActionButton(onClick = onClick) { 149 | Icon( 150 | Icons.Default.ArrowBack, contentDescription = "Add", tint = Color.Red 151 | ) 152 | } 153 | } 154 | ) { 155 | PullToRefreshBox( 156 | modifier = Modifier.padding(it), 157 | isRefreshing = isRefreshing, 158 | onRefresh = onRefresh, 159 | state = state 160 | ) { 161 | LazyColumn(Modifier.fillMaxSize()) { 162 | if (!isRefreshing) { 163 | items(itemCount) { ListItem({ Text(text = "Item ${itemCount - it}") }) } 164 | } 165 | } 166 | } 167 | } 168 | } 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/PullToRefreshActivity6.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.enableEdgeToEdge 7 | import androidx.activity.viewModels 8 | import androidx.compose.animation.core.Animatable 9 | import androidx.compose.animation.core.LinearOutSlowInEasing 10 | import androidx.compose.animation.core.Spring 11 | import androidx.compose.animation.core.VectorConverter 12 | import androidx.compose.animation.core.spring 13 | import androidx.compose.foundation.ScrollState 14 | import androidx.compose.foundation.background 15 | import androidx.compose.foundation.layout.Arrangement 16 | import androidx.compose.foundation.layout.Box 17 | import androidx.compose.foundation.layout.Column 18 | import androidx.compose.foundation.layout.FlowColumn 19 | import androidx.compose.foundation.layout.Row 20 | import androidx.compose.foundation.layout.fillMaxHeight 21 | import androidx.compose.foundation.layout.fillMaxSize 22 | import androidx.compose.foundation.layout.fillMaxWidth 23 | import androidx.compose.foundation.layout.height 24 | import androidx.compose.foundation.layout.padding 25 | import androidx.compose.foundation.lazy.LazyColumn 26 | import androidx.compose.foundation.rememberScrollState 27 | import androidx.compose.foundation.verticalScroll 28 | import androidx.compose.material.icons.Icons 29 | import androidx.compose.material.icons.filled.ArrowBack 30 | import androidx.compose.material.icons.filled.Favorite 31 | import androidx.compose.material.icons.filled.Menu 32 | import androidx.compose.material.icons.filled.Refresh 33 | import androidx.compose.material3.Button 34 | import androidx.compose.material3.ExperimentalMaterial3Api 35 | import androidx.compose.material3.FloatingActionButton 36 | import androidx.compose.material3.Icon 37 | import androidx.compose.material3.IconButton 38 | import androidx.compose.material3.LinearProgressIndicator 39 | import androidx.compose.material3.ListItem 40 | import androidx.compose.material3.MaterialTheme 41 | import androidx.compose.material3.NavigationBar 42 | import androidx.compose.material3.NavigationBarItem 43 | import androidx.compose.material3.Scaffold 44 | import androidx.compose.material3.Text 45 | import androidx.compose.material3.TopAppBar 46 | import androidx.compose.material3.TopAppBarDefaults 47 | import androidx.compose.material3.TopAppBarDefaults.mediumTopAppBarColors 48 | import androidx.compose.material3.pulltorefresh.PullToRefreshBox 49 | import androidx.compose.material3.pulltorefresh.PullToRefreshDefaults 50 | import androidx.compose.material3.pulltorefresh.PullToRefreshState 51 | import androidx.compose.material3.pulltorefresh.pullToRefresh 52 | import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState 53 | import androidx.compose.runtime.Composable 54 | import androidx.compose.runtime.getValue 55 | import androidx.compose.runtime.mutableIntStateOf 56 | import androidx.compose.runtime.mutableStateOf 57 | import androidx.compose.runtime.remember 58 | import androidx.compose.runtime.rememberCoroutineScope 59 | import androidx.compose.runtime.setValue 60 | import androidx.compose.ui.Alignment 61 | import androidx.compose.ui.Modifier 62 | import androidx.compose.ui.graphics.Color 63 | import androidx.compose.ui.graphics.graphicsLayer 64 | import androidx.compose.ui.text.TextStyle 65 | import androidx.compose.ui.text.style.TextAlign 66 | import androidx.compose.ui.tooling.preview.Preview 67 | import androidx.compose.ui.unit.dp 68 | import androidx.compose.ui.unit.sp 69 | import androidx.lifecycle.ViewModel 70 | import androidx.lifecycle.lifecycleScope 71 | import androidx.lifecycle.viewModelScope 72 | import androidx.navigation.NavHostController 73 | import androidx.navigation.compose.NavHost 74 | import androidx.navigation.compose.composable 75 | import androidx.navigation.compose.rememberNavController 76 | import com.wx.compose1.ui.theme.WXComposePlugin 77 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 78 | import kotlinx.coroutines.channels.Channel 79 | import kotlinx.coroutines.delay 80 | import kotlinx.coroutines.launch 81 | 82 | class PullToRefreshActivity6 : ComponentActivity() { 83 | 84 | val viewModel by viewModels() 85 | 86 | override fun onCreate(savedInstanceState: Bundle?) { 87 | super.onCreate(savedInstanceState) 88 | enableEdgeToEdge() 89 | lifecycleScope.launch { 90 | setContent { 91 | WXComposePlugin { 92 | PullToRefreshSample6(onClick = { 93 | finish() 94 | }) 95 | } 96 | } 97 | } 98 | } 99 | } 100 | 101 | @Composable 102 | @OptIn(ExperimentalMaterial3Api::class) 103 | fun PullToRefreshSample6(onClick: () -> Unit) { 104 | var itemCount by remember { mutableIntStateOf(15) } 105 | var isRefreshing by remember { mutableStateOf(false) } 106 | val state = rememberPullToRefreshState() 107 | val coroutineScope = rememberCoroutineScope() 108 | val onRefresh: () -> Unit = { 109 | isRefreshing = true 110 | coroutineScope.launch { 111 | delay(1500) 112 | itemCount += 5 113 | isRefreshing = false 114 | } 115 | } 116 | 117 | Scaffold(topBar = { 118 | TopAppBar(title = { Text("Title") }, 119 | // Provide an accessible alternative to trigger refresh. 120 | actions = { 121 | IconButton(onClick = onRefresh) { 122 | Icon(Icons.Filled.Refresh, "Trigger Refresh") 123 | } 124 | }) 125 | }, floatingActionButton = { 126 | FloatingActionButton(onClick = onClick) { 127 | Icon( 128 | Icons.Default.ArrowBack, contentDescription = "Add", tint = Color.Red 129 | ) 130 | } 131 | }) { 132 | PullToRefreshBox( 133 | modifier = Modifier 134 | .padding(it) 135 | .fillMaxSize(), 136 | state = state, 137 | isRefreshing = isRefreshing, 138 | onRefresh = onRefresh, 139 | ) { 140 | // Box( 141 | // modifier = Modifier 142 | // .fillMaxSize() 143 | // .background(Color.Red) 144 | // .verticalScroll(rememberScrollState()) 145 | // ) { 146 | Text( 147 | modifier = Modifier 148 | .fillMaxSize() 149 | .background(Color.Red) 150 | .verticalScroll(rememberScrollState()),// 一定要加这句, 151 | text = "AAAAAAAAAAAA", color = Color.Green, textAlign = TextAlign.Center 152 | ) 153 | // } 154 | } 155 | } 156 | } 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/StickListActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.enableEdgeToEdge 7 | import androidx.activity.viewModels 8 | import androidx.compose.foundation.ExperimentalFoundationApi 9 | import androidx.compose.foundation.Image 10 | import androidx.compose.foundation.background 11 | import androidx.compose.foundation.layout.Box 12 | import androidx.compose.foundation.layout.Column 13 | import androidx.compose.foundation.layout.PaddingValues 14 | import androidx.compose.foundation.layout.Row 15 | import androidx.compose.foundation.layout.Spacer 16 | import androidx.compose.foundation.layout.fillMaxSize 17 | import androidx.compose.foundation.layout.fillMaxWidth 18 | import androidx.compose.foundation.layout.height 19 | import androidx.compose.foundation.layout.padding 20 | import androidx.compose.foundation.lazy.LazyColumn 21 | import androidx.compose.foundation.lazy.items 22 | import androidx.compose.foundation.lazy.rememberLazyListState 23 | import androidx.compose.foundation.rememberScrollState 24 | import androidx.compose.foundation.verticalScroll 25 | import androidx.compose.material3.Button 26 | import androidx.compose.material3.Checkbox 27 | import androidx.compose.material3.MaterialTheme 28 | import androidx.compose.material3.Surface 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.alpha 38 | import androidx.compose.ui.graphics.Color 39 | import androidx.compose.ui.graphics.graphicsLayer 40 | import androidx.compose.ui.layout.ContentScale 41 | import androidx.compose.ui.res.painterResource 42 | import androidx.compose.ui.text.font.FontWeight 43 | import androidx.compose.ui.unit.dp 44 | import androidx.compose.ui.unit.sp 45 | import androidx.compose.ui.viewinterop.AndroidView 46 | import androidx.lifecycle.lifecycleScope 47 | import com.wx.compose.plugin.R 48 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 49 | import com.wx.compose1.ui.composable.baseUI 50 | import com.wx.compose1.ui.theme.WXComposePlugin 51 | import kotlinx.coroutines.launch 52 | import me.onebone.toolbar.CollapsingToolbarScaffold 53 | import me.onebone.toolbar.ExperimentalToolbarApi 54 | import me.onebone.toolbar.ScrollStrategy 55 | import me.onebone.toolbar.rememberCollapsingToolbarScaffoldState 56 | 57 | class StickListActivity : ComponentActivity() { 58 | 59 | val viewModel by viewModels() 60 | 61 | override fun onCreate(savedInstanceState: Bundle?) { 62 | super.onCreate(savedInstanceState) 63 | enableEdgeToEdge() 64 | lifecycleScope.launch { 65 | setContent { 66 | WXComposePlugin { 67 | baseUI(content = { paddingvalues -> 68 | StickyHeaderSample(paddingvalues) 69 | }, onClick = { 70 | finish() 71 | }) 72 | } 73 | } 74 | } 75 | } 76 | } 77 | 78 | @OptIn(ExperimentalFoundationApi::class) 79 | @Composable 80 | fun StickyHeaderSample(paddingValues: PaddingValues) { 81 | val sections = listOf("A", "B", "C", "D", "E", "F", "G") 82 | 83 | LazyColumn( 84 | modifier = Modifier.padding(paddingValues), contentPadding = PaddingValues(6.dp) 85 | ) { 86 | sections.forEach { section -> 87 | stickyHeader { 88 | Text( 89 | text = "Section $section", color = Color.White, modifier = Modifier 90 | .fillMaxWidth() 91 | .height(50.dp) 92 | .background(Color.Red) 93 | .padding(8.dp) 94 | ) 95 | } 96 | items(10) { 97 | Text("Item $it from the section $section") 98 | } 99 | } 100 | } 101 | } 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/TabHorizontalPagerActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.annotation.SuppressLint 4 | import android.os.Bundle 5 | import androidx.activity.ComponentActivity 6 | import androidx.activity.compose.setContent 7 | import androidx.activity.enableEdgeToEdge 8 | import androidx.activity.viewModels 9 | import androidx.compose.foundation.Image 10 | import androidx.compose.foundation.background 11 | import androidx.compose.foundation.border 12 | import androidx.compose.foundation.horizontalScroll 13 | import androidx.compose.foundation.layout.Box 14 | import androidx.compose.foundation.layout.Column 15 | import androidx.compose.foundation.layout.PaddingValues 16 | import androidx.compose.foundation.layout.Row 17 | import androidx.compose.foundation.layout.aspectRatio 18 | import androidx.compose.foundation.layout.fillMaxHeight 19 | import androidx.compose.foundation.layout.fillMaxWidth 20 | import androidx.compose.foundation.layout.height 21 | import androidx.compose.foundation.layout.padding 22 | import androidx.compose.foundation.layout.size 23 | import androidx.compose.foundation.layout.wrapContentWidth 24 | import androidx.compose.foundation.lazy.LazyColumn 25 | import androidx.compose.foundation.lazy.items 26 | import androidx.compose.foundation.lazy.rememberLazyListState 27 | import androidx.compose.foundation.pager.HorizontalPager 28 | import androidx.compose.foundation.pager.rememberPagerState 29 | import androidx.compose.foundation.rememberScrollState 30 | import androidx.compose.foundation.shape.RoundedCornerShape 31 | import androidx.compose.material3.Tab 32 | import androidx.compose.material3.TabRow 33 | import androidx.compose.material3.Text 34 | import androidx.compose.runtime.Composable 35 | import androidx.compose.runtime.getValue 36 | import androidx.compose.runtime.livedata.observeAsState 37 | import androidx.compose.runtime.mutableStateOf 38 | import androidx.compose.runtime.remember 39 | import androidx.compose.runtime.rememberCoroutineScope 40 | import androidx.compose.runtime.setValue 41 | import androidx.compose.ui.Alignment 42 | import androidx.compose.ui.Modifier 43 | import androidx.compose.ui.graphics.Color 44 | import androidx.compose.ui.graphics.SolidColor 45 | import androidx.compose.ui.layout.ContentScale 46 | import androidx.compose.ui.platform.LocalContext 47 | import androidx.compose.ui.res.painterResource 48 | import androidx.compose.ui.text.style.TextAlign 49 | import androidx.compose.ui.text.style.TextOverflow 50 | import androidx.compose.ui.unit.dp 51 | import androidx.compose.ui.unit.sp 52 | import androidx.lifecycle.lifecycleScope 53 | import coil.compose.AsyncImage 54 | import coil.compose.rememberAsyncImagePainter 55 | import coil.request.ImageRequest 56 | import com.wx.compose1.ui.composable.baseUI 57 | import com.wx.compose1.ui.theme.WXComposePlugin 58 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 59 | import kotlinx.coroutines.launch 60 | 61 | class TabHorizontalPagerActivity : ComponentActivity() { 62 | 63 | val viewModel by viewModels() 64 | 65 | override fun onCreate(savedInstanceState: Bundle?) { 66 | super.onCreate(savedInstanceState) 67 | enableEdgeToEdge() 68 | lifecycleScope.launch { 69 | setContent { 70 | WXComposePlugin { 71 | baseUI(content = { paddingvalues -> 72 | tabPage(paddingvalues, viewModel) 73 | }, onClick = { 74 | finish() 75 | }) 76 | } 77 | } 78 | } 79 | viewModel.add() 80 | } 81 | } 82 | 83 | @SuppressLint("UnrememberedMutableState") 84 | @Composable 85 | fun tabPage(innerPadding: PaddingValues, viewModel: ComposeViewModel) { 86 | var state by remember { mutableStateOf(0) } 87 | var statePage = rememberPagerState(initialPage = state) { 5 } 88 | val titles = listOf("Tab 1", "Tab 2", "Tab 3 ", "Tab 4 ", "Tab 5 ") 89 | val scope = rememberCoroutineScope() 90 | Column( 91 | modifier = Modifier 92 | .padding(innerPadding) 93 | .background(Color.Yellow) 94 | // .verticalScroll(rememberScrollState()) 95 | .padding(5.dp) 96 | .fillMaxWidth() 97 | .fillMaxHeight() 98 | ) { 99 | TabRow(selectedTabIndex = statePage.currentPage) { 100 | titles.forEachIndexed { index, title -> 101 | Tab(modifier = Modifier.background(Color.Green), selected = state == index, onClick = { 102 | scope.launch { 103 | // statePage.scrollToPage(index) 104 | statePage.animateScrollToPage(index) 105 | } 106 | }, text = { 107 | Text(text = title, maxLines = 2, overflow = TextOverflow.Ellipsis, fontSize = 20.sp, color = Color.Magenta) 108 | }) 109 | } 110 | } 111 | HorizontalPager( 112 | state = statePage, modifier = Modifier 113 | .fillMaxWidth() 114 | .fillMaxHeight() 115 | ) { page -> 116 | when (page) { 117 | 0 -> page1(viewModel) 118 | else -> Box( 119 | modifier = Modifier 120 | .padding(10.dp) 121 | .background(Color.Red) 122 | .fillMaxWidth() 123 | .fillMaxHeight() 124 | .aspectRatio(1f), contentAlignment = Alignment.Center 125 | ) { 126 | Text(text = page.toString(), fontSize = 32.sp) 127 | } 128 | } 129 | } 130 | } 131 | } 132 | 133 | @Composable 134 | fun page1(viewModel: ComposeViewModel) { 135 | val datas by viewModel.datas.observeAsState(initial = emptyList()) 136 | LazyColumn( 137 | modifier = Modifier 138 | .padding(10.dp) 139 | .background(Color.Red) 140 | .fillMaxWidth() 141 | .fillMaxHeight(), 142 | state = rememberLazyListState() 143 | ) { 144 | items(datas) { data -> 145 | Row( 146 | modifier = Modifier 147 | .fillMaxWidth() 148 | .horizontalScroll(rememberScrollState()) 149 | .height(80.dp), verticalAlignment = Alignment.CenterVertically 150 | ) { 151 | Image( 152 | painter = painterResource(id = data.resID), contentDescription = "小姐姐", modifier = Modifier 153 | .size(80.dp) 154 | .padding(5.dp), contentScale = ContentScale.Fit 155 | ) 156 | AsyncImage( 157 | model = data.imgUrl, contentDescription = "", contentScale = ContentScale.Crop 158 | ) 159 | val modelBuilder = ImageRequest.Builder(LocalContext.current).data(data.imgUrl ?: "").crossfade(false).allowHardware(true).build() 160 | Image( 161 | painter = rememberAsyncImagePainter(model = modelBuilder), contentDescription = "小姐姐", modifier = Modifier 162 | .size(80.dp) 163 | .padding(5.dp), contentScale = ContentScale.Crop 164 | ) 165 | Text( 166 | modifier = Modifier 167 | .wrapContentWidth() 168 | .height(60.dp) 169 | .background(Color.Yellow) 170 | .border(2.dp, SolidColor(Color.Green), RoundedCornerShape(20.dp)) 171 | .padding(0.dp, 5.dp, 0.dp, 0.dp), fontSize = 16.sp, text = data.title, textAlign = TextAlign.Center, color = Color.Magenta 172 | ) 173 | Text( 174 | modifier = Modifier 175 | .wrapContentWidth() 176 | .height(60.dp) 177 | .background(Color.Yellow) 178 | .border(2.dp, SolidColor(Color.Green), RoundedCornerShape(20.dp)) 179 | .padding(0.dp, 5.dp, 0.dp, 0.dp), fontSize = 16.sp, text = data.title, textAlign = TextAlign.Center, color = Color.Magenta 180 | ) 181 | } 182 | } 183 | } 184 | } 185 | 186 | 187 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/TabLayoutActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.enableEdgeToEdge 7 | import androidx.activity.viewModels 8 | import androidx.compose.foundation.background 9 | import androidx.compose.foundation.layout.Arrangement 10 | import androidx.compose.foundation.layout.Box 11 | import androidx.compose.foundation.layout.Column 12 | import androidx.compose.foundation.layout.PaddingValues 13 | import androidx.compose.foundation.layout.aspectRatio 14 | import androidx.compose.foundation.layout.fillMaxHeight 15 | import androidx.compose.foundation.layout.fillMaxWidth 16 | import androidx.compose.foundation.layout.height 17 | import androidx.compose.foundation.layout.padding 18 | import androidx.compose.foundation.layout.size 19 | import androidx.compose.foundation.pager.HorizontalPager 20 | import androidx.compose.foundation.pager.rememberPagerState 21 | import androidx.compose.foundation.rememberScrollState 22 | import androidx.compose.foundation.verticalScroll 23 | import androidx.compose.material3.ExperimentalMaterial3Api 24 | import androidx.compose.material3.MaterialTheme 25 | import androidx.compose.material3.PrimaryTabRow 26 | import androidx.compose.material3.ScrollableTabRow 27 | import androidx.compose.material3.SecondaryTabRow 28 | import androidx.compose.material3.Tab 29 | import androidx.compose.material3.TabRow 30 | import androidx.compose.material3.Text 31 | import androidx.compose.runtime.Composable 32 | import androidx.compose.runtime.getValue 33 | import androidx.compose.runtime.mutableIntStateOf 34 | import androidx.compose.runtime.mutableStateOf 35 | import androidx.compose.runtime.remember 36 | import androidx.compose.runtime.setValue 37 | import androidx.compose.ui.Alignment 38 | import androidx.compose.ui.Modifier 39 | import androidx.compose.ui.graphics.Color 40 | import androidx.compose.ui.input.key.Key.Companion.Tab 41 | import androidx.compose.ui.text.style.TextOverflow 42 | import androidx.compose.ui.unit.dp 43 | import androidx.compose.ui.unit.sp 44 | import androidx.lifecycle.lifecycleScope 45 | import com.wx.compose1.ui.composable.baseUI 46 | import com.wx.compose1.ui.theme.WXComposePlugin 47 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 48 | import kotlinx.coroutines.launch 49 | 50 | class TabLayoutActivity : ComponentActivity() { 51 | 52 | val viewModel by viewModels() 53 | 54 | override fun onCreate(savedInstanceState: Bundle?) { 55 | super.onCreate(savedInstanceState) 56 | enableEdgeToEdge() 57 | lifecycleScope.launch { 58 | setContent { 59 | WXComposePlugin { 60 | baseUI(content = { paddingvalues -> 61 | TabLayoutExample(paddingvalues, viewModel) 62 | }, onClick = { 63 | viewModel.add() 64 | }) 65 | } 66 | } 67 | } 68 | viewModel.add() 69 | } 70 | } 71 | 72 | 73 | @OptIn(ExperimentalMaterial3Api::class) 74 | @Composable 75 | fun TabLayoutExample(innerPadding: PaddingValues, viewModel: ComposeViewModel) { 76 | var state by remember { mutableStateOf(0) } 77 | val titles = listOf("Tab 1", "Tab 2", "Tab 3 ") 78 | 79 | var state2 by remember { mutableStateOf(0) } 80 | val titles2 = listOf("Tab 1", "Tab 2", "Tab 3 ", "Tab 4 ", "Tab 5 ", "Tab 6 ", "Tab 7 ", "Tab 8 ", "Tab 9 ", "Tab 10 ", "Tab 11 ") 81 | 82 | 83 | Column( 84 | modifier = Modifier 85 | .padding(innerPadding) 86 | .background(Color.Yellow) 87 | // .verticalScroll(rememberScrollState()) 88 | .padding(5.dp) 89 | .fillMaxWidth() 90 | .fillMaxHeight() 91 | ) { 92 | TabRow(selectedTabIndex = state) { 93 | titles.forEachIndexed { index, title -> 94 | Tab(modifier = Modifier.background(Color.Green), selected = state == index, onClick = { 95 | state = index 96 | }, text = { 97 | Text(text = title, maxLines = 2, overflow = TextOverflow.Ellipsis, fontSize = 20.sp, color = Color.Magenta) 98 | }) 99 | } 100 | } 101 | Text( 102 | modifier = Modifier.align(Alignment.CenterHorizontally), text = "Text tab ${state + 1} selected", style = MaterialTheme.typography.bodyLarge, color = Color.Red, fontSize = 36.sp 103 | ) 104 | 105 | PrimaryTabRow(selectedTabIndex = state) { 106 | titles.forEachIndexed { index, title -> 107 | Tab(modifier = Modifier.background(Color.Green), selected = state == index, onClick = { 108 | state = index 109 | }, text = { 110 | Text(text = title, maxLines = 2, overflow = TextOverflow.Ellipsis, fontSize = 20.sp, color = Color.Magenta) 111 | }) 112 | } 113 | } 114 | 115 | SecondaryTabRow(selectedTabIndex = state, containerColor = Color.Cyan) { 116 | titles.forEachIndexed { index, title -> 117 | FancyTab(title = title, onClick = { state = index }, selected = (index == state)) 118 | } 119 | } 120 | Text(modifier = Modifier.align(Alignment.CenterHorizontally), text = "Fancy tab ${state + 1} selected", style = MaterialTheme.typography.bodyLarge) 121 | 122 | ScrollableTabRow(selectedTabIndex = state2, containerColor = Color.Red) { 123 | titles2.forEachIndexed { index, title -> 124 | FancyTab(title = title, onClick = { state2 = index }, selected = (index == state2)) 125 | } 126 | } 127 | 128 | } 129 | } 130 | 131 | @Composable 132 | fun FancyTab(title: String, onClick: () -> Unit, selected: Boolean) { 133 | Tab(selected, onClick) { 134 | Column( 135 | Modifier 136 | .padding(10.dp) 137 | .height(50.dp) 138 | .fillMaxWidth(), verticalArrangement = Arrangement.SpaceBetween 139 | ) { 140 | Box( 141 | Modifier 142 | .size(10.dp) 143 | .align(Alignment.CenterHorizontally) 144 | .background( 145 | color = if (selected) MaterialTheme.colorScheme.primary 146 | else MaterialTheme.colorScheme.background 147 | ) 148 | ) 149 | Text( 150 | text = title, color = Color.White, style = MaterialTheme.typography.bodyLarge, modifier = Modifier.align(Alignment.CenterHorizontally) 151 | ) 152 | } 153 | } 154 | } 155 | 156 | //@Preview 157 | //@Composable 158 | //fun girdLayoutPreview(innerPadding: PaddingValues = PaddingValues(0.dp)) { 159 | // WXComposePlugin { 160 | // girdLayoutExample(innerPadding) 161 | // } 162 | //} -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/ViewPageLayoutActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import androidx.activity.ComponentActivity 5 | import androidx.activity.compose.setContent 6 | import androidx.activity.enableEdgeToEdge 7 | import androidx.activity.viewModels 8 | import androidx.compose.foundation.background 9 | import androidx.compose.foundation.layout.Box 10 | import androidx.compose.foundation.layout.PaddingValues 11 | import androidx.compose.foundation.layout.aspectRatio 12 | import androidx.compose.foundation.layout.fillMaxHeight 13 | import androidx.compose.foundation.layout.fillMaxWidth 14 | import androidx.compose.foundation.layout.padding 15 | import androidx.compose.foundation.pager.VerticalPager 16 | import androidx.compose.foundation.pager.rememberPagerState 17 | import androidx.compose.material3.Text 18 | import androidx.compose.runtime.Composable 19 | import androidx.compose.ui.Alignment 20 | import androidx.compose.ui.Modifier 21 | import androidx.compose.ui.graphics.Color 22 | import androidx.compose.ui.unit.dp 23 | import androidx.compose.ui.unit.sp 24 | import androidx.lifecycle.lifecycleScope 25 | import com.wx.compose1.ui.composable.baseUI 26 | import com.wx.compose1.ui.theme.WXComposePlugin 27 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 28 | import kotlinx.coroutines.launch 29 | 30 | class ViewPageLayoutActivity : ComponentActivity() { 31 | 32 | val viewModel by viewModels() 33 | 34 | override fun onCreate(savedInstanceState: Bundle?) { 35 | super.onCreate(savedInstanceState) 36 | enableEdgeToEdge() 37 | lifecycleScope.launch { 38 | setContent { 39 | WXComposePlugin { 40 | baseUI(content = { paddingvalues -> 41 | ViewPageLayoutExample(paddingvalues, viewModel) 42 | }, onClick = { 43 | viewModel.add() 44 | }) 45 | } 46 | } 47 | } 48 | viewModel.add() 49 | } 50 | } 51 | 52 | 53 | @Composable 54 | fun ViewPageLayoutExample(innerPadding: PaddingValues, viewModel: ComposeViewModel) { 55 | val state = rememberPagerState(initialPage = 3) { 5 } 56 | VerticalPager( 57 | state = state, modifier = Modifier 58 | .fillMaxWidth() 59 | .fillMaxHeight() 60 | ) { page -> 61 | Box( 62 | modifier = Modifier 63 | .padding(10.dp) 64 | .background(Color.Yellow) 65 | .fillMaxWidth() 66 | .fillMaxHeight() 67 | .aspectRatio(1f), contentAlignment = Alignment.Center 68 | ) { 69 | Text(text = page.toString(), fontSize = 32.sp) 70 | } 71 | } 72 | } 73 | 74 | //@Preview 75 | //@Composable 76 | //fun girdLayoutPreview(innerPadding: PaddingValues = PaddingValues(0.dp)) { 77 | // WXComposePlugin { 78 | // girdLayoutExample(innerPadding) 79 | // } 80 | //} -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/activity/WebViewActivity.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.activity 2 | 3 | import android.os.Bundle 4 | import android.webkit.WebSettings 5 | import android.webkit.WebView 6 | import androidx.activity.ComponentActivity 7 | import androidx.activity.compose.setContent 8 | import androidx.activity.enableEdgeToEdge 9 | import androidx.activity.viewModels 10 | import androidx.compose.foundation.Image 11 | import androidx.compose.foundation.background 12 | import androidx.compose.foundation.gestures.Orientation 13 | import androidx.compose.foundation.gestures.scrollable 14 | import androidx.compose.foundation.layout.Arrangement 15 | import androidx.compose.foundation.layout.Box 16 | import androidx.compose.foundation.layout.Column 17 | import androidx.compose.foundation.layout.Row 18 | import androidx.compose.foundation.layout.fillMaxHeight 19 | import androidx.compose.foundation.layout.fillMaxSize 20 | import androidx.compose.foundation.layout.fillMaxWidth 21 | import androidx.compose.foundation.layout.height 22 | import androidx.compose.foundation.layout.padding 23 | import androidx.compose.foundation.layout.size 24 | import androidx.compose.foundation.lazy.LazyColumn 25 | import androidx.compose.foundation.lazy.rememberLazyListState 26 | import androidx.compose.foundation.rememberScrollState 27 | import androidx.compose.foundation.verticalScroll 28 | import androidx.compose.material.icons.Icons 29 | import androidx.compose.material.icons.filled.ArrowBack 30 | import androidx.compose.material3.ExperimentalMaterial3Api 31 | import androidx.compose.material3.ExtendedFloatingActionButton 32 | import androidx.compose.material3.Icon 33 | import androidx.compose.material3.IconButton 34 | import androidx.compose.material3.MaterialTheme 35 | import androidx.compose.material3.Scaffold 36 | import androidx.compose.material3.SnackbarHostState 37 | import androidx.compose.material3.Surface 38 | import androidx.compose.material3.Text 39 | import androidx.compose.material3.TopAppBar 40 | import androidx.compose.material3.TopAppBarDefaults.mediumTopAppBarColors 41 | import androidx.compose.material3.pulltorefresh.PullToRefreshBox 42 | import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState 43 | import androidx.compose.runtime.Composable 44 | import androidx.compose.runtime.State 45 | import androidx.compose.runtime.derivedStateOf 46 | import androidx.compose.runtime.getValue 47 | import androidx.compose.runtime.mutableStateOf 48 | import androidx.compose.runtime.remember 49 | import androidx.compose.runtime.rememberCoroutineScope 50 | import androidx.compose.runtime.setValue 51 | import androidx.compose.ui.Alignment 52 | import androidx.compose.ui.Modifier 53 | import androidx.compose.ui.geometry.Offset 54 | import androidx.compose.ui.graphics.Color 55 | import androidx.compose.ui.graphics.vector.rememberVectorPainter 56 | import androidx.compose.ui.input.nestedscroll.NestedScrollConnection 57 | import androidx.compose.ui.input.nestedscroll.NestedScrollSource 58 | import androidx.compose.ui.input.nestedscroll.nestedScroll 59 | import androidx.compose.ui.layout.ContentScale 60 | import androidx.compose.ui.layout.layoutId 61 | import androidx.compose.ui.layout.onGloballyPositioned 62 | import androidx.compose.ui.platform.LocalDensity 63 | import androidx.compose.ui.res.painterResource 64 | import androidx.compose.ui.text.TextStyle 65 | import androidx.compose.ui.text.font.FontWeight 66 | import androidx.compose.ui.text.style.TextAlign 67 | import androidx.compose.ui.unit.Dp 68 | import androidx.compose.ui.unit.dp 69 | import androidx.compose.ui.unit.sp 70 | import androidx.compose.ui.viewinterop.AndroidView 71 | import androidx.constraintlayout.compose.Dimension 72 | import androidx.constraintlayout.compose.ExperimentalMotionApi 73 | import androidx.constraintlayout.compose.MotionLayout 74 | import androidx.constraintlayout.compose.MotionScene 75 | import androidx.lifecycle.lifecycleScope 76 | import com.wx.compose.plugin.R 77 | import com.wx.compose1.ui.theme.WXComposePlugin 78 | import com.wx.compose.plugin.viewmodel.ComposeViewModel 79 | import kotlinx.coroutines.delay 80 | import kotlinx.coroutines.launch 81 | 82 | class WebViewActivity : ComponentActivity() { 83 | 84 | val viewModel by viewModels() 85 | 86 | override fun onCreate(savedInstanceState: Bundle?) { 87 | super.onCreate(savedInstanceState) 88 | enableEdgeToEdge() 89 | lifecycleScope.launch { 90 | setContent { 91 | WXComposePlugin { 92 | PullToRefreshScalingSample8(onClick = { 93 | finish() 94 | }) 95 | } 96 | } 97 | } 98 | } 99 | } 100 | 101 | @OptIn(ExperimentalMaterial3Api::class) 102 | @Composable 103 | fun PullToRefreshScalingSample8(onClick: () -> Unit) { 104 | val snackbarHostState = remember { SnackbarHostState() } 105 | var isRefreshing by remember { mutableStateOf(false) } 106 | val state = rememberPullToRefreshState() 107 | val coroutineScope = rememberCoroutineScope() 108 | val onRefresh: () -> Unit = { 109 | isRefreshing = true 110 | coroutineScope.launch { 111 | delay(1500) 112 | isRefreshing = false 113 | } 114 | } 115 | Scaffold(topBar = { 116 | TopAppBar(modifier = Modifier 117 | .fillMaxWidth() 118 | .background(Color.Blue) 119 | .height(81.dp), colors = mediumTopAppBarColors( 120 | containerColor = Color.Blue, 121 | titleContentColor = MaterialTheme.colorScheme.primary, 122 | ), title = { 123 | Row( 124 | modifier = Modifier 125 | .fillMaxWidth() 126 | .fillMaxHeight(), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center 127 | ) { 128 | Text(text = "compose 稀土掘金", fontSize = 18.sp, color = Color.Red, style = TextStyle.Default) 129 | } 130 | }) 131 | }, floatingActionButton = { 132 | ExtendedFloatingActionButton( 133 | onClick = onClick 134 | ) { 135 | Text("返回") 136 | } 137 | }, content = { innerPadding -> 138 | PullToRefreshBox( 139 | modifier = Modifier.padding(innerPadding), 140 | state = state, 141 | isRefreshing = isRefreshing, 142 | onRefresh = onRefresh, 143 | ) { 144 | AndroidView( 145 | factory = { context -> 146 | WebView(context).apply { 147 | settings.apply { 148 | defaultTextEncodingName = "UTF-8" 149 | allowFileAccess = true 150 | cacheMode = WebSettings.LOAD_NO_CACHE 151 | javaScriptEnabled = true 152 | domStorageEnabled = true 153 | // webViewClient = implWeb 154 | } 155 | } 156 | }, modifier = Modifier 157 | .fillMaxWidth() 158 | .fillMaxHeight() 159 | .verticalScroll(rememberScrollState()) 160 | ) { webview -> 161 | webview.loadUrl("https://juejin.cn/") 162 | } 163 | } 164 | }) 165 | } 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/classloader/WXClassLoader.java: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.classloader; 2 | 3 | import dalvik.system.DexClassLoader; 4 | 5 | public class WXClassLoader extends DexClassLoader { 6 | protected ClassLoader parent; 7 | 8 | public WXClassLoader(String dexPath, String optimizedDirectory, ClassLoader parent) { 9 | super(dexPath, optimizedDirectory, null, parent); 10 | this.parent = parent; 11 | } 12 | 13 | public WXClassLoader(String dexPath, String optimizedDirectory, String librarySearchPath, ClassLoader parent) { 14 | super(dexPath, optimizedDirectory, librarySearchPath, parent); 15 | this.parent = parent; 16 | } 17 | 18 | public T getInterface(Class clazz, String className) { 19 | try { 20 | Class interfaceImplementClass = loadClass(className); 21 | Object interfaceImplement = interfaceImplementClass.newInstance(); 22 | return clazz.cast(interfaceImplement); 23 | } catch (ClassNotFoundException | InstantiationException 24 | | ClassCastException | IllegalAccessException e) { 25 | return null; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/composable/BaseComposable.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose1.ui.composable 2 | 3 | import androidx.compose.foundation.background 4 | import androidx.compose.foundation.layout.Arrangement 5 | import androidx.compose.foundation.layout.PaddingValues 6 | import androidx.compose.foundation.layout.Row 7 | import androidx.compose.foundation.layout.fillMaxHeight 8 | import androidx.compose.foundation.layout.fillMaxWidth 9 | import androidx.compose.foundation.layout.height 10 | import androidx.compose.material.icons.Icons 11 | import androidx.compose.material.icons.filled.Add 12 | import androidx.compose.material.icons.filled.ArrowBack 13 | import androidx.compose.material3.BottomAppBar 14 | import androidx.compose.material3.ExperimentalMaterial3Api 15 | import androidx.compose.material3.FloatingActionButton 16 | import androidx.compose.material3.Icon 17 | import androidx.compose.material3.MaterialTheme 18 | import androidx.compose.material3.Scaffold 19 | import androidx.compose.material3.Text 20 | import androidx.compose.material3.TopAppBar 21 | import androidx.compose.material3.TopAppBarDefaults.mediumTopAppBarColors 22 | import androidx.compose.runtime.Composable 23 | import androidx.compose.ui.Alignment 24 | import androidx.compose.ui.Modifier 25 | import androidx.compose.ui.graphics.Color 26 | import androidx.compose.ui.platform.LocalContext 27 | import androidx.compose.ui.text.TextStyle 28 | import androidx.compose.ui.text.style.TextAlign 29 | import androidx.compose.ui.unit.dp 30 | import androidx.compose.ui.unit.sp 31 | 32 | @OptIn(ExperimentalMaterial3Api::class) 33 | @Composable 34 | fun baseUI(bottomLayout: (@Composable () -> Unit) = { BottomLayout() }, content: @Composable (PaddingValues) -> Unit, onClick: () -> Unit) { 35 | val context = LocalContext.current 36 | Scaffold(topBar = { 37 | TopAppBar(modifier = Modifier 38 | .fillMaxWidth() 39 | .background(Color.Blue) 40 | .height(81.dp), colors = mediumTopAppBarColors( 41 | containerColor = Color.Blue, 42 | titleContentColor = MaterialTheme.colorScheme.primary, 43 | ), title = { 44 | Row( 45 | modifier = Modifier 46 | .fillMaxWidth() 47 | .fillMaxHeight(), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center 48 | ) { 49 | Text(text = "compose写法标题栏", fontSize = 18.sp, color = Color.Red, style = TextStyle.Default) 50 | } 51 | }) 52 | }, bottomBar = bottomLayout, floatingActionButton = { 53 | FloatingActionButton(onClick = onClick) { 54 | Icon( 55 | Icons.Default.ArrowBack, contentDescription = "Add", tint = Color.Red 56 | ) 57 | } 58 | }) { innerPadding -> 59 | content(innerPadding) 60 | } 61 | } 62 | 63 | @Composable 64 | fun BottomLayout() { 65 | BottomAppBar( 66 | modifier = Modifier 67 | .fillMaxWidth() 68 | .height(50.dp), 69 | containerColor = MaterialTheme.colorScheme.primaryContainer, 70 | contentColor = MaterialTheme.colorScheme.primary, 71 | ) { 72 | Text( 73 | text = "compose 底部栏", fontSize = 18.sp, color = Color.Red, style = TextStyle.Default, textAlign = TextAlign.Center, modifier = Modifier.fillMaxWidth() 74 | ) 75 | } 76 | } 77 | 78 | 79 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/data/DataBean.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose1.ui.data 2 | 3 | data class DataBean( 4 | val id: Long, val title: String, val imgUrl: String, val resID: Int 5 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/data/MainUIItem.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose1.ui.data 2 | 3 | import androidx.activity.ComponentActivity 4 | 5 | data class MainUIItem( 6 | val title: String, val clazz: Class 7 | ) 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/data/TopDataSource.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose.plugin.data 2 | 3 | data class TopDataSource(val title: String, val img: String, val value: Float, val vectorResId: Int = 0) 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/theme/Color.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose1.ui.theme 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | val Purple80 = Color(0xFFD0BCFF) 6 | val PurpleGrey80 = Color(0xFFCCC2DC) 7 | val Pink80 = Color(0xFFEFB8C8) 8 | 9 | val Purple40 = Color(0xFF6650a4) 10 | val PurpleGrey40 = Color(0xFF625b71) 11 | val Pink40 = Color(0xFF7D5260) -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/theme/Theme.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose1.ui.theme 2 | 3 | import android.os.Build 4 | import androidx.compose.foundation.isSystemInDarkTheme 5 | import androidx.compose.material3.MaterialTheme 6 | import androidx.compose.material3.darkColorScheme 7 | import androidx.compose.material3.dynamicDarkColorScheme 8 | import androidx.compose.material3.dynamicLightColorScheme 9 | import androidx.compose.material3.lightColorScheme 10 | import androidx.compose.runtime.Composable 11 | import androidx.compose.ui.platform.LocalContext 12 | 13 | private val DarkColorScheme = darkColorScheme( 14 | primary = Purple80, secondary = PurpleGrey80, tertiary = Pink80 15 | ) 16 | 17 | private val LightColorScheme = lightColorScheme( 18 | primary = Purple40, secondary = PurpleGrey40, tertiary = Pink40 19 | 20 | /* Other default colors to override 21 | background = Color(0xFFFFFBFE), 22 | surface = Color(0xFFFFFBFE), 23 | onPrimary = Color.White, 24 | onSecondary = Color.White, 25 | onTertiary = Color.White, 26 | onBackground = Color(0xFF1C1B1F), 27 | onSurface = Color(0xFF1C1B1F), 28 | */ 29 | ) 30 | 31 | @Composable 32 | fun WXComposePlugin( 33 | darkTheme: Boolean = isSystemInDarkTheme(), 34 | // Dynamic color is available on Android 12+ 35 | dynamicColor: Boolean = true, content: @Composable () -> Unit 36 | ) { 37 | val colorScheme = when { 38 | dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { 39 | val context = LocalContext.current 40 | if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) 41 | } 42 | 43 | darkTheme -> DarkColorScheme 44 | else -> LightColorScheme 45 | } 46 | 47 | MaterialTheme( 48 | colorScheme = colorScheme, typography = Typography, content = content 49 | ) 50 | } -------------------------------------------------------------------------------- /app/src/main/java/com/wx/compose/plugin/theme/Type.kt: -------------------------------------------------------------------------------- 1 | package com.wx.compose1.ui.theme 2 | 3 | import androidx.compose.material3.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 | bodyLarge = TextStyle( 12 | fontFamily = FontFamily.Default, 13 | fontWeight = FontWeight.Normal, 14 | fontSize = 16.sp, 15 | lineHeight = 24.sp, 16 | letterSpacing = 0.5.sp 17 | ) 18 | /* Other default text styles to override 19 | titleLarge = TextStyle( 20 | fontFamily = FontFamily.Default, 21 | fontWeight = FontWeight.Normal, 22 | fontSize = 22.sp, 23 | lineHeight = 28.sp, 24 | letterSpacing = 0.sp 25 | ), 26 | labelSmall = TextStyle( 27 | fontFamily = FontFamily.Default, 28 | fontWeight = FontWeight.Medium, 29 | fontSize = 11.sp, 30 | lineHeight = 16.sp, 31 | letterSpacing = 0.5.sp 32 | ) 33 | */ 34 | ) -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/ava1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wgllss/WX-Compose-Plugin/f6d693f1a5b1d34cb5b3972c27e0b68101953a69/app/src/main/res/drawable-nodpi/ava1.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/ava2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wgllss/WX-Compose-Plugin/f6d693f1a5b1d34cb5b3972c27e0b68101953a69/app/src/main/res/drawable-nodpi/ava2.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/ava3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wgllss/WX-Compose-Plugin/f6d693f1a5b1d34cb5b3972c27e0b68101953a69/app/src/main/res/drawable-nodpi/ava3.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/people_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wgllss/WX-Compose-Plugin/f6d693f1a5b1d34cb5b3972c27e0b68101953a69/app/src/main/res/drawable-nodpi/people_4.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_dashboard_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_home_black_24dp.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_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_notifications_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wgllss/WX-Compose-Plugin/f6d693f1a5b1d34cb5b3972c27e0b68101953a69/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wgllss/WX-Compose-Plugin/f6d693f1a5b1d34cb5b3972c27e0b68101953a69/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wgllss/WX-Compose-Plugin/f6d693f1a5b1d34cb5b3972c27e0b68101953a69/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wgllss/WX-Compose-Plugin/f6d693f1a5b1d34cb5b3972c27e0b68101953a69/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wgllss/WX-Compose-Plugin/f6d693f1a5b1d34cb5b3972c27e0b68101953a69/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wgllss/WX-Compose-Plugin/f6d693f1a5b1d34cb5b3972c27e0b68101953a69/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wgllss/WX-Compose-Plugin/f6d693f1a5b1d34cb5b3972c27e0b68101953a69/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wgllss/WX-Compose-Plugin/f6d693f1a5b1d34cb5b3972c27e0b68101953a69/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wgllss/WX-Compose-Plugin/f6d693f1a5b1d34cb5b3972c27e0b68101953a69/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wgllss/WX-Compose-Plugin/f6d693f1a5b1d34cb5b3972c27e0b68101953a69/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 |