├── .gitignore ├── .idea ├── .gitignore ├── compiler.xml ├── gradle.xml ├── misc.xml └── vcs.xml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ └── andnext_markdown-debug.aar ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── seewo │ │ └── brick │ │ └── app │ │ ├── App.kt │ │ ├── component │ │ ├── ComponentFragment.kt │ │ ├── coordinator │ │ │ ├── CoordinatorLayoutActivity1.kt │ │ │ └── CoordinatorLayoutActivity2.kt │ │ ├── extra │ │ │ ├── ExtraComponentActivity.kt │ │ │ └── page │ │ │ │ ├── EmbededPage.kt │ │ │ │ ├── GlidePage.kt │ │ │ │ └── SmartRefreshPage.kt │ │ ├── layout │ │ │ ├── LayoutActivity.kt │ │ │ └── page │ │ │ │ ├── ColumnPage.kt │ │ │ │ ├── ConstraintPage.kt │ │ │ │ ├── FlexboxPage.kt │ │ │ │ ├── RelativePage.kt │ │ │ │ └── RowPage.kt │ │ ├── list │ │ │ ├── list │ │ │ │ ├── ListActivity.kt │ │ │ │ └── page │ │ │ │ │ ├── ComplexStatefulListPage.kt │ │ │ │ │ └── StatefulListPage.kt │ │ │ └── simple │ │ │ │ ├── SimpleListActivity.kt │ │ │ │ └── page │ │ │ │ ├── GridListPage.kt │ │ │ │ ├── HorizontalListPage.kt │ │ │ │ ├── ScrollViewPage.kt │ │ │ │ └── VerticalListPage.kt │ │ └── pager │ │ │ ├── PagerActivity.kt │ │ │ └── page │ │ │ ├── FragmentPagerPage.kt │ │ │ ├── LoopViewPagerPage.kt │ │ │ ├── TabLayoutViewPagerPage.kt │ │ │ └── ViewPagerPage.kt │ │ ├── extra │ │ ├── ExtraFragment.kt │ │ ├── about │ │ │ ├── AboutActivity.kt │ │ │ └── AboutPage.kt │ │ ├── counter │ │ │ ├── CounterActivity.kt │ │ │ ├── CounterPage.kt │ │ │ └── CounterPageViewModel.kt │ │ └── list │ │ │ ├── LongListActivity.kt │ │ │ └── LongListPage.kt │ │ ├── helper │ │ ├── HelperFragment.kt │ │ ├── animator │ │ │ ├── AnimatorHelperActivity.kt │ │ │ └── page │ │ │ │ └── AnimatorPage.kt │ │ ├── clip │ │ │ ├── ClipAndShadowHelperActivity.kt │ │ │ └── page │ │ │ │ ├── ClipPage.kt │ │ │ │ └── ShadowPage.kt │ │ ├── color │ │ │ ├── ColorAndDrawableHelperActivity.kt │ │ │ └── page │ │ │ │ ├── ColorPage.kt │ │ │ │ └── DrawablePage.kt │ │ └── spannable │ │ │ ├── SpannableHelperActivity.kt │ │ │ └── page │ │ │ └── SpannablePage.kt │ │ ├── main │ │ ├── MainActivity.kt │ │ ├── MainFragmentList.kt │ │ ├── MainItemBean.kt │ │ └── MainPage.kt │ │ └── widget │ │ ├── CommonKTX.kt │ │ ├── Markdown.kt │ │ ├── MultiTabViewPager.kt │ │ ├── SeekValue.kt │ │ └── TopBar.kt │ └── res │ ├── drawable-hdpi │ ├── ic_expand_web.png │ ├── ic_util_color.png │ ├── ic_util_drawable.png │ ├── ic_widget_button.png │ ├── ic_widget_dialog.png │ ├── ic_widget_flowlayout.png │ ├── ic_widget_layout.png │ ├── ic_widget_loading.png │ ├── ic_widget_picker_view.png │ ├── ic_widget_spinner.png │ ├── ic_widget_statelayout.png │ ├── ic_widget_titlebar.png │ ├── icon_tabbar_component.png │ ├── icon_tabbar_component_selected.png │ ├── icon_tabbar_expand.png │ ├── icon_tabbar_expand_selected.png │ ├── icon_tabbar_util.png │ └── icon_tabbar_util_selected.png │ ├── drawable-xhdpi │ ├── btn_add_food.png │ ├── ic_back_white.webp │ ├── page1.webp │ ├── page2.webp │ ├── page3.webp │ ├── tab_courseware_normal.png │ ├── tab_courseware_press.png │ ├── tab_me_normal.png │ └── tab_me_press.png │ ├── drawable │ ├── ic_back_dark.xml │ ├── ic_checked_right.xml │ ├── ic_launcher_background.xml │ ├── ic_well_chosen.xml │ ├── selector_icon_tabbar_component.xml │ ├── selector_icon_tabbar_expand.xml │ ├── selector_icon_tabbar_util.xml │ ├── tab_color.xml │ ├── tab_me.xml │ ├── tab_permission.xml │ └── white_radius.xml │ ├── mipmap │ └── ic_launcher.webp │ ├── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ ├── styles.xml │ └── themes.xml │ └── xml │ ├── backup_rules.xml │ └── data_extraction_rules.xml ├── build.gradle ├── core ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── gradle.properties ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── seewo │ │ └── brick │ │ ├── BrickPreview.kt │ │ ├── BrickUI.kt │ │ ├── JavaDrawableUtils.java │ │ ├── cache │ │ └── DrawableCache.kt │ │ ├── drawable │ │ ├── OvalClipDrawable.kt │ │ └── RectClipDrawable.kt │ │ ├── init │ │ ├── BrickUIInitializer.kt │ │ └── ViewInit.kt │ │ ├── ktx │ │ ├── layout │ │ │ ├── CollapsingToolbarLayout.kt │ │ │ ├── ConstraintLayoutKTX.kt │ │ │ ├── CoordinatorLayout.kt │ │ │ ├── FlexboxLayoutKTX.kt │ │ │ ├── FrameLayoutKTX.kt │ │ │ ├── GridLayoutKTX.kt │ │ │ ├── LayoutKTX.kt │ │ │ ├── LinearLayoutKTX.kt │ │ │ ├── NestedScrollView.kt │ │ │ ├── RelativeLayoutKTX.kt │ │ │ ├── TabLayoutKTX.kt │ │ │ └── Toolbar.kt │ │ ├── util │ │ │ ├── ActivityKTX.kt │ │ │ ├── AnimatorKTX.kt │ │ │ ├── CommonKTX.kt │ │ │ ├── DrawableKTX.kt │ │ │ ├── ResourceKTX.kt │ │ │ ├── SpanKTX.kt │ │ │ └── ViewClipKTX.kt │ │ └── widget │ │ │ ├── FragmentKTX.kt │ │ │ ├── FragmentPagerKTX.kt │ │ │ ├── NestedScrollableKTX.kt │ │ │ ├── RecyclerViewKTX.kt │ │ │ ├── SimpleRecyclerViewKTX.kt │ │ │ ├── SimpleStatelessRecyclerViewKTX.kt │ │ │ ├── ViewKTX.kt │ │ │ └── ViewPagerKTX.kt │ │ ├── params │ │ ├── CollapseMode.java │ │ ├── CompoundDrawables.kt │ │ ├── CornerRadius.kt │ │ ├── EdgeInsets.kt │ │ ├── RecyclerItemData.kt │ │ └── Shadow.kt │ │ ├── span │ │ └── CenterAlignImageSpan.java │ │ └── view │ │ ├── BrickFragment.kt │ │ ├── ConstraintHelper.kt │ │ ├── DividerDecoration.kt │ │ ├── FixDurationScroller.kt │ │ ├── GridSpaceDecoration.kt │ │ ├── LimitLinesFlexboxLayout.kt │ │ ├── NestedScrollableHost.kt │ │ ├── ShadowLayout.kt │ │ └── WindowInsetsFrameLayout.kt │ └── res │ └── animator │ └── scale_with_alpha.xml ├── dependencies.gradle ├── doc ├── BrickUI.md ├── BrickUIPreview.png ├── CvteCall.png ├── QRCodeDemo.png ├── RecylerView.md ├── courseLive.png ├── demo_page.png ├── en.png └── seewoScan.png ├── glide ├── .gitignore ├── build.gradle ├── gradle.properties ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── seewo │ └── brick │ ├── glide │ └── exception │ │ └── GlideBlurTransformation.kt │ └── ktx │ └── GlideKTX.kt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradles ├── jfrog-push.gradle ├── jitpack-push.gradle └── utils.gradle ├── gradlew ├── gradlew.bat ├── live ├── .gitignore ├── build.gradle ├── gradle.properties ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── seewo │ └── brick │ ├── ktx │ ├── LifecycleKTX.kt │ ├── LiveBrickViewKTX.kt │ ├── LiveDataKTX.kt │ ├── LiveGlideKTX.kt │ ├── LiveLayoutKTX.kt │ ├── LiveLoopPager.kt │ ├── LiveRecyclerViewKTX.kt │ ├── LiveResourceKTX.kt │ ├── LiveSmartRefreshKTX.kt │ ├── LiveViewKTX.kt │ └── LiveViewPager.kt │ └── live │ └── params │ └── StaticData.kt ├── loop-pager ├── .gitignore ├── build.gradle ├── gradle.properties ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── seewo │ │ └── brick │ │ ├── indicator │ │ ├── BaseCircleIndicator.kt │ │ ├── CircleIndicator.kt │ │ └── CircleIndicator3.kt │ │ ├── ktx │ │ ├── IndicatorKTX.kt │ │ ├── InternalKTX.kt │ │ └── LoopPagerKTX.kt │ │ └── pager │ │ ├── LoopPagerAdapterWrapper.kt │ │ └── LoopViewPager.kt │ └── res │ └── animator │ └── scale_with_alpha.xml ├── settings.gradle ├── smart-refresh ├── .gitignore ├── build.gradle ├── gradle.properties ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── seewo │ └── brick │ └── ktx │ └── SmartRefreshKTX.kt └── versions.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/ 17 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 25 | 26 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 14 | 15 | 16 | 17 | 18 | 20 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change LOG 2 | 3 | ### 0.2.43 4 | 5 | - [feature] TabLayout增加fixedItemWidth参数:当tabMode为MODE_SCROLLABLE时,设置每个Tab的固定宽度(如果不设置,可能控件自带奇怪的padding) 6 | - [fix] liveTabLayout的data参数改为LiveData类型 7 | - [fix] 修复设置阴影的blur较小,offset较大时,内容被裁剪的问题 8 | 9 | ### 0.2.40 10 | 11 | - [fix] 修复loopPager嵌套在RecyclerView或ViewPager中时,进行自动动画翻页时的几个经典bug,如翻页动画丢失,动画卡在一半 12 | - [fix] 修复liveLoopPager闪退问题,liveLoopPager的duration改为LiveData类型 13 | 14 | ### 0.2.36 15 | 16 | - [feature] 为DrawableKTX增加简单的缓存机制,调用方需要设置cacheKey以使其生效,并需要保证cacheKey不变且唯一 17 | 18 | ### 0.2.35 19 | 20 | - [improve] loop-pager在onStop时,停止轮播,onStart恢复轮播 21 | 22 | ### 0.2.34 23 | 24 | - [feature] loop-pager提供live支持 25 | - [feature] loop-pager支持设置滚动动画时长 26 | - [feature] glideImage提供live支持 27 | 28 | ### 0.2.31 29 | 30 | - [feature] 添加nestedScrollableChild,帮助解决ViewPager2等的嵌套导致的滑动冲突问题 31 | - [improve] 为viewPager添加以Context为接收者的函数 32 | 33 | ### 0.2.30 34 | 35 | - [feature] 添加brick函数用于嵌入普通View,废弃view函数 36 | - [improve] 为ViewKTX中的函数均添加以Context为接收者的函数 37 | - [feature] 封装loop-pager组件,提供轮播图和pager指示器的实现 (基于[CircleIndicator](https://github.com/ongakuer/CircleIndicator)实现) 38 | 39 | ### 0.2.23 40 | 41 | - improve: 对于LiveData添加了toVisibility()扩展函数,inverse扩展属性,并重载了not操作符 42 | 43 | ### 0.2.22 44 | 45 | - improve: 为资源相关扩展函数添加类型注解 46 | - improve: RecyclerView,SmartRefresh等添加Receiver为Context的扩展函数 47 | 48 | ### 0.2.21 49 | 50 | - improve: runAnimator和live组件允许传入LifecycleOwner,避免在Fragment使用时造成内存泄露 51 | 52 | ### 0.2.20 53 | 54 | - improve: runAnimator增加生命周期监听并自动取消动画 55 | 56 | ### 0.2.19 57 | 58 | - feature: 提供更易调用的`LiveData.bind(context, block)`和`LiveData.bindNotNull(context, block)`方法,方便开发者绑定LiveData到View。 59 | - improve: 优化`LiveData.bind(context, block)`和`LiveData.bindNotNull(context, block)`方法的实现,如果value无变化,不会重复调用`block`方法 60 | > **注意**,以上两个方法所接收的Context必须是FragmentActivity一类的`LifecycleOwner`,否则绑定无法生效 61 | 62 | ### 0.2.17 63 | 64 | - feature: 统一为ViewGroup构造的View添加`margin`参数 65 | 66 | ### 0.2.16 67 | 68 | - Improve: 移除`Fragment.fragmentPager()`方法,改用参数`parentFragment`参数来实现此功能 69 | 70 | ### 0.2.15 71 | 72 | - Improve: `smartRefresh`提到单独module:com.github.robin8yeung.BrickUI:brick-ui-smart-refresh。**(注意:用到smartRefresh的话必须引入此依赖)** 73 | - feature: 添加`Fragment.fragmentPager()`方法,来构造基于Fragment生命周期的fragmentPager 74 | - feature: 统一增加`foreground`属性(系统版本23以上才支持) 75 | - feature: 提供`livePlaceHolder()`构造占位View 76 | 77 | ### 0.2.14 78 | 79 | - Improve: 为LiveData增加combine扩展函数,方便合并2个LiveData的值来处理UI状态 80 | 81 | ### 0.2.13 82 | 83 | - Improve: 允许RecyclerView类控件接受非RecyclerItemData类型的数据,但仍然强烈建议传入RecyclerItemData类型的数据,以使用DiffUtil来更新RecyclerView 84 | 85 | ### 0.2.12 86 | 87 | - New: 增加CoordinatorLayout相关的支持 88 | 89 | ### 0.2.11 90 | 91 | - New: 增加TabLayout相关的支持 92 | 93 | ### 0.2.7 94 | 95 | - Improve: 补充LiveLayoutKTX中几个Context的扩展布局函数 96 | 97 | ### 0.2.6 98 | 99 | - Improve: 对几种Widget引入泛型,避免丢类型 100 | 101 | ### 0.2.5 102 | 103 | - New: 增加sourceJar打包,避免使用时无法链接到源码 104 | 105 | ### 0.2.1 106 | 107 | - New: 首次正式发布版本 108 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'org.jetbrains.kotlin.android' 4 | } 5 | 6 | android { 7 | compileSdk 32 8 | 9 | defaultConfig { 10 | applicationId "com.seewo.brick.app" 11 | minSdk 21 12 | targetSdk 32 13 | versionCode 1 14 | versionName "1.0" 15 | 16 | } 17 | 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | compileOptions { 25 | sourceCompatibility JavaVersion.VERSION_1_8 26 | targetCompatibility JavaVersion.VERSION_1_8 27 | } 28 | kotlinOptions { 29 | jvmTarget = '1.8' 30 | } 31 | buildFeatures { 32 | viewBinding true 33 | } 34 | } 35 | 36 | dependencies { 37 | implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs') 38 | // implementation(name: 'andnext_markdown-debug', ext: 'aar') 39 | implementation rootProject.ext.deps.kotlin.coroutines.core 40 | implementation rootProject.ext.deps.kotlin.coroutines.android 41 | 42 | implementation rootProject.ext.deps.android.appcompat 43 | implementation rootProject.ext.deps.android.material 44 | implementation rootProject.ext.deps.android.constraintlayout 45 | 46 | implementation rootProject.ext.deps.toast 47 | 48 | // KTX 49 | implementation rootProject.ext.deps.ktx.core 50 | implementation rootProject.ext.deps.ktx.collection 51 | implementation rootProject.ext.deps.ktx.fragment 52 | implementation project(':core') 53 | implementation project(':live') 54 | implementation project(':smart-refresh') 55 | implementation project(':loop-pager') 56 | implementation project(':glide') 57 | implementation rootProject.ext.deps.glide 58 | 59 | implementation rootProject.ext.deps.android.flexbox 60 | 61 | implementation rootProject.ext.deps.smart_refresh_new.core 62 | implementation rootProject.ext.deps.smart_refresh_new.classics_header 63 | implementation rootProject.ext.deps.smart_refresh_new.classics_footer 64 | } -------------------------------------------------------------------------------- /app/libs/andnext_markdown-debug.aar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/libs/andnext_markdown-debug.aar -------------------------------------------------------------------------------- /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/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 20 | 24 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/App.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app 2 | 3 | import android.app.Application 4 | import com.hjq.toast.ToastUtils 5 | 6 | class App: Application() { 7 | override fun onCreate() { 8 | super.onCreate() 9 | ToastUtils.init(this) 10 | } 11 | } -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/component/ComponentFragment.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.component 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import com.seewo.brick.BrickPreview 6 | import com.seewo.brick.app.R 7 | import com.seewo.brick.app.component.coordinator.CoordinatorLayoutActivity1 8 | import com.seewo.brick.app.component.coordinator.CoordinatorLayoutActivity2 9 | import com.seewo.brick.app.component.extra.ExtraComponentActivity 10 | import com.seewo.brick.app.component.layout.LayoutActivity 11 | import com.seewo.brick.app.component.list.list.ListActivity 12 | import com.seewo.brick.app.component.list.simple.SimpleListActivity 13 | import com.seewo.brick.app.component.pager.PagerActivity 14 | import com.seewo.brick.app.main.MainItemBean 15 | import com.seewo.brick.app.main.mainFragmentList 16 | import com.seewo.brick.ktx.drawable 17 | import com.seewo.brick.ktx.startActivity 18 | import com.seewo.brick.ktx.view 19 | 20 | class PreviewComponentFragment(context: Context, attrs: AttributeSet? = null) : 21 | BrickPreview(context, attrs) { 22 | 23 | override fun preview(context: Context) { 24 | view { 25 | context.ComponentPage() 26 | } 27 | } 28 | } 29 | 30 | fun Context.ComponentPage() = mainFragmentList( 31 | listOf( 32 | MainItemBean("控件与布局", R.drawable.ic_widget_layout.drawable) { 33 | startActivity() 34 | }, 35 | MainItemBean("吸顶布局", R.drawable.ic_widget_titlebar.drawable) { 36 | startActivity() 37 | }, 38 | MainItemBean("折叠布局", R.drawable.ic_widget_titlebar.drawable) { 39 | startActivity() 40 | }, 41 | MainItemBean("增强控件", R.drawable.icon_tabbar_expand_selected.drawable) { 42 | startActivity() 43 | }, 44 | MainItemBean("静态列表", R.drawable.ic_widget_flowlayout.drawable) { 45 | startActivity() 46 | }, 47 | MainItemBean("动态列表", R.drawable.ic_widget_picker_view.drawable) { 48 | startActivity() 49 | }, 50 | MainItemBean("分页", R.drawable.ic_widget_statelayout.drawable) { 51 | startActivity() 52 | }, 53 | ) 54 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/component/extra/ExtraComponentActivity.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.component.extra 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.seewo.brick.app.component.extra.page.EmbededPage 6 | import com.seewo.brick.app.component.extra.page.GlidePage 7 | import com.seewo.brick.app.component.extra.page.SmartRefreshPage 8 | import com.seewo.brick.app.widget.multiTabViewPager 9 | import com.seewo.brick.ktx.MATCH_PARENT 10 | import com.seewo.brick.ktx.frameLayout 11 | import com.seewo.brick.ktx.setStatusBarTransparent 12 | 13 | class ExtraComponentActivity : AppCompatActivity() { 14 | 15 | override fun onCreate(savedInstanceState: Bundle?) { 16 | super.onCreate(savedInstanceState) 17 | setStatusBarTransparent(true) 18 | setContentView(multiTabViewPager( 19 | data = listOf( 20 | "图片加载", 21 | "下拉加载", 22 | "原生控件嵌入", 23 | ), 24 | ) { _, index -> 25 | when (index) { 26 | 0 -> GlidePage() 27 | 1 -> SmartRefreshPage() 28 | 2 -> EmbededPage() 29 | else -> frameLayout( 30 | MATCH_PARENT, MATCH_PARENT, 31 | ) 32 | } 33 | }) 34 | } 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/component/extra/page/EmbededPage.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.component.extra.page 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.widget.LinearLayout 6 | import com.seewo.brick.BrickPreview 7 | import com.seewo.brick.app.widget.Markdown 8 | import com.seewo.brick.ktx.MATCH_PARENT 9 | import com.seewo.brick.ktx.column 10 | import com.seewo.brick.ktx.expand 11 | import com.seewo.brick.ktx.view 12 | 13 | private class EmbededPage(context: Context, attrs: AttributeSet? = null) : 14 | BrickPreview(context, attrs) { 15 | 16 | override fun preview(context: Context) { 17 | view { 18 | context.EmbededPage() 19 | } 20 | } 21 | } 22 | 23 | fun Context.EmbededPage() = column( 24 | MATCH_PARENT, MATCH_PARENT, 25 | ) { 26 | ShowMarkDown() 27 | } 28 | 29 | private fun LinearLayout.ShowMarkDown() { 30 | expand { 31 | Markdown( 32 | """ 33 | ## 代码展示 34 | 35 | 虽然BrickUI封装了一些常用的控件,和一些好用的第三方控件,但不可能对所有控件都进行封装,而且这样做意义不大。 36 | 由于BrickUI本身就是基于View体系实现的,把第三方控件嵌入到BrickUI中并非难事。 37 | 当前你所看到的Markdown文档就是用第三方控件来展示的,实现如下: 38 | 39 | ```kotlin 40 | private fun LinearLayout.ShowMarkDown() { 41 | expand { 42 | Markdown( 43 | ""${'"'} 44 | ... 45 | 这里是 Markdown 文档 46 | ... 47 | ""${'"'}.trimIndent() 48 | ) 49 | } 50 | } 51 | 52 | fun ViewGroup.Markdown( 53 | text: String 54 | ): View { 55 | if (isInEditMode) return placeholder() // 避免预览模式报错 56 | return view { 57 | // 第三方控件:MarkdownWebView 58 | MarkdownWebView(context).apply { 59 | // 初始化宽高 60 | init(MATCH_PARENT, MATCH_PARENT) 61 | setText(text) 62 | } 63 | } 64 | } 65 | ``` 66 | """.trimIndent() 67 | ) 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/component/extra/page/GlidePage.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.component.extra.page 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.widget.LinearLayout 6 | import com.bumptech.glide.load.resource.bitmap.CenterCrop 7 | import com.bumptech.glide.load.resource.bitmap.RoundedCorners 8 | import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions 9 | import com.bumptech.glide.request.RequestOptions 10 | import com.hjq.toast.ToastUtils 11 | import com.seewo.brick.BrickPreview 12 | import com.seewo.brick.app.widget.Markdown 13 | import com.seewo.brick.ktx.* 14 | import com.seewo.brick.params.EdgeInsets 15 | 16 | private class GlidePage(context: Context, attrs: AttributeSet? = null) : 17 | BrickPreview(context, attrs) { 18 | 19 | override fun preview(context: Context) { 20 | view { 21 | context.GlidePage() 22 | } 23 | } 24 | } 25 | 26 | fun Context.GlidePage() = column( 27 | MATCH_PARENT, MATCH_PARENT, 28 | ) { 29 | networkImages() 30 | 31 | ShowMarkDown() 32 | } 33 | 34 | private fun LinearLayout.networkImages() { 35 | row( 36 | padding = EdgeInsets.symmetric(4.dp, 16.dp) 37 | ) { 38 | // 简单加载图片 39 | glideImage( 40 | urlOrPath = "https://easinote.seewo.com/statics/modules/themes/images/index/1x/qrode_ebf6c6e.png", 41 | ) { 42 | // 可选择imageView,也可选择liveImage 43 | imageView(84.dp, 84.dp) 44 | } 45 | // 自定义各种参数和回调 46 | glideImage( 47 | urlOrPath = "https://img0.baidu.com/it/u=3995530121,45712565&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=313", 48 | transition = DrawableTransitionOptions.withCrossFade(), 49 | requestOptions = RequestOptions() 50 | .transform( 51 | CenterCrop(), RoundedCorners(4.dp), 52 | ), 53 | onLoadFailed = { 54 | ToastUtils.show("图片加载异常") 55 | }, 56 | onResourceReady = { 57 | ToastUtils.show("图片加载完成") 58 | } 59 | ) { 60 | imageView(150.dp, 84.dp) 61 | } 62 | } 63 | } 64 | 65 | private fun LinearLayout.ShowMarkDown() { 66 | expand { 67 | Markdown( 68 | """ 69 | ## 代码展示 70 | 71 | 主要提供了 glideImage、glideGif 2个函数来修饰ImageView,用于执行网络图片或本地图片加载,提供了Glide框架的相关能力 72 | 73 | ```kotlin 74 | private fun LinearLayout.networkImages() { 75 | row( 76 | padding = EdgeInsets.symmetric(4.dp, 16.dp) 77 | ) { 78 | // 简单加载图片 79 | glideImage( 80 | urlOrPath = "https://easinote.seewo.com/statics/modules/themes/images/index/1x/qrode_ebf6c6e.png", 81 | ) { 82 | // 可选择imageView,也可选择liveImage 83 | imageView(84.dp, 84.dp) 84 | } 85 | // 自定义各种参数和回调 86 | glideImage( 87 | urlOrPath = "https://img0.baidu.com/it/u=3995530121,45712565&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=313", 88 | transition = DrawableTransitionOptions.withCrossFade(), 89 | requestOptions = RequestOptions() 90 | .transform( 91 | CenterCrop(), RoundedCorners(4.dp), 92 | ), 93 | onLoadFailed = { 94 | ToastUtils.show("图片加载异常") 95 | }, 96 | onResourceReady = { 97 | ToastUtils.show("图片加载完成") 98 | } 99 | ) { 100 | imageView(150.dp, 84.dp) 101 | } 102 | } 103 | } 104 | ``` 105 | """.trimIndent() 106 | ) 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/component/layout/LayoutActivity.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.component.layout 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.seewo.brick.app.component.layout.page.ColumnPage 6 | import com.seewo.brick.app.component.layout.page.ConstraintPage 7 | import com.seewo.brick.app.component.layout.page.FlexboxPage 8 | import com.seewo.brick.app.component.layout.page.RelativePage 9 | import com.seewo.brick.app.component.layout.page.RowPage 10 | import com.seewo.brick.app.widget.multiTabViewPager 11 | import com.seewo.brick.ktx.MATCH_PARENT 12 | import com.seewo.brick.ktx.frameLayout 13 | import com.seewo.brick.ktx.setStatusBarTransparent 14 | 15 | class LayoutActivity : AppCompatActivity() { 16 | 17 | override fun onCreate(savedInstanceState: Bundle?) { 18 | super.onCreate(savedInstanceState) 19 | setStatusBarTransparent(true) 20 | setContentView(multiTabViewPager( 21 | data = listOf( 22 | "行布局", 23 | "列布局", 24 | "相对布局", 25 | "约束布局", 26 | "Flexbox布局", 27 | ), 28 | viewPagerBuilder = { _, index -> 29 | when (index) { 30 | 0 -> RowPage() 31 | 1 -> ColumnPage() 32 | 2 -> RelativePage() 33 | 3 -> ConstraintPage() 34 | 4 -> FlexboxPage() 35 | else -> frameLayout( 36 | MATCH_PARENT, MATCH_PARENT, 37 | ) 38 | } 39 | } 40 | )) 41 | } 42 | } -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/component/layout/page/FlexboxPage.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.component.layout.page 2 | 3 | import android.content.Context 4 | import android.graphics.Color 5 | import android.util.AttributeSet 6 | import android.widget.LinearLayout 7 | import com.seewo.brick.BrickPreview 8 | import com.seewo.brick.app.widget.Markdown 9 | import com.seewo.brick.ktx.MATCH_PARENT 10 | import com.seewo.brick.ktx.column 11 | import com.seewo.brick.ktx.dp 12 | import com.seewo.brick.ktx.expand 13 | import com.seewo.brick.ktx.flexboxLayout 14 | import com.seewo.brick.ktx.rectDrawable 15 | import com.seewo.brick.ktx.textView 16 | import com.seewo.brick.ktx.view 17 | import com.seewo.brick.ktx.withAlpha 18 | import com.seewo.brick.params.CornerRadius 19 | import com.seewo.brick.params.EdgeInsets 20 | import com.seewo.brick.view.LimitLinesFlexboxLayout 21 | 22 | class FlexboxPage(context: Context, attrs: AttributeSet? = null) : 23 | BrickPreview(context, attrs) { 24 | 25 | override fun preview(context: Context) { 26 | view { 27 | context.FlexboxPage() 28 | } 29 | } 30 | } 31 | 32 | fun Context.FlexboxPage() = column( 33 | MATCH_PARENT, MATCH_PARENT, 34 | ) { 35 | Chips() 36 | ShowMarkDown() 37 | } 38 | 39 | private fun LinearLayout.Chips() { 40 | // flexboxLayout 用于线性展示控件,并在控件不够时可以换行 41 | // 需要引入FlexboxLayout的依赖 com.google.android.flexbox:flexbox 42 | flexboxLayout( 43 | MATCH_PARENT, 44 | padding = EdgeInsets.symmetric(8.dp, 16.dp) 45 | ) { 46 | repeat(10) { 47 | Chip(it) 48 | } 49 | } 50 | } 51 | 52 | private fun LimitLinesFlexboxLayout.Chip(it: Int) { 53 | textView( 54 | background = rectDrawable( 55 | corners = CornerRadius.all(4.dp), 56 | fillColor = Color.GRAY.withAlpha(0.7f), 57 | ), 58 | margin = EdgeInsets.all(4.dp), 59 | padding = EdgeInsets.symmetric(2.dp, 6.dp), 60 | text = "TAG $it", 61 | textColor = Color.WHITE, 62 | textSize = 12.dp, 63 | ) 64 | } 65 | 66 | private fun LinearLayout.ShowMarkDown() { 67 | expand { 68 | Markdown( 69 | """ 70 | ## 代码展示 71 | 72 | 需要引入FlexboxLayout的依赖 com.google.android.flexbox:flexbox 73 | 74 | ```kotlin 75 | private fun LinearLayout.Chips() { 76 | // flexboxLayout 用于线性展示控件,并在控件不够时可以换行 77 | flexboxLayout( 78 | MATCH_PARENT, 79 | padding = EdgeInsets.symmetric(8.dp, 16.dp) 80 | ) { 81 | repeat(10) { 82 | Chip(it) 83 | } 84 | } 85 | } 86 | 87 | private fun LimitLinesFlexboxLayout.Chip(it: Int) { 88 | textView( 89 | background = rectDrawable( 90 | corners = CornerRadius.all(4.dp), 91 | fillColor = Color.GRAY.withAlpha(0.7f), 92 | ), 93 | margin = EdgeInsets.all(4.dp), 94 | padding = EdgeInsets.symmetric(2.dp, 6.dp), 95 | text = "TAG ${'$'}it", 96 | textColor = Color.WHITE, 97 | textSize = 12.dp, 98 | ) 99 | } 100 | ``` 101 | """.trimIndent() 102 | ) 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/component/layout/page/RelativePage.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.component.layout.page 2 | 3 | import android.content.Context 4 | import android.graphics.Color 5 | import android.util.AttributeSet 6 | import android.widget.LinearLayout 7 | import android.widget.RelativeLayout 8 | import com.seewo.brick.BrickPreview 9 | import com.seewo.brick.app.R 10 | import com.seewo.brick.app.widget.Markdown 11 | import com.seewo.brick.ktx.* 12 | import com.seewo.brick.params.EdgeInsets 13 | 14 | class RelativePage(context: Context, attrs: AttributeSet? = null) : 15 | BrickPreview(context, attrs) { 16 | 17 | override fun preview(context: Context) { 18 | view { 19 | context.RelativePage() 20 | } 21 | } 22 | } 23 | 24 | fun Context.RelativePage() = column( 25 | MATCH_PARENT, MATCH_PARENT, 26 | animateLayoutChanges = true, 27 | ) { 28 | IconWithBadge() 29 | ShowMarkDown() 30 | } 31 | 32 | private fun LinearLayout.IconWithBadge() { 33 | relativeLayout( 34 | MATCH_PARENT, 35 | padding = EdgeInsets.symmetric(vertical = 8.dp, horizontal = 16.dp) 36 | ) { 37 | // icon在布局内居中 38 | layoutParams( 39 | rules = { 40 | addRule(RelativeLayout.CENTER_IN_PARENT) 41 | }, 42 | ) { 43 | // 圆角裁剪 44 | roundRectClip(radius = 4.dp) { 45 | // icon,这里id取得比较随意,正式使用,建议把id定义在ids.xml中 46 | imageView( 47 | 48.dp, 48.dp, 48 | id = 0x1234, 49 | drawable = R.mipmap.ic_launcher.drawable, 50 | ) 51 | } 52 | } 53 | // 红点布局与icon的右侧对齐 54 | layoutParams( 55 | rules = { 56 | addRule(RelativeLayout.ALIGN_END, 0x1234) 57 | }, 58 | margins = EdgeInsets.only(end = (-4).dp, top = (-4).dp) 59 | ) { 60 | // 随便用个占位符作为红点 61 | placeholder( 62 | 8.dp, 63 | 8.dp, 64 | background = ovalDrawable(fillColor = Color.RED) 65 | ) 66 | } 67 | }.apply { 68 | // 避免布局padding裁剪红点 69 | clipToOutline = false 70 | clipToPadding = false 71 | } 72 | } 73 | 74 | private fun LinearLayout.ShowMarkDown() { 75 | expand { 76 | Markdown( 77 | """ 78 | ## 代码展示 79 | 80 | ```kotlin 81 | private fun LinearLayout.IconWithBadge() { 82 | relativeLayout( 83 | MATCH_PARENT, 84 | padding = EdgeInsets.symmetric(vertical = 8.dp, horizontal = 16.dp) 85 | ) { 86 | // icon在布局内居中 87 | layoutParams( 88 | rules = { 89 | addRule(RelativeLayout.CENTER_IN_PARENT) 90 | }, 91 | ) { 92 | // 圆角裁剪 93 | roundRectClip(radius = 4.dp) { 94 | // icon,这里id取得比较随意,正式使用,建议把id定义在ids.xml中 95 | imageView( 96 | 48.dp, 48.dp, 97 | id = 0x1234, 98 | drawable = R.mipmap.ic_launcher.drawable, 99 | ) 100 | } 101 | } 102 | // 红点布局与icon的右侧对齐 103 | layoutParams( 104 | rules = { 105 | addRule(RelativeLayout.ALIGN_END, 0x1234) 106 | }, 107 | margins = EdgeInsets.only(end = (-4).dp, top = (-4).dp) 108 | ) { 109 | // 随便用个占位符作为红点 110 | placeholder( 111 | 8.dp, 112 | 8.dp, 113 | background = ovalDrawable(fillColor = Color.RED) 114 | ) 115 | } 116 | }.apply { 117 | // 避免布局padding裁剪红点 118 | clipToOutline = false 119 | clipToPadding = false 120 | } 121 | } 122 | ``` 123 | """.trimIndent() 124 | ) 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/component/list/list/ListActivity.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.component.list.list 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.seewo.brick.app.component.list.list.page.ComplexStatefulListPage 6 | import com.seewo.brick.app.component.list.list.page.StatefulListPage 7 | import com.seewo.brick.app.widget.multiTabViewPager 8 | import com.seewo.brick.ktx.MATCH_PARENT 9 | import com.seewo.brick.ktx.frameLayout 10 | import com.seewo.brick.ktx.setStatusBarTransparent 11 | 12 | class ListActivity : AppCompatActivity() { 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setStatusBarTransparent(true) 17 | setContentView(multiTabViewPager( 18 | data = listOf( 19 | "动态列表", 20 | "动态列表(复杂实现)", 21 | ), 22 | viewPagerBuilder = { _, index -> 23 | when (index) { 24 | 0 -> StatefulListPage() 25 | 1 -> ComplexStatefulListPage() 26 | else -> frameLayout( 27 | MATCH_PARENT, MATCH_PARENT, 28 | ) 29 | } 30 | } 31 | )) 32 | } 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/component/list/simple/SimpleListActivity.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.component.list.simple 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.seewo.brick.app.component.list.simple.page.GridListPage 6 | import com.seewo.brick.app.component.list.simple.page.HorizontalListPage 7 | import com.seewo.brick.app.component.list.simple.page.ScrollViewPage 8 | import com.seewo.brick.app.component.list.simple.page.VerticalListPage 9 | import com.seewo.brick.app.widget.multiTabViewPager 10 | import com.seewo.brick.ktx.MATCH_PARENT 11 | import com.seewo.brick.ktx.frameLayout 12 | import com.seewo.brick.ktx.setStatusBarTransparent 13 | 14 | class SimpleListActivity : AppCompatActivity() { 15 | 16 | override fun onCreate(savedInstanceState: Bundle?) { 17 | super.onCreate(savedInstanceState) 18 | setStatusBarTransparent(true) 19 | setContentView(multiTabViewPager( 20 | data = listOf( 21 | "纵向列表", 22 | "横向列表", 23 | "方阵列表", 24 | "页面滚动", 25 | ), 26 | viewPagerBuilder = { _, index -> 27 | when (index) { 28 | 0 -> VerticalListPage() 29 | 1 -> HorizontalListPage() 30 | 2 -> GridListPage() 31 | 3 -> ScrollViewPage() 32 | else -> frameLayout( 33 | MATCH_PARENT, MATCH_PARENT, 34 | ) 35 | } 36 | } 37 | )) 38 | } 39 | } -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/component/list/simple/page/GridListPage.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.component.list.simple.page 2 | 3 | import android.content.Context 4 | import android.graphics.Color 5 | import android.util.AttributeSet 6 | import android.view.Gravity 7 | import android.widget.LinearLayout 8 | import androidx.recyclerview.widget.GridLayoutManager 9 | import com.seewo.brick.BrickPreview 10 | import com.seewo.brick.app.R 11 | import com.seewo.brick.app.widget.Markdown 12 | import com.seewo.brick.ktx.* 13 | import com.seewo.brick.params.EdgeInsets 14 | 15 | private class GridListPage(context: Context, attrs: AttributeSet? = null) : 16 | BrickPreview(context, attrs) { 17 | 18 | override fun preview(context: Context) { 19 | view { 20 | context.GridListPage() 21 | } 22 | } 23 | } 24 | 25 | fun Context.GridListPage() = column( 26 | MATCH_PARENT, MATCH_PARENT, 27 | ) { 28 | SimpleList() 29 | ShowMarkDown() 30 | } 31 | 32 | private fun LinearLayout.SimpleList() { 33 | simpleStatelessRecyclerView( 34 | MATCH_PARENT, WRAP_CONTENT, 35 | // 列表数据 36 | data = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), 37 | // 设置LayoutManager,每行4列 38 | layoutManager = GridLayoutManager(context, 4), 39 | padding = EdgeInsets.symmetric(vertical = 8.dp, horizontal = 16.dp) 40 | ) { data, index -> 41 | // 构造每一项的控件,可以根据不同的item构建不同的控件 42 | val item = data[index] 43 | textView( 44 | MATCH_PARENT, 48.dp, 45 | text = "$item", 46 | // 单数为主题色,双数为黑色 47 | textColor = if (item % 2 == 0) Color.BLACK else R.color.primary.color, 48 | textSize = 14.dp, 49 | gravity = Gravity.CENTER, 50 | ) 51 | } 52 | } 53 | 54 | private fun LinearLayout.ShowMarkDown() { 55 | expand { 56 | Markdown( 57 | """ 58 | ## 代码展示 59 | 60 | 无状态简单列表,静态设置的简单列表,data为固定列表,不可修改 61 | 62 | ```kotlin 63 | private fun LinearLayout.simpleList() { 64 | simpleStatelessRecyclerView( 65 | MATCH_PARENT, WRAP_CONTENT, 66 | // 列表数据 67 | data = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11), 68 | // 设置LayoutManager,每行4列 69 | layoutManager = GridLayoutManager(context, 4), 70 | padding = EdgeInsets.symmetric(vertical = 8.dp, horizontal = 16.dp) 71 | ) { data, index -> 72 | // 构造每一项的控件,可以根据不同的item构建不同的控件 73 | val item = data[index] 74 | textView( 75 | MATCH_PARENT, 48.dp, 76 | text = "${'$'}item", 77 | // 单数为主题色,双数为黑色 78 | textColor = if (item % 2 == 0) Color.BLACK else R.color.primary.color, 79 | textSize = 14.dp, 80 | gravity = Gravity.CENTER, 81 | ) 82 | } 83 | } 84 | ``` 85 | """.trimIndent() 86 | ) 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/component/list/simple/page/HorizontalListPage.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.component.list.simple.page 2 | 3 | import android.content.Context 4 | import android.graphics.Color 5 | import android.util.AttributeSet 6 | import android.view.Gravity 7 | import android.widget.LinearLayout 8 | import androidx.recyclerview.widget.LinearLayoutManager 9 | import com.seewo.brick.BrickPreview 10 | import com.seewo.brick.app.R 11 | import com.seewo.brick.app.widget.Markdown 12 | import com.seewo.brick.ktx.* 13 | import com.seewo.brick.params.EdgeInsets 14 | 15 | private class HorizontalListPage(context: Context, attrs: AttributeSet? = null) : 16 | BrickPreview(context, attrs) { 17 | 18 | override fun preview(context: Context) { 19 | view { 20 | context.HorizontalListPage() 21 | } 22 | } 23 | } 24 | 25 | fun Context.HorizontalListPage() = column( 26 | MATCH_PARENT, MATCH_PARENT, 27 | ) { 28 | SimpleList() 29 | ShowMarkDown() 30 | } 31 | 32 | private fun LinearLayout.SimpleList() { 33 | simpleStatelessRecyclerView( 34 | MATCH_PARENT, WRAP_CONTENT, 35 | // 列表数据 36 | data = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9), 37 | // 设置分割线 38 | itemDecoration = dividerDecoration( 39 | color = R.color.primary.color, 40 | orientation = LinearLayoutManager.HORIZONTAL, 41 | ), 42 | // 设置横向LayoutManager 43 | layoutManager = LinearLayoutManager(context).apply { 44 | orientation = LinearLayoutManager.HORIZONTAL 45 | }, 46 | // 注意:由于默认ViewHolder不适合布局横向列表,这里需要自定义一个宽高结尾WRAP_CONTENT的帧布局 47 | viewHolderCreator = { 48 | frameLayout() 49 | }, 50 | padding = EdgeInsets.symmetric(vertical = 8.dp, horizontal = 16.dp) 51 | ) { data, index -> 52 | // 构造每一项的控件,可以根据不同的item构建不同的控件 53 | val item = data[index] 54 | textView( 55 | 48.dp, 32.dp, 56 | text = "$item", 57 | // 单数为主题色,双数为黑色 58 | textColor = if (item % 2 == 0) Color.BLACK else R.color.primary.color, 59 | textSize = 14.dp, 60 | gravity = Gravity.CENTER, 61 | ) 62 | } 63 | } 64 | 65 | private fun LinearLayout.ShowMarkDown() { 66 | expand { 67 | Markdown( 68 | """ 69 | ## 代码展示 70 | 71 | 无状态简单列表,静态设置的简单列表,data为固定列表,不可修改 72 | 73 | ```kotlin 74 | private fun LinearLayout.simpleList() { 75 | simpleStatelessRecyclerView( 76 | MATCH_PARENT, WRAP_CONTENT, 77 | // 列表数据 78 | data = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9), 79 | // 设置分割线 80 | itemDecoration = dividerDecoration( 81 | color = R.color.primary.color, 82 | orientation = LinearLayoutManager.HORIZONTAL, 83 | ), 84 | // 设置横向LayoutManager 85 | layoutManager = LinearLayoutManager(context).apply { 86 | orientation = LinearLayoutManager.HORIZONTAL 87 | }, 88 | // 注意:由于默认ViewHolder不适合布局横向列表,这里需要自定义一个宽高结尾WRAP_CONTENT的帧布局 89 | viewHolderCreator = { 90 | frameLayout() 91 | }, 92 | padding = EdgeInsets.symmetric(vertical = 8.dp, horizontal = 16.dp) 93 | ) { data, index -> 94 | // 构造每一项的控件,可以根据不同的item构建不同的控件 95 | val item = data[index] 96 | textView( 97 | 48.dp, 32.dp, 98 | text = "${'$'}item", 99 | // 单数为主题色,双数为黑色 100 | textColor = if (item % 2 == 0) Color.BLACK else R.color.primary.color, 101 | textSize = 14.dp, 102 | gravity = Gravity.CENTER, 103 | ) 104 | } 105 | } 106 | ``` 107 | """.trimIndent() 108 | ) 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/component/list/simple/page/ScrollViewPage.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.component.list.simple.page 2 | 3 | import android.content.Context 4 | import android.graphics.Color 5 | import android.util.AttributeSet 6 | import android.view.Gravity 7 | import android.widget.LinearLayout 8 | import com.seewo.brick.BrickPreview 9 | import com.seewo.brick.app.R 10 | import com.seewo.brick.app.widget.Markdown 11 | import com.seewo.brick.ktx.* 12 | import com.seewo.brick.params.EdgeInsets 13 | 14 | private class ScrollViewPage(context: Context, attrs: AttributeSet? = null) : 15 | BrickPreview(context, attrs) { 16 | 17 | override fun preview(context: Context) { 18 | view { 19 | context.ScrollViewPage() 20 | } 21 | } 22 | } 23 | 24 | fun Context.ScrollViewPage() = column( 25 | MATCH_PARENT, MATCH_PARENT, 26 | ) { 27 | SimpleList() 28 | ShowMarkDown() 29 | } 30 | 31 | private fun LinearLayout.SimpleList() { 32 | scrollView( 33 | MATCH_PARENT, 100.dp, 34 | ) { 35 | column( 36 | MATCH_PARENT 37 | ) { 38 | repeat(50) { 39 | if (it != 0) { 40 | layoutParams( 41 | margins = EdgeInsets.symmetric(horizontal = 16.dp) 42 | ) { 43 | divider( 44 | background = R.color.primary.colorDrawable, 45 | ) 46 | } 47 | } 48 | textView( 49 | MATCH_PARENT, 32.dp, 50 | text = "$it", 51 | // 单数为主题色,双数为黑色 52 | textColor = if (it % 2 == 0) Color.BLACK else R.color.primary.color, 53 | textSize = 14.dp, 54 | gravity = Gravity.CENTER, 55 | ) 56 | } 57 | } 58 | } 59 | } 60 | 61 | private fun LinearLayout.ShowMarkDown() { 62 | expand { 63 | Markdown( 64 | """ 65 | ## 代码展示 66 | 67 | 通过ScrollView实现页面可滚动 68 | 69 | ```kotlin 70 | private fun LinearLayout.simpleList() { 71 | scrollView( 72 | MATCH_PARENT, 100.dp, 73 | ) { 74 | column( 75 | MATCH_PARENT 76 | ) { 77 | repeat(50) { 78 | if (it != 0) { 79 | layoutParams( 80 | margins = EdgeInsets.symmetric(horizontal = 16.dp) 81 | ) { 82 | divider( 83 | background = R.color.primary.colorDrawable, 84 | ) 85 | } 86 | } 87 | textView( 88 | MATCH_PARENT, 32.dp, 89 | text = "${'$'}it", 90 | // 单数为主题色,双数为黑色 91 | textColor = if (it % 2 == 0) Color.BLACK else R.color.primary.color, 92 | textSize = 14.dp, 93 | gravity = Gravity.CENTER, 94 | ) 95 | } 96 | } 97 | } 98 | } 99 | ``` 100 | """.trimIndent() 101 | ) 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/component/list/simple/page/VerticalListPage.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.component.list.simple.page 2 | 3 | import android.content.Context 4 | import android.graphics.Color 5 | import android.util.AttributeSet 6 | import android.view.Gravity 7 | import android.widget.LinearLayout 8 | import com.seewo.brick.BrickPreview 9 | import com.seewo.brick.app.R 10 | import com.seewo.brick.app.widget.Markdown 11 | import com.seewo.brick.ktx.* 12 | import com.seewo.brick.params.EdgeInsets 13 | 14 | private class VerticalListPage(context: Context, attrs: AttributeSet? = null) : 15 | BrickPreview(context, attrs) { 16 | 17 | override fun preview(context: Context) { 18 | view { 19 | context.VerticalListPage() 20 | } 21 | } 22 | } 23 | 24 | fun Context.VerticalListPage() = column( 25 | MATCH_PARENT, MATCH_PARENT, 26 | ) { 27 | SimpleList() 28 | ShowMarkDown() 29 | } 30 | 31 | private fun LinearLayout.SimpleList() { 32 | simpleStatelessRecyclerView( 33 | MATCH_PARENT, 100.dp, 34 | // 列表数据 35 | data = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9), 36 | // 设置分割线 37 | itemDecoration = dividerDecoration( 38 | color = R.color.primary.color, 39 | padding = EdgeInsets.only(bottom = 8.dp, start = 16.dp, end = 16.dp) 40 | ), 41 | ) { data, index -> 42 | // 构造每一项的控件,可以根据不同的item构建不同的控件 43 | val item = data[index] 44 | textView( 45 | MATCH_PARENT, 32.dp, 46 | text = "$item", 47 | // 单数为主题色,双数为黑色 48 | textColor = if (item % 2 == 0) Color.BLACK else R.color.primary.color, 49 | textSize = 14.dp, 50 | gravity = Gravity.CENTER, 51 | ) 52 | } 53 | } 54 | 55 | private fun LinearLayout.ShowMarkDown() { 56 | expand { 57 | Markdown( 58 | """ 59 | ## 代码展示 60 | 61 | 无状态简单列表,静态设置的简单列表,data为固定列表,不可修改 62 | 63 | ```kotlin 64 | private fun LinearLayout.simpleList() { 65 | simpleStatelessRecyclerView( 66 | MATCH_PARENT, 100.dp, 67 | // 列表数据 68 | data = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9), 69 | // 设置分割线 70 | itemDecoration = dividerDecoration( 71 | color = R.color.primary.color, 72 | padding = EdgeInsets.only(bottom = 8.dp, start = 16.dp, end = 16.dp) 73 | ), 74 | ) { data, index -> 75 | // 构造每一项的控件,可以根据不同的item构建不同的控件 76 | val item = data[index] 77 | textView( 78 | MATCH_PARENT, 32.dp, 79 | text = "${'$'}item", 80 | // 单数为主题色,双数为黑色 81 | textColor = if (item % 2 == 0) Color.BLACK else R.color.primary.color, 82 | textSize = 14.dp, 83 | gravity = Gravity.CENTER, 84 | ) 85 | } 86 | } 87 | ``` 88 | """.trimIndent() 89 | ) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/component/pager/PagerActivity.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.component.pager 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.seewo.brick.app.component.pager.page.FragmentPagerPage 6 | import com.seewo.brick.app.component.pager.page.LoopViewPagerPage 7 | import com.seewo.brick.app.component.pager.page.TabLayoutViewPagerPage 8 | import com.seewo.brick.app.component.pager.page.ViewPagerPage 9 | import com.seewo.brick.app.widget.multiTabViewPager 10 | import com.seewo.brick.ktx.MATCH_PARENT 11 | import com.seewo.brick.ktx.frameLayout 12 | import com.seewo.brick.ktx.setStatusBarTransparent 13 | 14 | class PagerActivity : AppCompatActivity() { 15 | 16 | override fun onCreate(savedInstanceState: Bundle?) { 17 | super.onCreate(savedInstanceState) 18 | setStatusBarTransparent(true) 19 | setContentView(multiTabViewPager( 20 | data = listOf( 21 | "轮播图", 22 | "TabLayout分页切换", 23 | "分页切换", 24 | "Fragment分页切换", 25 | ), 26 | viewPagerBuilder = { _, index -> 27 | when (index) { 28 | 0 -> LoopViewPagerPage() 29 | 1 -> TabLayoutViewPagerPage() 30 | 2 -> ViewPagerPage() 31 | 3 -> FragmentPagerPage() 32 | else -> frameLayout( 33 | MATCH_PARENT, MATCH_PARENT, 34 | ) 35 | } 36 | } 37 | )) 38 | } 39 | } -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/component/pager/page/LoopViewPagerPage.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.component.pager.page 2 | 3 | 4 | import android.content.Context 5 | import android.util.AttributeSet 6 | import android.util.Log 7 | import android.view.Gravity 8 | import android.widget.ImageView 9 | import android.widget.LinearLayout 10 | import com.seewo.brick.BrickPreview 11 | import com.seewo.brick.app.R 12 | import com.seewo.brick.app.widget.Markdown 13 | import com.seewo.brick.ktx.MATCH_PARENT 14 | import com.seewo.brick.ktx.column 15 | import com.seewo.brick.ktx.dp 16 | import com.seewo.brick.ktx.drawable 17 | import com.seewo.brick.ktx.expand 18 | import com.seewo.brick.ktx.frameLayout 19 | import com.seewo.brick.ktx.imageView 20 | import com.seewo.brick.ktx.indicator 21 | import com.seewo.brick.ktx.layoutParams 22 | import com.seewo.brick.ktx.loopPager 23 | import com.seewo.brick.ktx.view 24 | import kotlin.time.Duration.Companion.seconds 25 | 26 | private class LoopViewPagerPage(context: Context, attrs: AttributeSet? = null) : 27 | BrickPreview(context, attrs) { 28 | 29 | override fun preview(context: Context) { 30 | view { 31 | context.LoopViewPagerPage() 32 | } 33 | } 34 | } 35 | 36 | fun Context.LoopViewPagerPage() = column( 37 | MATCH_PARENT, MATCH_PARENT, 38 | ) { 39 | LoopViewPager() 40 | ShowMarkDown() 41 | } 42 | 43 | private fun LinearLayout.LoopViewPager() { 44 | frameLayout( 45 | MATCH_PARENT, 200.dp, 46 | ) { 47 | val viewPager = loopPager( 48 | MATCH_PARENT, MATCH_PARENT, 49 | data = listOf( 50 | R.drawable.page1, 51 | R.drawable.page2, 52 | R.drawable.page3, 53 | ), 54 | duration = 1.seconds, 55 | scrollDuration = 300, 56 | onPageSelected = { 57 | Log.i("BrickUI", "onPageSelected: $it") 58 | } 59 | ) { data, position -> 60 | imageView( 61 | MATCH_PARENT, MATCH_PARENT, 62 | scaleType = ImageView.ScaleType.CENTER_CROP, 63 | drawable = data[position].drawable, 64 | ) 65 | } 66 | layoutParams(gravity = Gravity.CENTER_HORIZONTAL or Gravity.BOTTOM) { 67 | indicator( 68 | MATCH_PARENT, 48.dp, 69 | viewPager, 70 | ) 71 | } 72 | } 73 | } 74 | 75 | private fun LinearLayout.ShowMarkDown() { 76 | expand { 77 | Markdown( 78 | """ 79 | ## 代码展示 80 | 81 | 轮播图以1秒间隔翻页 82 | 83 | ```kotlin 84 | private fun LinearLayout.LoopViewPager() { 85 | frameLayout( 86 | MATCH_PARENT, 200.dp, 87 | ) { 88 | val viewPager = loopPager( 89 | MATCH_PARENT, MATCH_PARENT, 90 | data = listOf( 91 | R.drawable.page1, 92 | R.drawable.page2, 93 | R.drawable.page3, 94 | ), 95 | duration = 1.seconds, 96 | onPageSelected = { 97 | Log.i("BrickUI", "onPageSelected: ${'$'}it") 98 | } 99 | ) { data, position -> 100 | imageView( 101 | MATCH_PARENT, MATCH_PARENT, 102 | scaleType = ImageView.ScaleType.CENTER_CROP, 103 | drawable = data[position].drawable, 104 | ) 105 | } 106 | layoutParams(gravity = Gravity.CENTER_HORIZONTAL or Gravity.BOTTOM) { 107 | indicator( 108 | MATCH_PARENT, 48.dp, 109 | viewPager, 110 | ) 111 | } 112 | } 113 | } 114 | ``` 115 | """.trimIndent() 116 | ) 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/extra/ExtraFragment.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.extra 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import com.hjq.toast.ToastUtils 6 | import com.seewo.brick.BrickPreview 7 | import com.seewo.brick.app.R 8 | import com.seewo.brick.app.extra.about.AboutActivity 9 | import com.seewo.brick.app.extra.counter.CounterActivity 10 | import com.seewo.brick.app.extra.list.LongListActivity 11 | import com.seewo.brick.app.main.MainItemBean 12 | import com.seewo.brick.app.main.mainFragmentList 13 | import com.seewo.brick.ktx.* 14 | 15 | class PreviewExtraFragment(context: Context, attrs: AttributeSet? = null) : 16 | BrickPreview(context, attrs) { 17 | 18 | override fun preview(context: Context) { 19 | view { 20 | context.ExtraPage() 21 | } 22 | } 23 | } 24 | 25 | fun Context.ExtraPage() = mainFragmentList( 26 | listOf( 27 | MainItemBean("计数器", R.drawable.btn_add_food.drawable) { 28 | startActivity() 29 | }, 30 | MainItemBean("长列表体验", R.drawable.ic_widget_picker_view.drawable) { 31 | startActivity() 32 | }, 33 | MainItemBean("To-Do", R.drawable.ic_checked_right.drawable) { 34 | ToastUtils.show("有空再搞") 35 | }, 36 | MainItemBean("关于", R.mipmap.ic_launcher.drawable?.clipRect(8.dp)) { 37 | startActivity() 38 | }, 39 | ) 40 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/extra/about/AboutActivity.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.extra.about 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.seewo.brick.ktx.setStatusBarTransparent 6 | 7 | class AboutActivity : AppCompatActivity() { 8 | 9 | override fun onCreate(savedInstanceState: Bundle?) { 10 | super.onCreate(savedInstanceState) 11 | setStatusBarTransparent(true) 12 | setContentView(AboutPage()) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/extra/about/AboutPage.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.extra.about 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.graphics.Color 6 | import android.graphics.Typeface 7 | import android.net.Uri 8 | import android.text.method.LinkMovementMethod 9 | import android.util.AttributeSet 10 | import android.view.Gravity 11 | import android.view.ViewGroup 12 | import android.widget.LinearLayout 13 | import androidx.core.text.buildSpannedString 14 | import com.seewo.brick.BrickPreview 15 | import com.seewo.brick.app.R 16 | import com.seewo.brick.app.widget.TopBar 17 | import com.seewo.brick.ktx.* 18 | import com.seewo.brick.params.EdgeInsets 19 | 20 | class AboutPage(context: Context, attrs: AttributeSet): BrickPreview(context, attrs) { 21 | override fun preview(context: Context) { 22 | view { 23 | context.AboutPage() 24 | } 25 | } 26 | } 27 | 28 | fun Context.AboutPage() = column( 29 | MATCH_PARENT, MATCH_PARENT, 30 | gravity = Gravity.CENTER_HORIZONTAL, 31 | fitsSystemWindows = true, 32 | ) { 33 | TopBar() 34 | LOGO() 35 | Title() 36 | TextBody() 37 | Links() 38 | } 39 | 40 | private fun ViewGroup.Links() { 41 | row( 42 | padding = EdgeInsets.only(bottom = 32.dp) 43 | ) { 44 | textView( 45 | text = buildSpannedString { 46 | appendClickable( 47 | "BrickUI@github", 48 | isUnderlineText = false, 49 | ) { 50 | context.startActivity(Intent(Intent.ACTION_VIEW).apply { 51 | data = Uri.parse("https://github.com/robin8yeung/BrickUI") 52 | }) 53 | } 54 | }, 55 | textSize = 14.dp, 56 | padding = EdgeInsets.only(end = 8.dp), 57 | movementMethod = LinkMovementMethod(), 58 | highLightColor = Color.TRANSPARENT, 59 | ) 60 | divider( 61 | 1.dp, 16.dp, 62 | background = R.color.grey_e4.colorDrawable, 63 | ) 64 | textView( 65 | text = buildSpannedString { 66 | appendClickable( 67 | "BrickUI@gitlab(内部)", 68 | isUnderlineText = false, 69 | ) { 70 | context.startActivity(Intent(Intent.ACTION_VIEW).apply { 71 | data = Uri.parse("https://gitlab.gz.cvte.cn/seewocbb/BrickUI") 72 | }) 73 | } 74 | }, 75 | textSize = 14.dp, 76 | padding = EdgeInsets.only(start = 8.dp), 77 | movementMethod = LinkMovementMethod(), 78 | highLightColor = Color.TRANSPARENT, 79 | ) 80 | } 81 | } 82 | 83 | private fun LinearLayout.Title() { 84 | textView( 85 | text = "BrickUI", 86 | textSize = 24.dp, 87 | textColor = R.color.primary.color, 88 | padding = EdgeInsets.only(bottom = 48.dp), 89 | textStyle = Typeface.BOLD, 90 | ) 91 | } 92 | 93 | private fun LinearLayout.TextBody() { 94 | expand { 95 | textView( 96 | MATCH_PARENT, MATCH_PARENT, 97 | text = """ 98 | 受Jetpack Compose启发,通过组合和声明的方式去搭建UI,就像用砖头垒出来的一样自然。 99 | 100 | BrickUI是一套Kotlin实现的,基于原生View体系的声明式UI框架。 101 | 与原生View体系无缝对接,从此代码徒手撸layout,忘记你的xml吧~ 102 | """.trimIndent(), 103 | textSize = 16.dp, 104 | padding = EdgeInsets.only(bottom = 16.dp, start = 32.dp, end = 32.dp), 105 | textColor = Color.GRAY, 106 | ) 107 | } 108 | } 109 | 110 | private fun LinearLayout.LOGO() { 111 | layoutParams(margins = EdgeInsets.only(top = 32.dp, bottom = 16.dp)) { 112 | roundRectClip( 113 | radius = 8.dp 114 | ) { 115 | imageView( 116 | 64.dp, 64.dp, 117 | drawable = R.mipmap.ic_launcher.drawable, 118 | ) 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/extra/counter/CounterActivity.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.extra.counter 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.seewo.brick.ktx.setStatusBarTransparent 6 | 7 | class CounterActivity : AppCompatActivity() { 8 | 9 | override fun onCreate(savedInstanceState: Bundle?) { 10 | super.onCreate(savedInstanceState) 11 | setStatusBarTransparent(true) 12 | setContentView(CounterPage()) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/extra/counter/CounterPage.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.extra.counter 2 | 3 | import android.content.Context 4 | import android.graphics.Color 5 | import android.graphics.Typeface 6 | import android.graphics.drawable.ColorDrawable 7 | import android.util.AttributeSet 8 | import android.view.Gravity 9 | import android.view.View 10 | import android.view.ViewGroup 11 | import android.widget.LinearLayout 12 | import com.seewo.brick.BrickPreview 13 | import com.seewo.brick.app.R 14 | import com.seewo.brick.app.widget.Markdown 15 | import com.seewo.brick.app.widget.TopBar 16 | import com.seewo.brick.ktx.* 17 | import com.seewo.brick.params.EdgeInsets 18 | import com.seewo.brick.params.Shadow 19 | 20 | 21 | class CounterPage(context: Context, attrs: AttributeSet?) : BrickPreview(context, attrs) { 22 | override fun preview(context: Context) { 23 | view { 24 | context.CounterPage() 25 | } 26 | } 27 | } 28 | 29 | fun Context.CounterPage() = column( 30 | MATCH_PARENT, MATCH_PARENT, 31 | fitsSystemWindows = true, 32 | ) { 33 | // 通过上下文获取ViewModel,这样可以保证在任何嵌套下均能获取到Activity的ViewModel 34 | val viewModel: CounterPageViewModel? = context.activityViewModelOrNull() 35 | 36 | TopBar() 37 | divider(background = ColorDrawable(Color.GRAY)) 38 | row( 39 | MATCH_PARENT, 160.dp, 40 | gravity = Gravity.CENTER, 41 | fitsSystemWindows = true, 42 | ) { 43 | button("-") { 44 | viewModel?.minus() 45 | } 46 | liveText( 47 | 84.dp, 48 | style = R.style.BigNumber, 49 | text = viewModel?.count?.map { it.toString() } ?: "0".static, // 为了在预览模式能看到0的效果 50 | textColor = viewModel?.count?.map { if (it % 2 == 0) Color.RED else Color.BLACK }, 51 | padding = EdgeInsets.all(12.dp), 52 | ) 53 | button("+") { 54 | viewModel?.plus() 55 | } 56 | } 57 | ShowMarkDown() 58 | } 59 | 60 | private fun ViewGroup.button( 61 | text: String, 62 | onClick: View.OnClickListener 63 | ) = shadowBox( 64 | radius = 14.dp, shadow = Shadow(blur = 8.dp), 65 | onClick = onClick 66 | ) { 67 | textView( 68 | width = 100.dp, height = 100.dp, 69 | text = text, 70 | textSize = 28.dp, 71 | textStyle = Typeface.BOLD, 72 | gravity = Gravity.CENTER 73 | ) 74 | } 75 | 76 | 77 | private fun LinearLayout.ShowMarkDown() { 78 | expand { 79 | Markdown( 80 | """ 81 | ## 最佳实践 82 | 83 | ### 架构 84 | 85 | 与Flutter的默认demo类似,这里给到一个简单的计数器demo,用于阐释一个带有具体业务的例子。 86 | BrickUI作为基于View体系的一套框架,对标的实际更多是DataBinding,所以最佳实践仍然是采用MVVM架构。 87 | 88 | ### 数据绑定 89 | 90 | 相比DataBind,我们不需要再在xml里面写逻辑,而且brick-ui-live提供了比DataBinding更纯粹而有效的双向绑定,可以参考其中liveEdit、liveCheckBox、liveSeekBar等的实现 91 | 92 | ### 代码展示 93 | 篇幅有限,这里就不展示代码了,请到demo源码去看吧 94 | """.trimIndent() 95 | ) 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/extra/counter/CounterPageViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.extra.counter 2 | 3 | import android.app.Application 4 | import androidx.lifecycle.AndroidViewModel 5 | import androidx.lifecycle.LiveData 6 | import com.seewo.brick.ktx.data 7 | import com.seewo.brick.ktx.live 8 | 9 | class CounterPageViewModel(application: Application): AndroidViewModel(application) { 10 | val count: LiveData = 0.live 11 | 12 | fun plus() { 13 | count.data = count.data + 1 14 | } 15 | 16 | fun minus() { 17 | count.data = count.data - 1 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/extra/list/LongListActivity.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.extra.list 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.seewo.brick.ktx.setStatusBarTransparent 6 | 7 | class LongListActivity : AppCompatActivity() { 8 | 9 | override fun onCreate(savedInstanceState: Bundle?) { 10 | super.onCreate(savedInstanceState) 11 | setStatusBarTransparent(true) 12 | setContentView(LongListPage()) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/helper/HelperFragment.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.helper 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import com.seewo.brick.BrickPreview 6 | import com.seewo.brick.app.R 7 | import com.seewo.brick.app.helper.animator.AnimatorHelperActivity 8 | import com.seewo.brick.app.helper.clip.ClipAndShadowHelperActivity 9 | import com.seewo.brick.app.helper.color.ColorAndDrawableHelperActivity 10 | import com.seewo.brick.app.helper.spannable.SpannableHelperActivity 11 | import com.seewo.brick.app.main.MainItemBean 12 | import com.seewo.brick.app.main.mainFragmentList 13 | import com.seewo.brick.ktx.drawable 14 | import com.seewo.brick.ktx.startActivity 15 | import com.seewo.brick.ktx.view 16 | 17 | class PreviewHelperFragment(context: Context, attrs: AttributeSet? = null) : 18 | BrickPreview(context, attrs) { 19 | 20 | override fun preview(context: Context) { 21 | view { 22 | context.HelperPage() 23 | } 24 | } 25 | } 26 | 27 | fun Context.HelperPage() = mainFragmentList( 28 | listOf( 29 | MainItemBean("裁剪与阴影", R.drawable.ic_util_drawable.drawable) { 30 | startActivity() 31 | }, 32 | MainItemBean("颜色与Drawable", R.drawable.ic_util_color.drawable) { 33 | startActivity() 34 | }, 35 | MainItemBean("富文本", R.drawable.ic_widget_dialog.drawable) { 36 | startActivity() 37 | }, 38 | MainItemBean("动画", R.drawable.ic_widget_loading.drawable) { 39 | startActivity() 40 | }, 41 | ) 42 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/helper/animator/AnimatorHelperActivity.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.helper.animator 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.seewo.brick.app.helper.animator.page.AnimatorPage 6 | import com.seewo.brick.app.widget.multiTabViewPager 7 | import com.seewo.brick.ktx.MATCH_PARENT 8 | import com.seewo.brick.ktx.frameLayout 9 | import com.seewo.brick.ktx.setStatusBarTransparent 10 | 11 | class AnimatorHelperActivity : AppCompatActivity() { 12 | 13 | override fun onCreate(savedInstanceState: Bundle?) { 14 | super.onCreate(savedInstanceState) 15 | setStatusBarTransparent(true) 16 | setContentView(multiTabViewPager( 17 | data = listOf( 18 | "动画", 19 | ), 20 | viewPagerBuilder = { _, index -> 21 | when (index) { 22 | 0 -> AnimatorPage() 23 | 24 | else -> frameLayout( 25 | MATCH_PARENT, MATCH_PARENT, 26 | ) 27 | } 28 | } 29 | )) 30 | } 31 | } -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/helper/clip/ClipAndShadowHelperActivity.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.helper.clip 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.seewo.brick.app.helper.clip.page.ClipPage 6 | import com.seewo.brick.app.helper.clip.page.ShadowPage 7 | import com.seewo.brick.app.widget.multiTabViewPager 8 | import com.seewo.brick.ktx.MATCH_PARENT 9 | import com.seewo.brick.ktx.frameLayout 10 | import com.seewo.brick.ktx.setStatusBarTransparent 11 | 12 | class ClipAndShadowHelperActivity : AppCompatActivity() { 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setStatusBarTransparent(true) 17 | setContentView(multiTabViewPager( 18 | data = listOf( 19 | "阴影", 20 | "裁剪", 21 | ), 22 | viewPagerBuilder = { _, index -> 23 | when (index) { 24 | 0 -> ShadowPage() 25 | 1 -> ClipPage() 26 | 27 | else -> frameLayout( 28 | MATCH_PARENT, MATCH_PARENT, 29 | ) 30 | } 31 | } 32 | )) 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/helper/color/ColorAndDrawableHelperActivity.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.helper.color 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.seewo.brick.app.helper.color.page.ColorPage 6 | import com.seewo.brick.app.helper.color.page.DrawablePage 7 | import com.seewo.brick.app.widget.multiTabViewPager 8 | import com.seewo.brick.ktx.MATCH_PARENT 9 | import com.seewo.brick.ktx.frameLayout 10 | import com.seewo.brick.ktx.setStatusBarTransparent 11 | 12 | class ColorAndDrawableHelperActivity : AppCompatActivity() { 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setStatusBarTransparent(true) 17 | setContentView(multiTabViewPager( 18 | data = listOf( 19 | "颜色", 20 | "Drawable", 21 | ), 22 | viewPagerBuilder = { _, index -> 23 | when (index) { 24 | 0 -> ColorPage() 25 | 1 -> DrawablePage() 26 | 27 | else -> frameLayout( 28 | MATCH_PARENT, MATCH_PARENT, 29 | ) 30 | } 31 | } 32 | )) 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/helper/spannable/SpannableHelperActivity.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.helper.spannable 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.seewo.brick.app.helper.spannable.page.SpannablePage 6 | import com.seewo.brick.app.widget.multiTabViewPager 7 | import com.seewo.brick.ktx.MATCH_PARENT 8 | import com.seewo.brick.ktx.frameLayout 9 | import com.seewo.brick.ktx.setStatusBarTransparent 10 | 11 | class SpannableHelperActivity : AppCompatActivity() { 12 | 13 | override fun onCreate(savedInstanceState: Bundle?) { 14 | super.onCreate(savedInstanceState) 15 | setStatusBarTransparent(true) 16 | setContentView(multiTabViewPager( 17 | data = listOf( 18 | "富文本", 19 | ), 20 | viewPagerBuilder = { _, index -> 21 | when (index) { 22 | 0 -> SpannablePage() 23 | 24 | else -> frameLayout( 25 | MATCH_PARENT, MATCH_PARENT, 26 | ) 27 | } 28 | } 29 | )) 30 | } 31 | } -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/main/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.main 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.seewo.brick.ktx.setStatusBarTransparent 6 | 7 | class MainActivity : AppCompatActivity() { 8 | override fun onCreate(savedInstanceState: Bundle?) { 9 | super.onCreate(savedInstanceState) 10 | setStatusBarTransparent(true) 11 | setContentView(mainPage()) 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/main/MainFragmentList.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.main 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.view.ViewGroup 6 | import androidx.recyclerview.widget.GridLayoutManager 7 | import androidx.recyclerview.widget.RecyclerView 8 | import com.seewo.brick.BrickPreview 9 | import com.seewo.brick.app.R 10 | import com.seewo.brick.ktx.MATCH_PARENT 11 | import com.seewo.brick.ktx.drawable 12 | import com.seewo.brick.ktx.simpleStatelessRecyclerView 13 | 14 | class MainFragmentList(context: Context, attrs: AttributeSet): BrickPreview(context, attrs) { 15 | override fun preview(context: Context) { 16 | mainFragmentList(listOf( 17 | MainItemBean("计数器", R.drawable.btn_add_food.drawable), 18 | MainItemBean("To-Do", R.drawable.ic_checked_right.drawable), 19 | MainItemBean("关于", R.mipmap.ic_launcher.drawable), 20 | )) 21 | } 22 | } 23 | 24 | fun Context.mainFragmentList( 25 | items: List 26 | ) = simpleStatelessRecyclerView( 27 | MATCH_PARENT, MATCH_PARENT, 28 | data = items, 29 | layoutManager = GridLayoutManager(this, 3), 30 | overScrollMode = RecyclerView.OVER_SCROLL_NEVER, 31 | ) { data, i -> 32 | MainItemWidget( 33 | text = data[i].text, 34 | drawable = data[i].drawable, 35 | onClick = data[i].onClick, 36 | ) 37 | } 38 | 39 | fun ViewGroup.mainFragmentList( 40 | items: List 41 | ) = context.mainFragmentList(items).also { addView(it) } -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/main/MainItemBean.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.main 2 | 3 | import android.content.Context 4 | import android.graphics.Color 5 | import android.graphics.drawable.Drawable 6 | import android.text.TextUtils 7 | import android.util.AttributeSet 8 | import android.view.Gravity 9 | import android.view.View.OnClickListener 10 | import android.view.ViewGroup 11 | import com.seewo.brick.BrickPreview 12 | import com.seewo.brick.app.R 13 | import com.seewo.brick.ktx.MATCH_PARENT 14 | import com.seewo.brick.ktx.column 15 | import com.seewo.brick.ktx.dp 16 | import com.seewo.brick.ktx.drawable 17 | import com.seewo.brick.ktx.imageView 18 | import com.seewo.brick.ktx.rectDrawable 19 | import com.seewo.brick.ktx.stateListDrawable 20 | import com.seewo.brick.ktx.textView 21 | import com.seewo.brick.params.EdgeInsets 22 | 23 | class PreviewMainItem(context: Context, attrs: AttributeSet? = null): BrickPreview(context, attrs) { 24 | 25 | override fun preview(context: Context) { 26 | MainItemWidget( 27 | "Hello Brick", 28 | R.mipmap.ic_launcher.drawable, 29 | ) 30 | } 31 | } 32 | 33 | class MainItemBean( 34 | val text: String, 35 | val drawable: Drawable? = null, 36 | val onClick: OnClickListener? = null, 37 | ) 38 | 39 | fun ViewGroup.MainItemWidget( 40 | text: String, 41 | drawable: Drawable? = null, 42 | onClick: OnClickListener? = null, 43 | ) = column( 44 | MATCH_PARENT, 120.dp, 45 | padding = EdgeInsets.symmetric(horizontal = 8.dp, vertical = 10.dp), 46 | gravity = Gravity.CENTER, 47 | background = stateListDrawable( 48 | mapOf( 49 | intArrayOf(-android.R.attr.state_pressed) to rectDrawable(fillColor = Color.WHITE), 50 | intArrayOf(android.R.attr.state_pressed) to rectDrawable(fillColor = Color.parseColor("#E4E4E4")), 51 | ) 52 | ), 53 | onClick = onClick, 54 | ) { 55 | imageView( 56 | 48.dp, 48.dp, 57 | drawable = drawable, 58 | ) 59 | textView( 60 | text = text, 61 | maxLines = 1, 62 | ellipsize = TextUtils.TruncateAt.END, 63 | margin = EdgeInsets.all(8.dp), 64 | ) 65 | } -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/main/MainPage.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.main 2 | 3 | import android.content.Context 4 | import android.graphics.Typeface 5 | import android.util.AttributeSet 6 | import android.view.Gravity 7 | import com.seewo.brick.BrickPreview 8 | import com.seewo.brick.app.R 9 | import com.seewo.brick.app.component.ComponentPage 10 | import com.seewo.brick.app.extra.ExtraPage 11 | import com.seewo.brick.app.helper.HelperPage 12 | import com.seewo.brick.ktx.MATCH_PARENT 13 | import com.seewo.brick.ktx.colorDrawable 14 | import com.seewo.brick.ktx.column 15 | import com.seewo.brick.ktx.divider 16 | import com.seewo.brick.ktx.dp 17 | import com.seewo.brick.ktx.drawable 18 | import com.seewo.brick.ktx.expand 19 | import com.seewo.brick.ktx.live 20 | import com.seewo.brick.ktx.liveTabLayout 21 | import com.seewo.brick.ktx.liveViewPager 22 | import com.seewo.brick.ktx.static 23 | import com.seewo.brick.ktx.textView 24 | import com.seewo.brick.ktx.view 25 | import com.seewo.brick.params.CompoundDrawables 26 | import com.seewo.brick.params.EdgeInsets 27 | 28 | class MainPage(context: Context, attributeSet: AttributeSet?) : 29 | BrickPreview(context, attributeSet) { 30 | override fun preview(context: Context) { 31 | view { 32 | context.mainPage() 33 | } 34 | } 35 | } 36 | 37 | fun Context.mainPage() = column( 38 | MATCH_PARENT, MATCH_PARENT, 39 | fitsSystemWindows = true 40 | ) { 41 | val currentIndex = 0.live 42 | val tabs = listOf( 43 | Pair(R.drawable.selector_icon_tabbar_component, "控件"), 44 | Pair(R.drawable.selector_icon_tabbar_util, "工具"), 45 | Pair(R.drawable.selector_icon_tabbar_expand, "扩展"), 46 | ).static 47 | expand { 48 | liveViewPager( 49 | MATCH_PARENT, MATCH_PARENT, 50 | data = tabs, 51 | currentIndex = currentIndex, 52 | smoothScroll = false, 53 | isUserInputEnable = false, 54 | ) { _, index -> 55 | when (index) { 56 | 0 -> ComponentPage() 57 | 1 -> HelperPage() 58 | else -> ExtraPage() 59 | } 60 | } 61 | } 62 | divider(height = 1.dp, background = R.color.grey_e4.colorDrawable) 63 | liveTabLayout( 64 | MATCH_PARENT, 64.dp, 65 | data = tabs, 66 | margin = EdgeInsets.symmetric(horizontal = 44.dp), 67 | currentIndex = currentIndex, 68 | ) { _, item -> 69 | textView( 70 | text = item.second, 71 | style = R.style.TabStyle, 72 | compoundDrawables = CompoundDrawables( 73 | top = item.first.drawable 74 | ), 75 | textStyle = Typeface.BOLD, 76 | gravity = Gravity.CENTER, 77 | ) 78 | } 79 | } -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/widget/CommonKTX.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.widget 2 | 3 | import android.graphics.drawable.Drawable 4 | import com.seewo.brick.app.R 5 | import com.seewo.brick.ktx.* 6 | import com.seewo.brick.params.CornerRadius 7 | 8 | val buttonBackGround: Drawable 9 | get() = stateListDrawable( 10 | mapOf( 11 | intArrayOf(-android.R.attr.state_enabled) to rectDrawable( 12 | fillColor = R.color.primary.color.withAlpha(0.4f), 13 | corners = CornerRadius.all(4.dp), 14 | ), 15 | intArrayOf(android.R.attr.state_pressed) to rectDrawable( 16 | fillColor = R.color.primary.color.withAlpha(0.6f), 17 | corners = CornerRadius.all(4.dp), 18 | ), 19 | intArrayOf( 20 | -android.R.attr.state_pressed, 21 | android.R.attr.state_enabled 22 | ) to rectDrawable( 23 | fillColor = R.color.primary.color, 24 | corners = CornerRadius.all(4.dp), 25 | ), 26 | ) 27 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/widget/Markdown.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.widget 2 | 3 | import android.content.Context 4 | import android.view.View 5 | import android.view.ViewGroup 6 | import club.andnext.markdown.MarkdownWebView 7 | import com.seewo.brick.ktx.MATCH_PARENT 8 | import com.seewo.brick.ktx.init 9 | import com.seewo.brick.ktx.placeholder 10 | import com.seewo.brick.ktx.view 11 | 12 | fun ViewGroup.Markdown( 13 | text: String 14 | ): View { 15 | if (isInEditMode) return placeholder() // 避免预览模式报错 16 | return view { 17 | // 第三方控件:MarkdownWebView 18 | MarkdownWebView(context).apply { 19 | // 初始化宽高 20 | init(MATCH_PARENT, MATCH_PARENT) 21 | setText(text) 22 | } 23 | } 24 | } 25 | 26 | fun Context.Markdown( 27 | text: String 28 | ): View { 29 | return MarkdownWebView(this).apply { 30 | // 初始化宽高 31 | init(MATCH_PARENT, MATCH_PARENT) 32 | setText(text) 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/widget/SeekValue.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.widget 2 | 3 | import android.graphics.Color 4 | import android.view.Gravity 5 | import android.widget.LinearLayout 6 | import androidx.lifecycle.MutableLiveData 7 | import com.seewo.brick.app.R 8 | import com.seewo.brick.ktx.* 9 | import com.seewo.brick.params.CornerRadius 10 | import com.seewo.brick.params.EdgeInsets 11 | 12 | fun LinearLayout.SeekValue( 13 | name: String, 14 | max: Int, 15 | value: MutableLiveData, 16 | valueMapper: (Int) -> String 17 | ) { 18 | row(MATCH_PARENT, 24.dp) { 19 | textView( 20 | 60.dp, 21 | text = name 22 | ) 23 | expand { 24 | liveSeekBar( 25 | MATCH_PARENT, 12.dp, 26 | thumb = ovalDrawable( 27 | width = 12.dp, 28 | height = 12.dp, 29 | strokeWidth = 1.dp, 30 | strokeColor = R.color.primary.color, 31 | fillColor = Color.WHITE, 32 | ), 33 | thumbOffset = 2.dp, 34 | progressBackground = rectDrawable( 35 | fillColor = R.color.grey_e4.color, 36 | corners = CornerRadius.all(60.dp), 37 | ), 38 | progressDrawable = rectDrawable( 39 | fillColor = R.color.primary.color, 40 | corners = CornerRadius.all(60.dp), 41 | ), 42 | progress = value, 43 | max = max, 44 | padding = EdgeInsets.symmetric(vertical = 4.dp, horizontal = 2.dp) 45 | ) 46 | } 47 | liveText( 48 | 40.dp, 49 | text = value.map(valueMapper), 50 | gravity = Gravity.END, 51 | ) 52 | } 53 | } -------------------------------------------------------------------------------- /app/src/main/java/com/seewo/brick/app/widget/TopBar.kt: -------------------------------------------------------------------------------- 1 | package com.seewo.brick.app.widget 2 | 3 | import android.app.Activity 4 | import android.view.ViewGroup 5 | import android.widget.ImageView 6 | import com.seewo.brick.app.R 7 | import com.seewo.brick.ktx.* 8 | 9 | fun ViewGroup.TopBar() { 10 | row( 11 | MATCH_PARENT, 44.dp, 12 | ) { 13 | imageView( 14 | 44.dp, 44.dp, 15 | drawable = R.drawable.ic_back_dark.drawable, 16 | scaleType = ImageView.ScaleType.CENTER_INSIDE, 17 | ) { 18 | (context as? Activity)?.onBackPressed() 19 | } 20 | expand() 21 | } 22 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_expand_web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-hdpi/ic_expand_web.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_util_color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-hdpi/ic_util_color.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_util_drawable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-hdpi/ic_util_drawable.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_widget_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-hdpi/ic_widget_button.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_widget_dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-hdpi/ic_widget_dialog.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_widget_flowlayout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-hdpi/ic_widget_flowlayout.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_widget_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-hdpi/ic_widget_layout.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_widget_loading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-hdpi/ic_widget_loading.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_widget_picker_view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-hdpi/ic_widget_picker_view.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_widget_spinner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-hdpi/ic_widget_spinner.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_widget_statelayout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-hdpi/ic_widget_statelayout.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_widget_titlebar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-hdpi/ic_widget_titlebar.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/icon_tabbar_component.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-hdpi/icon_tabbar_component.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/icon_tabbar_component_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-hdpi/icon_tabbar_component_selected.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/icon_tabbar_expand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-hdpi/icon_tabbar_expand.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/icon_tabbar_expand_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-hdpi/icon_tabbar_expand_selected.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/icon_tabbar_util.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-hdpi/icon_tabbar_util.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/icon_tabbar_util_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-hdpi/icon_tabbar_util_selected.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/btn_add_food.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-xhdpi/btn_add_food.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_back_white.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-xhdpi/ic_back_white.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/page1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-xhdpi/page1.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/page2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-xhdpi/page2.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/page3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-xhdpi/page3.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/tab_courseware_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-xhdpi/tab_courseware_normal.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/tab_courseware_press.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-xhdpi/tab_courseware_press.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/tab_me_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-xhdpi/tab_me_normal.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/tab_me_press.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/drawable-xhdpi/tab_me_press.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_back_dark.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 9 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_checked_right.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_well_chosen.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 12 | 13 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_icon_tabbar_component.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_icon_tabbar_expand.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_icon_tabbar_util.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tab_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tab_me.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tab_permission.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/white_radius.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/robin8yeung/BrickUI/7841a5d78a18cef04fd775c36df653c1c1fae8bd/app/src/main/res/mipmap/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | #E4E4E4 11 | #399EE3 12 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 4dp 5 | 5dp 6 | 6dp 7 | 2dp 8 | 180dp 9 | 16dp 10 | 16dp 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 13 | 18 | 19 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 24 | 25 | 26 | 34 | 35 | 39 | 40 |