├── .gitignore
├── app
├── .gitignore
├── ExampleDemo
├── ExampleDemoFlavor.jks
├── build.gradle
├── google-services.json
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── chenyihong
│ │ └── exampledemo
│ │ └── ExampleInstrumentedTest.kt
│ ├── exampleflavor
│ ├── assets
│ │ └── flavor_config.json
│ └── res
│ │ ├── drawable
│ │ └── icon_android.png
│ │ ├── layout
│ │ └── layout_flavor_example_activity.xml
│ │ └── values
│ │ └── strings.xml
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ ├── index.html
│ │ ├── index_intercept_request.html
│ │ ├── index_new_tab.html
│ │ ├── index_open_tab.html
│ │ └── test_icon.jpg
│ ├── java
│ │ └── com
│ │ │ └── chenyihong
│ │ │ └── exampledemo
│ │ │ ├── adapter
│ │ │ ├── TestFunctionAdapter.kt
│ │ │ ├── TestFunctionGroupAdapter.kt
│ │ │ ├── TextDataAdapter.kt
│ │ │ └── ViewPager2Adapter.kt
│ │ │ ├── androidapi
│ │ │ ├── animation
│ │ │ │ └── AnimatorSetExampleActivity.kt
│ │ │ ├── autofill
│ │ │ │ ├── AutofillExampleActivity.kt
│ │ │ │ └── ExampleAutofillServices.kt
│ │ │ ├── autohide
│ │ │ │ └── AutoEdgeHideActivity.kt
│ │ │ ├── backpress
│ │ │ │ ├── BackPressApiActivity.kt
│ │ │ │ ├── FragmentA.kt
│ │ │ │ └── FragmentB.kt
│ │ │ ├── biometrics
│ │ │ │ ├── BiometricActivity.kt
│ │ │ │ └── CryptographyManager.kt
│ │ │ ├── camerax
│ │ │ │ ├── CameraActivity.kt
│ │ │ │ └── CameraLifecycle.kt
│ │ │ ├── downloadablefont
│ │ │ │ └── DownloadableFontActivity.kt
│ │ │ ├── fragmentresultapi
│ │ │ │ ├── DialogFragment.kt
│ │ │ │ ├── FragmentA.kt
│ │ │ │ ├── FragmentB.kt
│ │ │ │ └── FragmentResultApiActivity.kt
│ │ │ ├── fullscreen
│ │ │ │ ├── FullScreenActivity.kt
│ │ │ │ ├── FullScreenExampleActivity.kt
│ │ │ │ └── ImmersionActivity.kt
│ │ │ ├── gaid
│ │ │ │ └── GaIdActivity.kt
│ │ │ ├── gesturedetector
│ │ │ │ ├── BaseGestureDetectorActivity.kt
│ │ │ │ ├── GestureDetectorAActivity.kt
│ │ │ │ └── GestureDetectorBActivity.kt
│ │ │ ├── gps
│ │ │ │ └── GpsSignalActivity.kt
│ │ │ ├── ipandua
│ │ │ │ └── IPAndUAExample.kt
│ │ │ ├── motionlayout
│ │ │ │ └── MotionLayoutExampleActivity.kt
│ │ │ ├── resultapi
│ │ │ │ ├── ResultApiActivity.kt
│ │ │ │ └── custom
│ │ │ │ │ ├── MultipleLauncherOptions.kt
│ │ │ │ │ ├── PickMultipleMediumContract.kt
│ │ │ │ │ └── PickSingleMediumContract.kt
│ │ │ ├── search
│ │ │ │ ├── RecentSearchProvider.kt
│ │ │ │ ├── SearchActivity.kt
│ │ │ │ └── SearchExampleActivity.kt
│ │ │ ├── setting
│ │ │ │ ├── ExampleDataStore.kt
│ │ │ │ ├── HelperFragment.kt
│ │ │ │ ├── SettingActivity.kt
│ │ │ │ ├── SettingFragment.kt
│ │ │ │ └── UserInfoFragment.kt
│ │ │ ├── sharesheet
│ │ │ │ └── SystemShareActivity.kt
│ │ │ ├── shortcuts
│ │ │ │ ├── CreateCameraShortcutActivity.kt
│ │ │ │ ├── CreateLocationShortcutActivity.kt
│ │ │ │ └── ShortcutsActivity.kt
│ │ │ ├── timechange
│ │ │ │ └── TimeChangeExample.kt
│ │ │ ├── toolbar
│ │ │ │ └── ToolbarActivity.kt
│ │ │ ├── trafficstats
│ │ │ │ ├── NetSpeedUtils.kt
│ │ │ │ └── TrafficStatsActivity.kt
│ │ │ └── wifi
│ │ │ │ ├── WIFIAdapter.kt
│ │ │ │ ├── WIFIEntity.kt
│ │ │ │ └── WIFIExampleActivity.kt
│ │ │ ├── base
│ │ │ ├── ExampleApplication.kt
│ │ │ └── MimeType.kt
│ │ │ ├── customview
│ │ │ ├── CustomChartViewActivity.kt
│ │ │ ├── CustomShadowViewActivity.kt
│ │ │ └── view
│ │ │ │ ├── GradientLineChart.kt
│ │ │ │ ├── ShadowView.kt
│ │ │ │ └── VolumeControllerDialog.kt
│ │ │ ├── entity
│ │ │ ├── LineEntity.kt
│ │ │ ├── OptionsChildEntity.kt
│ │ │ ├── OptionsEntity.kt
│ │ │ └── PersonEntity.kt
│ │ │ ├── flavor
│ │ │ └── FlavorExampleActivity.kt
│ │ │ ├── home
│ │ │ └── HomeActivity.kt
│ │ │ ├── tripartite
│ │ │ ├── admob
│ │ │ │ ├── AdmobExampleActivity.kt
│ │ │ │ ├── AppOpenAdActivity.kt
│ │ │ │ └── AppOpenAdManager.kt
│ │ │ ├── fcm
│ │ │ │ └── ExampleFCMService.kt
│ │ │ ├── login
│ │ │ │ └── TripartiteLoginActivity.kt
│ │ │ └── share
│ │ │ │ ├── FacebookShareActivity.kt
│ │ │ │ └── TripartiteShareActivity.kt
│ │ │ ├── utils
│ │ │ ├── DateUtils.kt
│ │ │ ├── DensityUtil.kt
│ │ │ └── ShapeDrawableUtils.kt
│ │ │ └── web
│ │ │ ├── JsInteractive.kt
│ │ │ ├── WebViewActivity.kt
│ │ │ └── customtab
│ │ │ ├── CustomTabExampleActivity.kt
│ │ │ └── CustomTabHelper.kt
│ └── res
│ │ ├── anim
│ │ ├── slide_in_right.xml
│ │ └── slide_out_left.xml
│ │ ├── drawable
│ │ ├── facebook.webp
│ │ ├── google.webp
│ │ ├── icon_android.png
│ │ ├── icon_back.webp
│ │ ├── icon_biometrics.webp
│ │ ├── icon_camera.webp
│ │ ├── icon_juejin.jpeg
│ │ ├── icon_location.webp
│ │ ├── icon_lock.webp
│ │ ├── icon_scan.webp
│ │ ├── icon_scan_32_black.webp
│ │ ├── icon_search.webp
│ │ ├── icon_search_48.webp
│ │ ├── icon_setting.webp
│ │ ├── icon_thumb_up.webp
│ │ ├── icon_unlock.webp
│ │ ├── layer_progress.xml
│ │ ├── login.webp
│ │ ├── notification.webp
│ │ ├── shape_float_bg.xml
│ │ ├── shape_float_bg1.xml
│ │ ├── shape_oval.xml
│ │ ├── shape_red_oval.xml
│ │ ├── shape_vollume_controller.xml
│ │ ├── wifi_strength_0.webp
│ │ ├── wifi_strength_1.webp
│ │ ├── wifi_strength_2.webp
│ │ └── wifi_strength_3.webp
│ │ ├── font
│ │ ├── noto_sans.xml
│ │ ├── noto_sans_bold.xml
│ │ ├── noto_sanssc_bold.otf
│ │ ├── noto_sanssc_regular.otf
│ │ ├── noto_serif.xml
│ │ └── noto_serif_bold.xml
│ │ ├── layout
│ │ ├── layout_admob_example_activity.xml
│ │ ├── layout_admob_native_ad.xml
│ │ ├── layout_animatorset_example_activity.xml
│ │ ├── layout_app_open_activity.xml
│ │ ├── layout_auto_edge_hide_activity.xml
│ │ ├── layout_autofill_example_activity.xml
│ │ ├── layout_back_press_api_activity.xml
│ │ ├── layout_back_press_api_fragment.xml
│ │ ├── layout_biometric_activity.xml
│ │ ├── layout_camera_activity.xml
│ │ ├── layout_connectivity_example_activity.xml
│ │ ├── layout_create_shortcuts_activity.xml
│ │ ├── layout_custom_chart_view_activity.xml
│ │ ├── layout_custom_shadow_view_activity.xml
│ │ ├── layout_custom_tab_activity.xml
│ │ ├── layout_downloadable_font_activity.xml
│ │ ├── layout_facebook_share_activity.xml
│ │ ├── layout_flavor_example_activity.xml
│ │ ├── layout_fragment_result_api_activity.xml
│ │ ├── layout_fragment_result_api_dialog_fragment.xml
│ │ ├── layout_fragment_result_api_fragment_a.xml
│ │ ├── layout_fragment_result_api_fragment_b.xml
│ │ ├── layout_full_screen_activity.xml
│ │ ├── layout_full_screen_example_activity.xml
│ │ ├── layout_gaid_activity.xml
│ │ ├── layout_gesture_detector_activity.xml
│ │ ├── layout_gps_signal_activity.xml
│ │ ├── layout_home_activity.xml
│ │ ├── layout_immersion_activity.xml
│ │ ├── layout_motion_layout_example_activity.xml
│ │ ├── layout_options_child_item.xml
│ │ ├── layout_options_parent_item.xml
│ │ ├── layout_result_api_activity.xml
│ │ ├── layout_search_activity.xml
│ │ ├── layout_search_example_activity.xml
│ │ ├── layout_setting_activity.xml
│ │ ├── layout_share_activity.xml
│ │ ├── layout_shortcuts_activity.xml
│ │ ├── layout_system_share_activity.xml
│ │ ├── layout_text_content_item.xml
│ │ ├── layout_time_change_example_activity.xml
│ │ ├── layout_title.xml
│ │ ├── layout_toolbar_activity.xml
│ │ ├── layout_traffic_stats_activity.xml
│ │ ├── layout_tripartite_login_activity.xml
│ │ ├── layout_volume_contoller_dialog.xml
│ │ ├── layout_web_view_activity.xml
│ │ ├── layout_wifi_example_activity.xml
│ │ ├── layout_wifi_input_password_dialog.xml
│ │ └── layout_wifi_item.xml
│ │ ├── menu
│ │ ├── example_menu.xml
│ │ └── example_seach_menu.xml
│ │ ├── mipmap-hdpi
│ │ └── icon_back.webp
│ │ ├── mipmap-mdpi
│ │ └── icon_back.webp
│ │ ├── mipmap-xhdpi
│ │ └── icon_back.webp
│ │ ├── mipmap-xxhdpi
│ │ └── icon_back.webp
│ │ ├── mipmap-xxxhdpi
│ │ └── icon_back.webp
│ │ ├── values-night
│ │ └── themes.xml
│ │ ├── values
│ │ ├── attrs.xml
│ │ ├── colors.xml
│ │ ├── font_certs.xml
│ │ ├── preloaded_fonts.xml
│ │ ├── strings.xml
│ │ └── themes.xml
│ │ └── xml
│ │ ├── data_extraction_rules.xml
│ │ ├── example_motion_scene.xml
│ │ ├── example_setting.xml
│ │ ├── example_user_info.xml
│ │ ├── file_path.xml
│ │ ├── full_backup_content.xml
│ │ ├── searchable.xml
│ │ └── shortcuts.xml
│ └── test
│ └── java
│ └── com
│ └── chenyihong
│ └── exampledemo
│ └── ExampleUnitTest.kt
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea
5 | .DS_Store
6 | /build
7 | /captures
8 | .externalNativeBuild
9 | .cxx
10 | local.properties
11 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/ExampleDemo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/ExampleDemo
--------------------------------------------------------------------------------
/app/ExampleDemoFlavor.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/ExampleDemoFlavor.jks
--------------------------------------------------------------------------------
/app/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "905315689902",
4 | "project_id": "exampledemo-1651736171734",
5 | "storage_bucket": "exampledemo-1651736171734.appspot.com"
6 | },
7 | "client": [
8 | {
9 | "client_info": {
10 | "mobilesdk_app_id": "1:905315689902:android:08286b58e58c8c484ad43f",
11 | "android_client_info": {
12 | "package_name": "com.chenyihong.exampledemo"
13 | }
14 | },
15 | "oauth_client": [
16 | {
17 | "client_id": "905315689902-lpgfq29mikifeuoodaa0hm36p5quqr5h.apps.googleusercontent.com",
18 | "client_type": 1,
19 | "android_info": {
20 | "package_name": "com.chenyihong.exampledemo",
21 | "certificate_hash": "4a185aa09bd5bbb5a684b75b51477fb334f92897"
22 | }
23 | },
24 | {
25 | "client_id": "905315689902-hvgsu7564tllr1kaq9k2pecibvno97kq.apps.googleusercontent.com",
26 | "client_type": 3
27 | }
28 | ],
29 | "api_key": [
30 | {
31 | "current_key": "AIzaSyB7QFJ6Pe0f9ndgH1pBtBxL7X7-QkBJzQg"
32 | }
33 | ],
34 | "services": {
35 | "appinvite_service": {
36 | "other_platform_oauth_client": [
37 | {
38 | "client_id": "905315689902-hvgsu7564tllr1kaq9k2pecibvno97kq.apps.googleusercontent.com",
39 | "client_type": 3
40 | }
41 | ]
42 | }
43 | }
44 | }
45 | ],
46 | "configuration_version": "1"
47 | }
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/chenyihong/exampledemo/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.chenyihong.exampledemo", appContext.packageName)
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/exampleflavor/assets/flavor_config.json:
--------------------------------------------------------------------------------
1 | {
2 | "flavor_name": "example_flavor"
3 | }
--------------------------------------------------------------------------------
/app/src/exampleflavor/res/drawable/icon_android.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/exampleflavor/res/drawable/icon_android.png
--------------------------------------------------------------------------------
/app/src/exampleflavor/res/layout/layout_flavor_example_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
12 |
13 |
22 |
23 |
32 |
33 |
42 |
43 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/app/src/exampleflavor/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | FlavorExampleDemo
3 |
--------------------------------------------------------------------------------
/app/src/main/assets/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | test
6 |
27 |
28 |
29 |
30 |
receive:
31 |
35 |
39 |
40 |
41 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/app/src/main/assets/index_intercept_request.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | test
6 |
7 |
8 |
9 |

10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/assets/index_new_tab.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | test
6 |
15 |
16 |
17 |
18 |
receive:
19 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/assets/index_open_tab.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | test
6 |
15 |
16 |
17 |
18 |
receive:
19 |
use a tag
20 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/assets/test_icon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/assets/test_icon.jpg
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/adapter/TestFunctionAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.adapter
2 |
3 | import android.view.LayoutInflater
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import androidx.appcompat.widget.AppCompatTextView
7 | import androidx.recyclerview.widget.RecyclerView
8 | import com.chenyihong.exampledemo.R
9 | import com.chenyihong.exampledemo.entity.OptionsChildEntity
10 |
11 | class TestFunctionAdapter : RecyclerView.Adapter() {
12 |
13 | private val testFunctions = ArrayList()
14 |
15 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TestFunctionViewHolder {
16 | return TestFunctionViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.layout_options_child_item, parent, false))
17 | }
18 |
19 | override fun onBindViewHolder(holder: TestFunctionViewHolder, position: Int) {
20 | val functionEntity = testFunctions[position]
21 | holder.tvFunctionName.text = functionEntity.testFunctionName
22 | holder.vDividerBottom.visibility = if (position == itemCount - 1) View.GONE else View.VISIBLE
23 | holder.itemView.setOnClickListener {
24 | functionEntity.testFunction.invoke()
25 | }
26 | }
27 |
28 | override fun getItemCount(): Int {
29 | return testFunctions.size
30 | }
31 |
32 | fun setNewData(testFunctions: ArrayList?) {
33 | val currentItemCount = itemCount
34 | if (currentItemCount != 0) {
35 | this.testFunctions.clear()
36 | notifyItemRangeRemoved(0, currentItemCount)
37 | }
38 | if (!testFunctions.isNullOrEmpty()) {
39 | this.testFunctions.addAll(testFunctions)
40 | notifyItemRangeChanged(0, itemCount)
41 | }
42 | }
43 |
44 | class TestFunctionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
45 | val vDividerBottom: View = itemView.findViewById(R.id.v_divider_bottom)
46 | val tvFunctionName: AppCompatTextView = itemView.findViewById(R.id.tv_test_function_name)
47 | }
48 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/adapter/TestFunctionGroupAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.adapter
2 |
3 | import android.view.LayoutInflater
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import androidx.appcompat.widget.AppCompatTextView
7 | import androidx.recyclerview.widget.RecyclerView
8 | import androidx.recyclerview.widget.SimpleItemAnimator
9 | import com.chenyihong.exampledemo.R
10 |
11 | import com.minigame.testapp.ui.entity.OptionsEntity
12 |
13 | class TestFunctionGroupAdapter : RecyclerView.Adapter() {
14 |
15 | private val functionGroup = ArrayList()
16 |
17 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TestFunctionGroupViewHolder {
18 | return TestFunctionGroupViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.layout_options_parent_item, parent, false))
19 | }
20 |
21 | override fun onBindViewHolder(holder: TestFunctionGroupViewHolder, position: Int) {
22 | val functionGroupEntity = functionGroup[position]
23 | holder.vDividerTop.visibility = if (position == 0) View.VISIBLE else View.GONE
24 | holder.tvFunctionGroupName.text = functionGroupEntity.moduleName
25 | holder.tvFunctionGroupName.setOnClickListener {
26 | functionGroupEntity.expanded = !functionGroupEntity.expanded
27 | notifyItemChanged(position)
28 | }
29 | holder.rvTestFunction.visibility = if (functionGroupEntity.expanded) View.VISIBLE else View.GONE
30 | holder.vDividerMiddle.visibility = if (functionGroupEntity.expanded) View.VISIBLE else View.GONE
31 | holder.testFunctionAdapter?.setNewData(functionGroupEntity.containerTest)
32 | }
33 |
34 | override fun getItemCount(): Int {
35 | return functionGroup.size
36 | }
37 |
38 | fun setNewData(functionGroup: ArrayList?) {
39 | val currentItemCount = itemCount
40 | if (currentItemCount != 0) {
41 | this.functionGroup.clear()
42 | notifyItemRangeRemoved(0, currentItemCount)
43 | }
44 | if (!functionGroup.isNullOrEmpty()) {
45 | this.functionGroup.addAll(functionGroup)
46 | notifyItemRangeChanged(0, itemCount)
47 | }
48 | }
49 |
50 | class TestFunctionGroupViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
51 | val vDividerTop: View = itemView.findViewById(R.id.v_divider_top)
52 | val vDividerMiddle: View = itemView.findViewById(R.id.v_divider_middle)
53 | val tvFunctionGroupName: AppCompatTextView = itemView.findViewById(R.id.tv_group_name)
54 | val rvTestFunction: RecyclerView = itemView.findViewById(R.id.rv_test_function)
55 | var testFunctionAdapter: TestFunctionAdapter? = null
56 |
57 | init {
58 | testFunctionAdapter = TestFunctionAdapter()
59 | rvTestFunction.adapter = testFunctionAdapter
60 | val itemAnimator = rvTestFunction.itemAnimator
61 | if (itemAnimator != null) {
62 | (itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
63 | }
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/adapter/TextDataAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.adapter
2 |
3 | import android.view.LayoutInflater
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import androidx.appcompat.widget.AppCompatTextView
7 | import androidx.recyclerview.widget.RecyclerView
8 | import com.chenyihong.exampledemo.R
9 |
10 | class TextDataAdapter : RecyclerView.Adapter() {
11 |
12 | private val textData = ArrayList()
13 |
14 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TextDataViewHolder {
15 | return TextDataViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.layout_text_content_item, parent, false))
16 | }
17 |
18 | override fun onBindViewHolder(holder: TextDataViewHolder, position: Int) {
19 | holder.tvTextDataContent.text = textData[position]
20 | }
21 |
22 | override fun getItemCount(): Int {
23 | return textData.size
24 | }
25 |
26 | fun setNewData(searchData: ArrayList?) {
27 | val lastItemCount = itemCount
28 | if (lastItemCount != 0) {
29 | this.textData.clear()
30 | notifyItemRangeRemoved(0, lastItemCount)
31 | }
32 | searchData?.let { this.textData.addAll(it) }
33 | notifyItemChanged(0, itemCount)
34 | }
35 |
36 | class TextDataViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
37 | val tvTextDataContent: AppCompatTextView = itemView.findViewById(R.id.tv_content)
38 | }
39 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/adapter/ViewPager2Adapter.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.adapter
2 |
3 | import androidx.fragment.app.Fragment
4 | import androidx.fragment.app.FragmentActivity
5 | import androidx.viewpager2.adapter.FragmentStateAdapter
6 |
7 | class ViewPager2Adapter : FragmentStateAdapter {
8 |
9 | private val fragments: ArrayList>
10 |
11 | constructor(fragment: Fragment, fragments: ArrayList>) : super(fragment) {
12 | this.fragments = fragments
13 | }
14 |
15 | constructor(fragmentActivity: FragmentActivity, fragments: ArrayList>) : super(fragmentActivity) {
16 | this.fragments = fragments
17 | }
18 |
19 | override fun getItemCount(): Int {
20 | return fragments.size
21 | }
22 |
23 | override fun createFragment(position: Int): Fragment {
24 | return fragments[position].newInstance()!!
25 | }
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/autofill/AutofillExampleActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.autofill
2 |
3 | import android.app.Activity
4 | import android.content.Intent
5 | import android.net.Uri
6 | import android.os.Build
7 | import android.os.Bundle
8 | import android.provider.Settings
9 | import android.util.Log
10 | import android.view.autofill.AutofillManager
11 | import androidx.activity.result.contract.ActivityResultContracts
12 | import androidx.core.widget.addTextChangedListener
13 | import androidx.databinding.DataBindingUtil
14 | import com.chenyihong.exampledemo.R
15 | import com.chenyihong.exampledemo.androidapi.gesturedetector.BaseGestureDetectorActivity
16 | import com.chenyihong.exampledemo.databinding.LayoutAutofillExampleActivityBinding
17 |
18 | const val TAG = "AutofillExampleTag"
19 |
20 | class AutoFillExampleActivity : BaseGestureDetectorActivity() {
21 |
22 | private val launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
23 | if (it.resultCode == Activity.RESULT_OK) {
24 | Log.i(TAG, "result ok")
25 | }
26 | }
27 |
28 | override fun onCreate(savedInstanceState: Bundle?) {
29 | super.onCreate(savedInstanceState)
30 | val binding = DataBindingUtil.setContentView(this, R.layout.layout_autofill_example_activity)
31 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
32 | val autofillManager = getSystemService(AutofillManager::class.java)
33 | binding.etAccount.addTextChangedListener {
34 | it?.run {
35 | binding.etPassword.text?.let { passwordText ->
36 | binding.btnCommit.isEnabled = isNotEmpty() && passwordText.isNotEmpty()
37 | }
38 | }
39 | }
40 | binding.etPassword.addTextChangedListener {
41 | it?.run {
42 | binding.etAccount.text?.let { accountText ->
43 | binding.btnCommit.isEnabled = isNotEmpty() && accountText.isNotEmpty()
44 | }
45 | }
46 | }
47 | binding.btnCommit.setOnClickListener {
48 | binding.etAccount.clearFocus()
49 | binding.etPassword.clearFocus()
50 | autofillManager.commit()
51 | }
52 | binding.btnChangeAutofillService.setOnClickListener {
53 | // isAutofillSupported判断设备是否支持自动填充服务
54 | // hasEnabledAutofillServices判断当前使用的自动填充服务是否是我们自定义的
55 | if (autofillManager.isAutofillSupported && !autofillManager.hasEnabledAutofillServices()) {
56 | launcher.launch(Intent(Settings.ACTION_REQUEST_SET_AUTOFILL_SERVICE).apply {
57 | data = Uri.parse("package:com.chenyihong.exampledemo")
58 | })
59 | }
60 | }
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/backpress/BackPressApiActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.backpress
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Bundle
5 | import android.util.Log
6 | import androidx.activity.OnBackPressedCallback
7 | import androidx.databinding.DataBindingUtil
8 | import androidx.fragment.app.Fragment
9 | import com.chenyihong.exampledemo.R
10 | import com.chenyihong.exampledemo.adapter.ViewPager2Adapter
11 | import com.chenyihong.exampledemo.databinding.LayoutBackPressApiActivityBinding
12 | import com.chenyihong.exampledemo.androidapi.gesturedetector.BaseGestureDetectorActivity
13 |
14 | const val TAG = "BackPressApi"
15 |
16 | class BackPressApiActivity : BaseGestureDetectorActivity() {
17 |
18 | private val canonicalName = this::class.java.canonicalName!!
19 |
20 | @SuppressLint("SetTextI18n")
21 | override fun onCreate(savedInstanceState: Bundle?) {
22 | super.onCreate(savedInstanceState)
23 | val binding = DataBindingUtil.setContentView(this, R.layout.layout_back_press_api_activity)
24 | supportFragmentManager.setFragmentResultListener(canonicalName, this) { requestKey, result ->
25 | Log.i(com.chenyihong.exampledemo.androidapi.fragmentresultapi.TAG, "Activity receive result requestKey:$requestKey ,result:$result")
26 | if (requestKey == canonicalName) {
27 | val resultIndex = result.getInt("result", -1)
28 | if (resultIndex != -1) {
29 | binding.vpContainer.currentItem = resultIndex
30 | }
31 | }
32 | }
33 | onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
34 | override fun handleOnBackPressed() {
35 | Log.i(TAG, "BackPressApiActivity OnBackPressedCallback handleOnBackPressed function invoke")
36 | finish()
37 | }
38 | })
39 | binding.run {
40 | includeTitle.tvTitle.text = "BackPress Api"
41 | btnAFragment.setOnClickListener {
42 | vpContainer.currentItem = 0
43 | }
44 | btnBFragment.setOnClickListener {
45 | vpContainer.currentItem = 1
46 | }
47 |
48 | val fragments = ArrayList>()
49 | fragments.add(FragmentA::class.java)
50 | fragments.add(FragmentB::class.java)
51 |
52 | vpContainer.adapter = ViewPager2Adapter(this@BackPressApiActivity, fragments)
53 | vpContainer.isUserInputEnabled = false
54 |
55 | vpContainer.currentItem = 0
56 | }
57 | }
58 |
59 | override fun onDestroy() {
60 | super.onDestroy()
61 | supportFragmentManager.clearFragmentResultListener(canonicalName)
62 | }
63 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/backpress/FragmentA.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.backpress
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Bundle
5 | import android.util.Log
6 | import android.view.LayoutInflater
7 | import android.view.View
8 | import android.view.ViewGroup
9 | import androidx.activity.OnBackPressedCallback
10 | import androidx.databinding.DataBindingUtil
11 | import androidx.fragment.app.Fragment
12 | import com.chenyihong.exampledemo.R
13 | import com.chenyihong.exampledemo.databinding.LayoutBackPressApiFragmentBinding
14 |
15 | class FragmentA : Fragment() {
16 |
17 | lateinit var binding: LayoutBackPressApiFragmentBinding
18 |
19 | private val onBackPressedCallback = object : OnBackPressedCallback(true) {
20 | override fun handleOnBackPressed() {
21 | Log.i(TAG, "FragmentA OnBackPressedCallback handleOnBackPressed function invoke")
22 | isEnabled = false
23 | requireActivity().onBackPressedDispatcher.onBackPressed()
24 | }
25 | }
26 |
27 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
28 | binding = DataBindingUtil.inflate(inflater, R.layout.layout_back_press_api_fragment, container, false)
29 | return binding.root
30 | }
31 |
32 | @SuppressLint("SetTextI18n")
33 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
34 | super.onViewCreated(view, savedInstanceState)
35 | requireActivity().onBackPressedDispatcher.addCallback(onBackPressedCallback)
36 | binding.includeTitle.tvTitle.text = "BackPressFragmentA"
37 | binding.btnBackPress.setOnClickListener {
38 | requireActivity().onBackPressedDispatcher.onBackPressed()
39 | }
40 | }
41 |
42 | override fun onResume() {
43 | super.onResume()
44 | onBackPressedCallback.isEnabled = true
45 | }
46 |
47 | override fun onPause() {
48 | super.onPause()
49 | onBackPressedCallback.isEnabled = false
50 | }
51 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/backpress/FragmentB.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.backpress
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Bundle
5 | import android.util.Log
6 | import android.view.LayoutInflater
7 | import android.view.View
8 | import android.view.ViewGroup
9 | import androidx.activity.OnBackPressedCallback
10 | import androidx.databinding.DataBindingUtil
11 | import androidx.fragment.app.Fragment
12 | import com.chenyihong.exampledemo.R
13 | import com.chenyihong.exampledemo.databinding.LayoutBackPressApiFragmentBinding
14 |
15 | class FragmentB : Fragment() {
16 |
17 | lateinit var binding: LayoutBackPressApiFragmentBinding
18 |
19 | private val onBackPressedCallback = object : OnBackPressedCallback(true) {
20 | override fun handleOnBackPressed() {
21 | Log.i(TAG, "FragmentB OnBackPressedCallback handleOnBackPressed function invoke")
22 | parentFragmentManager.setFragmentResult(BackPressApiActivity::class.java.canonicalName!!, Bundle().apply { putInt("result", 0) })
23 | }
24 | }
25 |
26 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
27 | binding = DataBindingUtil.inflate(inflater, R.layout.layout_back_press_api_fragment, container, false)
28 | return binding.root
29 | }
30 |
31 | @SuppressLint("SetTextI18n")
32 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
33 | super.onViewCreated(view, savedInstanceState)
34 | requireActivity().onBackPressedDispatcher.addCallback(onBackPressedCallback)
35 | binding.includeTitle.tvTitle.text = "BackPressFragmentB"
36 | binding.btnBackPress.setOnClickListener {
37 | requireActivity().onBackPressedDispatcher.onBackPressed()
38 | }
39 | }
40 |
41 | override fun onResume() {
42 | super.onResume()
43 | onBackPressedCallback.isEnabled = true
44 | }
45 |
46 | override fun onPause() {
47 | super.onPause()
48 | onBackPressedCallback.isEnabled = false
49 | }
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/camerax/CameraLifecycle.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.camerax
2 |
3 | import androidx.lifecycle.Lifecycle
4 | import androidx.lifecycle.LifecycleOwner
5 | import androidx.lifecycle.LifecycleRegistry
6 |
7 | class CameraLifecycle : LifecycleOwner {
8 |
9 | private var lifecycleRegistry: LifecycleRegistry = LifecycleRegistry(this)
10 |
11 | fun cameraOnCreate() {
12 | lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
13 | }
14 |
15 | fun cameraOnStart() {
16 | lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
17 | }
18 |
19 | fun cameraOnResume() {
20 | lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
21 | }
22 |
23 | fun cameraOnPause() {
24 | lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE)
25 | }
26 |
27 | fun cameraOnStop() {
28 | lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
29 | }
30 |
31 | fun cameraOnDestroyed() {
32 | lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
33 | }
34 |
35 | override fun getLifecycle(): Lifecycle {
36 | return lifecycleRegistry
37 | }
38 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/downloadablefont/DownloadableFontActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.downloadablefont
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Bundle
5 | import androidx.databinding.DataBindingUtil
6 | import com.chenyihong.exampledemo.R
7 | import com.chenyihong.exampledemo.databinding.LayoutDownloadableFontActivityBinding
8 | import com.chenyihong.exampledemo.androidapi.gesturedetector.BaseGestureDetectorActivity
9 |
10 | class DownloadableFontActivity : BaseGestureDetectorActivity() {
11 |
12 | @SuppressLint("SetTextI18n")
13 | override fun onCreate(savedInstanceState: Bundle?) {
14 | super.onCreate(savedInstanceState)
15 | val binding: LayoutDownloadableFontActivityBinding = DataBindingUtil.setContentView(this, R.layout.layout_downloadable_font_activity)
16 | binding.includeTitle.tvTitle.text = "DownloadAbleFont"
17 | }
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/fragmentresultapi/DialogFragment.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.fragmentresultapi
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Bundle
5 | import android.util.Log
6 | import android.view.*
7 | import androidx.core.content.ContextCompat
8 | import androidx.databinding.DataBindingUtil
9 | import androidx.fragment.app.DialogFragment
10 | import androidx.fragment.app.Fragment
11 | import com.chenyihong.exampledemo.R
12 | import com.chenyihong.exampledemo.databinding.LayoutFragmentResultApiDialogFragmentBinding
13 | import com.chenyihong.exampledemo.adapter.ViewPager2Adapter
14 |
15 | class DialogFragment : DialogFragment() {
16 |
17 | private var binding: LayoutFragmentResultApiDialogFragmentBinding? = null
18 |
19 | private val canonicalName = this::class.java.canonicalName!!
20 |
21 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
22 | dialog?.window?.run {
23 | setBackgroundDrawable(ContextCompat.getDrawable(requireContext(), android.R.color.transparent))
24 | decorView.setBackgroundResource(android.R.color.transparent)
25 |
26 | val layoutParams = attributes
27 | layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT
28 | layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT
29 | layoutParams.gravity = Gravity.CENTER
30 | attributes = layoutParams
31 | }
32 | binding = DataBindingUtil.inflate(inflater, R.layout.layout_fragment_result_api_dialog_fragment, container, false)
33 | return binding?.root
34 | }
35 |
36 | @SuppressLint("SetTextI18n")
37 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
38 | super.onViewCreated(view, savedInstanceState)
39 | childFragmentManager.setFragmentResultListener(canonicalName, this) { requestKey, result ->
40 | Log.i(TAG, "Dialog Fragment receive result requestKey:$requestKey ,result:$result")
41 | binding?.tvReceiver?.text = "Dialog Fragment receive: requestKey = $requestKey ,result = $result"
42 | val bundle = Bundle()
43 | bundle.putString("result", "DialogFragment transit ${result.getString("result", "")}")
44 | parentFragmentManager.setFragmentResult(FragmentResultApiActivity::class.java.canonicalName!!, bundle)
45 | }
46 | binding?.run {
47 | btnAFragment.setOnClickListener {
48 | vpContainer.currentItem = 0
49 | }
50 | btnBFragment.setOnClickListener {
51 | vpContainer.currentItem = 1
52 | }
53 |
54 | val fragments = ArrayList>()
55 | fragments.add(FragmentA::class.java)
56 | fragments.add(FragmentB::class.java)
57 |
58 | vpContainer.adapter = ViewPager2Adapter(this@DialogFragment, fragments)
59 | vpContainer.isUserInputEnabled = false
60 |
61 | vpContainer.currentItem = 0
62 | }
63 | }
64 |
65 | override fun onDestroyView() {
66 | binding?.unbind()
67 | childFragmentManager.clearFragmentResultListener(canonicalName)
68 | super.onDestroyView()
69 | }
70 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/fragmentresultapi/FragmentA.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.fragmentresultapi
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Bundle
5 | import android.util.Log
6 | import android.view.LayoutInflater
7 | import android.view.View
8 | import android.view.ViewGroup
9 | import androidx.databinding.DataBindingUtil
10 | import androidx.fragment.app.Fragment
11 | import com.chenyihong.exampledemo.R
12 | import com.chenyihong.exampledemo.databinding.LayoutFragmentResultApiFragmentABinding
13 |
14 | class FragmentA : Fragment() {
15 |
16 | lateinit var binding: LayoutFragmentResultApiFragmentABinding
17 |
18 | private val canonicalName = this::class.java.canonicalName!!
19 |
20 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
21 | binding = DataBindingUtil.inflate(inflater, R.layout.layout_fragment_result_api_fragment_a, container, false)
22 | return binding.root
23 | }
24 |
25 | @SuppressLint("SetTextI18n")
26 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
27 | super.onViewCreated(view, savedInstanceState)
28 | parentFragmentManager.setFragmentResultListener(canonicalName, this) { requestKey, result ->
29 | Log.i(TAG, "A Fragment receive result requestKey:$requestKey ,result:$result")
30 | binding.tvReceiver.text = "A Fragment receive: requestKey = $requestKey ,result = $result"
31 | }
32 | binding.includeTitle.tvTitle.text = "Fragment A"
33 | binding.btnSendParent.setOnClickListener {
34 | val bundle = Bundle()
35 | bundle.putString("result", "a result from Fragment A")
36 | parentFragmentManager.setFragmentResult(DialogFragment::class.java.canonicalName!!, bundle)
37 | }
38 | binding.btnSendToB.setOnClickListener {
39 | val bundle = Bundle()
40 | bundle.putString("result", "a result from Fragment A")
41 | parentFragmentManager.setFragmentResult(FragmentB::class.java.canonicalName!!, bundle)
42 | }
43 | }
44 |
45 | override fun onDestroyView() {
46 | super.onDestroyView()
47 | parentFragmentManager.clearFragmentResultListener(canonicalName)
48 | }
49 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/fragmentresultapi/FragmentB.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.fragmentresultapi
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Bundle
5 | import android.util.Log
6 | import android.view.LayoutInflater
7 | import android.view.View
8 | import android.view.ViewGroup
9 | import androidx.databinding.DataBindingUtil
10 | import androidx.fragment.app.Fragment
11 | import com.chenyihong.exampledemo.R
12 | import com.chenyihong.exampledemo.databinding.LayoutFragmentResultApiFragmentBBinding
13 |
14 | class FragmentB : Fragment() {
15 |
16 | lateinit var binding: LayoutFragmentResultApiFragmentBBinding
17 |
18 | private val canonicalName = this::class.java.canonicalName!!
19 |
20 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
21 | binding = DataBindingUtil.inflate(inflater, R.layout.layout_fragment_result_api_fragment_b, container, false)
22 | return binding.root
23 | }
24 |
25 | @SuppressLint("SetTextI18n")
26 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
27 | super.onViewCreated(view, savedInstanceState)
28 | parentFragmentManager.setFragmentResultListener(canonicalName, this) { requestKey, result ->
29 | Log.i(TAG, "B Fragment receive result requestKey:$requestKey ,result:$result")
30 | binding.tvReceiver.text = "B Fragment receive: requestKey = $requestKey ,result = $result"
31 | }
32 | binding.includeTitle.tvTitle.text="Fragment B"
33 | binding.btnSendToA.setOnClickListener {
34 | val bundle = Bundle()
35 | bundle.putString("result", "a result from Fragment B")
36 | parentFragmentManager.setFragmentResult(FragmentA::class.java.canonicalName!!, bundle)
37 | }
38 | }
39 |
40 | override fun onDestroyView() {
41 | super.onDestroyView()
42 | parentFragmentManager.clearFragmentResultListener(canonicalName)
43 | }
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/fragmentresultapi/FragmentResultApiActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.fragmentresultapi
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Bundle
5 | import android.util.Log
6 | import androidx.databinding.DataBindingUtil
7 | import com.chenyihong.exampledemo.R
8 | import com.chenyihong.exampledemo.databinding.LayoutFragmentResultApiActivityBinding
9 | import com.chenyihong.exampledemo.androidapi.gesturedetector.BaseGestureDetectorActivity
10 |
11 | const val TAG = "FragmentResultAPI"
12 |
13 | class FragmentResultApiActivity : BaseGestureDetectorActivity() {
14 |
15 | private val canonicalName = this::class.java.canonicalName!!
16 |
17 | @SuppressLint("SetTextI18n")
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 | val binding = DataBindingUtil.setContentView(this, R.layout.layout_fragment_result_api_activity)
21 |
22 | binding.includeTitle.tvTitle.text = "Fragment Result Api"
23 | supportFragmentManager.setFragmentResultListener(canonicalName, this) { requestKey, result ->
24 | Log.i(TAG, "Activity receive result requestKey:$requestKey ,result:$result")
25 | binding.tvReceiver.text = "Activity receive: requestKey = $requestKey ,result = $result"
26 | }
27 |
28 | binding.btnShowDialog.setOnClickListener {
29 | DialogFragment().show(supportFragmentManager, null)
30 | }
31 | }
32 |
33 | override fun onDestroy() {
34 | super.onDestroy()
35 | supportFragmentManager.clearFragmentResultListener(canonicalName)
36 | }
37 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/fullscreen/FullScreenActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.fullscreen
2 |
3 | import android.os.Bundle
4 | import androidx.core.view.*
5 | import androidx.databinding.DataBindingUtil
6 | import com.chenyihong.exampledemo.R
7 | import com.chenyihong.exampledemo.databinding.LayoutFullScreenActivityBinding
8 | import com.chenyihong.exampledemo.androidapi.gesturedetector.BaseGestureDetectorActivity
9 |
10 | class FullScreenActivity : BaseGestureDetectorActivity() {
11 |
12 | lateinit var binding: LayoutFullScreenActivityBinding
13 |
14 | override fun onCreate(savedInstanceState: Bundle?) {
15 | super.onCreate(savedInstanceState)
16 | binding = DataBindingUtil.setContentView(this, R.layout.layout_full_screen_activity)
17 | val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
18 | windowInsetsController.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
19 | windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
20 | }
21 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/fullscreen/FullScreenExampleActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.fullscreen
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Intent
5 | import android.os.Bundle
6 | import androidx.databinding.DataBindingUtil
7 | import com.chenyihong.exampledemo.R
8 | import com.chenyihong.exampledemo.databinding.LayoutFullScreenExampleActivityBinding
9 | import com.chenyihong.exampledemo.androidapi.gesturedetector.BaseGestureDetectorActivity
10 |
11 | class FullScreenExampleActivity : BaseGestureDetectorActivity() {
12 |
13 | @SuppressLint("SetTextI18n")
14 | override fun onCreate(savedInstanceState: Bundle?) {
15 | super.onCreate(savedInstanceState)
16 | val binding = DataBindingUtil.setContentView(this, R.layout.layout_full_screen_example_activity)
17 |
18 | binding.includeTitle.tvTitle.text = "FullScreen Api"
19 | binding.btnFullScreen.setOnClickListener {
20 | startActivity(Intent(this, FullScreenActivity::class.java))
21 | }
22 |
23 | binding.btnImmersion.setOnClickListener {
24 | startActivity(Intent(this, ImmersionActivity::class.java))
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/fullscreen/ImmersionActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.fullscreen
2 |
3 | import android.os.Bundle
4 | import androidx.constraintlayout.widget.ConstraintLayout
5 | import androidx.core.content.ContextCompat
6 | import androidx.core.view.*
7 | import androidx.databinding.DataBindingUtil
8 | import com.chenyihong.exampledemo.R
9 | import com.chenyihong.exampledemo.databinding.LayoutImmersionActivityBinding
10 | import com.chenyihong.exampledemo.androidapi.gesturedetector.BaseGestureDetectorActivity
11 |
12 | class ImmersionActivity : BaseGestureDetectorActivity() {
13 |
14 | private lateinit var windowInsetsController: WindowInsetsControllerCompat
15 |
16 | lateinit var binding: LayoutImmersionActivityBinding
17 |
18 | private var hadChange = false
19 |
20 | override fun onCreate(savedInstanceState: Bundle?) {
21 | super.onCreate(savedInstanceState)
22 | binding = DataBindingUtil.setContentView(this, R.layout.layout_immersion_activity)
23 |
24 | WindowCompat.setDecorFitsSystemWindows(window, false)
25 | windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
26 | //透明的导航栏
27 | windowInsetsController.isAppearanceLightNavigationBars = false
28 |
29 | ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, windowInsets ->
30 | if (!hadChange) {
31 | hadChange = true
32 | val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
33 | //状态栏高度
34 | val statusBarHeight = insets.top
35 | //调整顶部控件的高度
36 | binding.topView.run {
37 | updateLayoutParams {
38 | height += statusBarHeight
39 | }
40 | updatePadding(top = paddingTop + statusBarHeight)
41 | }
42 | binding.tvTitle.run {
43 | updateLayoutParams {
44 | topMargin += statusBarHeight
45 | }
46 | }
47 |
48 | //导航栏高度
49 | val navigationBarHeight = insets.bottom
50 | //调整圆点控件不被导航栏遮挡
51 | binding.bottomView.run {
52 | updateLayoutParams {
53 | bottomMargin += navigationBarHeight
54 | }
55 | }
56 | }
57 | WindowInsetsCompat.CONSUMED
58 | }
59 |
60 | binding.btnChangeToLightBar.setOnClickListener {
61 | lightBar()
62 | }
63 |
64 | binding.btnChangeToDarkBar.setOnClickListener {
65 | darkBar()
66 | }
67 | }
68 |
69 | private fun lightBar() {
70 | binding.topView.setBackgroundColor(ContextCompat.getColor(this, R.color.white))
71 | binding.tvTitle.setTextColor(ContextCompat.getColor(this, R.color.black))
72 | setBarStatus(true)
73 | }
74 |
75 | private fun darkBar() {
76 | binding.topView.setBackgroundColor(ContextCompat.getColor(this, R.color.color_23242a))
77 | binding.tvTitle.setTextColor(ContextCompat.getColor(this, R.color.white))
78 | setBarStatus(false)
79 | }
80 |
81 | private fun setBarStatus(light: Boolean) {
82 | windowInsetsController.isAppearanceLightStatusBars = light
83 | }
84 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/gesturedetector/GestureDetectorAActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.gesturedetector
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Intent
5 | import android.os.Bundle
6 | import androidx.databinding.DataBindingUtil
7 | import com.chenyihong.exampledemo.R
8 | import com.chenyihong.exampledemo.databinding.LayoutGestureDetectorActivityBinding
9 |
10 | class GestureDetectorAActivity : BaseGestureDetectorActivity() {
11 |
12 | @SuppressLint("SetTextI18n")
13 | override fun onCreate(savedInstanceState: Bundle?) {
14 | super.onCreate(savedInstanceState)
15 | val binding = DataBindingUtil.setContentView(this, R.layout.layout_gesture_detector_activity)
16 | binding.tvTitle.text = "Gesture Detector Api"
17 | binding.btnEntrance.setOnClickListener {
18 | startActivity(Intent(this, GestureDetectorBActivity::class.java))
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/gesturedetector/GestureDetectorBActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.gesturedetector
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Bundle
5 | import android.view.View
6 | import androidx.databinding.DataBindingUtil
7 | import com.chenyihong.exampledemo.R
8 | import com.chenyihong.exampledemo.databinding.LayoutGestureDetectorActivityBinding
9 |
10 | class GestureDetectorBActivity : BaseGestureDetectorActivity() {
11 |
12 | @SuppressLint("SetTextI18n")
13 | override fun onCreate(savedInstanceState: Bundle?) {
14 | super.onCreate(savedInstanceState)
15 | val binding = DataBindingUtil.setContentView(this, R.layout.layout_gesture_detector_activity)
16 | binding.tvTitle.text = "Gesture Detector B"
17 | binding.btnEntrance.visibility = View.GONE
18 | }
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/motionlayout/MotionLayoutExampleActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.motionlayout
2 |
3 | import android.os.Bundle
4 | import android.util.Log
5 | import android.view.View
6 | import androidx.constraintlayout.motion.widget.MotionLayout
7 | import androidx.databinding.DataBindingUtil
8 | import com.chenyihong.exampledemo.R
9 | import com.chenyihong.exampledemo.androidapi.gesturedetector.BaseGestureDetectorActivity
10 | import com.chenyihong.exampledemo.databinding.LayoutMotionLayoutExampleActivityBinding
11 |
12 | const val TAG = "MotionLayoutExampleTag"
13 |
14 | class MotionLayoutExampleActivity : BaseGestureDetectorActivity() {
15 |
16 | override fun onCreate(savedInstanceState: Bundle?) {
17 | super.onCreate(savedInstanceState)
18 | val binding: LayoutMotionLayoutExampleActivityBinding = DataBindingUtil.setContentView(this, R.layout.layout_motion_layout_example_activity)
19 | binding.motionLayout.setTransitionListener(object : MotionLayout.TransitionListener {
20 | override fun onTransitionStarted(motionLayout: MotionLayout?, startId: Int, endId: Int) {
21 | Log.i(TAG, "onTransitionStarted startId:$startId, endId:$endId")
22 | // 动画开始
23 | // 把发散的按钮显示出来
24 | binding.ivThumbUp1.visibility = View.VISIBLE
25 | binding.ivThumbUp2.visibility = View.VISIBLE
26 | binding.ivThumbUp3.visibility = View.VISIBLE
27 | binding.ivThumbUp4.visibility = View.VISIBLE
28 | binding.ivThumbUp5.visibility = View.VISIBLE
29 | }
30 |
31 | override fun onTransitionChange(motionLayout: MotionLayout?, startId: Int, endId: Int, progress: Float) {
32 | Log.i(TAG, "onTransitionChange startId:$startId, endId:$endId, progress:$progress")
33 | // 动画进行中
34 | }
35 |
36 | override fun onTransitionCompleted(motionLayout: MotionLayout?, currentId: Int) {
37 | Log.i(TAG, "onTransitionCompleted currentId:$currentId")
38 | // 动画完成
39 | // 隐藏发散的按钮,将状态还原
40 | binding.root.postDelayed({
41 | binding.ivThumbUp1.visibility = View.GONE
42 | binding.ivThumbUp2.visibility = View.GONE
43 | binding.ivThumbUp3.visibility = View.GONE
44 | binding.ivThumbUp4.visibility = View.GONE
45 | binding.ivThumbUp5.visibility = View.GONE
46 | binding.motionLayout.progress = 0f
47 | }, 200)
48 | }
49 |
50 | override fun onTransitionTrigger(motionLayout: MotionLayout?, triggerId: Int, positive: Boolean, progress: Float) {
51 | Log.i(TAG, "onTransitionTrigger triggerId:$triggerId, positive:$positive, progress:$progress")
52 | }
53 | })
54 | }
55 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/resultapi/custom/MultipleLauncherOptions.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.resultapi.custom
2 |
3 | data class MultipleLauncherOptions(val mimeType: String?, val maxCount: Int)
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/resultapi/custom/PickMultipleMediumContract.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.resultapi.custom
2 |
3 | import android.app.Activity
4 | import android.content.Context
5 | import android.content.Intent
6 | import android.net.Uri
7 | import android.os.Build
8 | import android.provider.MediaStore
9 | import androidx.activity.result.contract.ActivityResultContract
10 | import com.chenyihong.exampledemo.base.MimeType
11 |
12 | class PickMultipleMediumContract : ActivityResultContract>() {
13 |
14 | override fun createIntent(context: Context, input: MultipleLauncherOptions?): Intent {
15 | return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
16 | val maxLimit = MediaStore.getPickImagesMaxLimit()
17 | val inputMaxCount = input?.maxCount ?: 0
18 | val finalMaxCount = if (inputMaxCount != 0 && inputMaxCount < maxLimit) inputMaxCount else maxLimit
19 | Intent(MediaStore.ACTION_PICK_IMAGES)
20 | .setType(if (input?.mimeType.isNullOrEmpty() || input?.mimeType.isNullOrBlank()) MimeType.ALL else input?.mimeType)
21 | .putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, finalMaxCount)
22 | } else {
23 | Intent(Intent.ACTION_PICK)
24 | .setType(if (input?.mimeType.isNullOrEmpty() || input?.mimeType.isNullOrBlank()) MimeType.ALL else input?.mimeType)
25 | .putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
26 | }
27 | }
28 |
29 | override fun parseResult(resultCode: Int, intent: Intent?): List {
30 | return if (intent == null || resultCode != Activity.RESULT_OK) {
31 | emptyList()
32 | } else {
33 | getClipDataUris(intent)
34 | }
35 | }
36 |
37 | private fun getClipDataUris(intent: Intent): List {
38 | val resultSet = LinkedHashSet()
39 | intent.data?.let { resultSet.add(it) }
40 | val clipData = intent.clipData
41 | if (clipData == null && resultSet.isEmpty()) {
42 | return emptyList()
43 | } else if (clipData != null) {
44 | for (i in 0 until clipData.itemCount) {
45 | val uri = clipData.getItemAt(i).uri
46 | if (uri != null) {
47 | resultSet.add(uri)
48 | }
49 | }
50 | }
51 | return ArrayList(resultSet)
52 | }
53 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/resultapi/custom/PickSingleMediumContract.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.resultapi.custom
2 |
3 | import android.app.Activity
4 | import android.content.Context
5 | import android.content.Intent
6 | import android.net.Uri
7 | import android.os.Build
8 | import android.provider.MediaStore
9 | import androidx.activity.result.contract.ActivityResultContract
10 | import com.chenyihong.exampledemo.base.MimeType
11 |
12 | class PickSingleMediumContract : ActivityResultContract() {
13 |
14 | override fun createIntent(context: Context, input: String?): Intent {
15 | return Intent(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) MediaStore.ACTION_PICK_IMAGES else Intent.ACTION_PICK)
16 | .setType(if (input.isNullOrEmpty() || input.isBlank()) MimeType.ALL else input)
17 | }
18 |
19 | override fun parseResult(resultCode: Int, intent: Intent?): Uri? {
20 | return if (intent == null || resultCode != Activity.RESULT_OK) null else intent.data
21 | }
22 |
23 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/search/RecentSearchProvider.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.search
2 |
3 | import android.content.SearchRecentSuggestionsProvider
4 |
5 | class RecentSearchProvider : SearchRecentSuggestionsProvider() {
6 |
7 | companion object {
8 | const val AUTHORITY = "com.chenyihong.exampledemo.androidapi.search.RecentSearchProvider"
9 | const val MODE: Int = DATABASE_MODE_QUERIES or DATABASE_MODE_2LINES
10 | }
11 |
12 | init {
13 | setupSuggestions(AUTHORITY, MODE)
14 | }
15 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/search/SearchExampleActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.search
2 |
3 | import android.annotation.SuppressLint
4 | import android.app.SearchManager
5 | import android.content.Context
6 | import android.content.Intent
7 | import android.os.Bundle
8 | import androidx.databinding.DataBindingUtil
9 | import com.chenyihong.exampledemo.R
10 | import com.chenyihong.exampledemo.databinding.LayoutSearchExampleActivityBinding
11 | import com.chenyihong.exampledemo.androidapi.gesturedetector.BaseGestureDetectorActivity
12 |
13 | class SearchExampleActivity : BaseGestureDetectorActivity() {
14 |
15 | override fun onSearchRequested(): Boolean {
16 | val appData = Bundle()
17 | appData.putString("gender", "male")
18 | appData.putInt("age", 24)
19 | startSearch(null, false, appData, false)
20 | return true
21 | }
22 |
23 | @SuppressLint("SetTextI18n")
24 | override fun onCreate(savedInstanceState: Bundle?) {
25 | super.onCreate(savedInstanceState)
26 | val binding: LayoutSearchExampleActivityBinding = DataBindingUtil.setContentView(this, R.layout.layout_search_example_activity)
27 | binding.includeTitle.tvTitle.text = "Search Api"
28 | binding.btnSearchView.setOnClickListener { startActivity(Intent(this, SearchActivity::class.java)) }
29 | binding.btnSearchDialog.setOnClickListener { onSearchRequested() }
30 | val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
31 | searchManager.setOnDismissListener {
32 | showToast("Search Dialog dismiss")
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/setting/HelperFragment.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.setting
2 |
3 | import android.os.Bundle
4 | import android.widget.Toast
5 | import androidx.preference.Preference
6 | import androidx.preference.PreferenceCategory
7 | import androidx.preference.PreferenceFragmentCompat
8 |
9 | class HelperFragment : PreferenceFragmentCompat() {
10 |
11 | override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
12 | val context = preferenceManager.context
13 | val screen = preferenceManager.createPreferenceScreen(context)
14 | val qaPreferenceCategory = PreferenceCategory(context)
15 | qaPreferenceCategory.key = "qa"
16 | qaPreferenceCategory.title = "QA"
17 | val qa1Preference = Preference(context)
18 | qa1Preference.key = "qa1"
19 | qa1Preference.title = "How to open Notification"
20 | qa1Preference.summary = "Open system setting"
21 | val qa2Preference = Preference(context)
22 | qa2Preference.key = "qa2"
23 | qa2Preference.title = "How to bind google account"
24 | qa2Preference.summary = "oOpen settings, bind Google login"
25 | screen.addPreference(qaPreferenceCategory)
26 | qaPreferenceCategory.addPreference(qa1Preference)
27 | qaPreferenceCategory.addPreference(qa2Preference)
28 | val contactPreferenceCategory = PreferenceCategory(context)
29 | contactPreferenceCategory.key = "contact"
30 | contactPreferenceCategory.title = "Contact"
31 | val onlineContactPreference = Preference(context)
32 | onlineContactPreference.key = "online_customer"
33 | onlineContactPreference.title = "Online customer"
34 | onlineContactPreference.summary = "Contact online customer service to solve your problem"
35 | onlineContactPreference.setOnPreferenceClickListener {
36 | requireActivity().runOnUiThread { Toast.makeText(requireContext(), "Click online customer", Toast.LENGTH_SHORT).show() }
37 | true
38 | }
39 | val telephoneContactPreference = Preference(context)
40 | telephoneContactPreference.key = "telephone_customer"
41 | telephoneContactPreference.title = "Telephone customer"
42 | telephoneContactPreference.summary = "Contact telephone_contact customer service to solve your problem"
43 | telephoneContactPreference.setOnPreferenceClickListener {
44 | requireActivity().runOnUiThread { Toast.makeText(requireContext(), "Click Telephone customer", Toast.LENGTH_SHORT).show() }
45 | true
46 | }
47 | screen.addPreference(contactPreferenceCategory)
48 | contactPreferenceCategory.addPreference(onlineContactPreference)
49 | contactPreferenceCategory.addPreference(telephoneContactPreference)
50 | preferenceScreen = screen
51 | }
52 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/setting/SettingActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.setting
2 |
3 | import android.os.Bundle
4 | import androidx.databinding.DataBindingUtil
5 | import androidx.lifecycle.lifecycleScope
6 | import androidx.preference.Preference
7 | import androidx.preference.PreferenceFragmentCompat
8 | import com.chenyihong.exampledemo.R
9 | import com.chenyihong.exampledemo.databinding.LayoutSettingActivityBinding
10 | import com.chenyihong.exampledemo.androidapi.gesturedetector.BaseGestureDetectorActivity
11 |
12 | const val TAG = "PreferenceApi"
13 |
14 | class SettingActivity : BaseGestureDetectorActivity(), PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
15 |
16 | private lateinit var binding: LayoutSettingActivityBinding
17 |
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 | binding = DataBindingUtil.setContentView(this, R.layout.layout_setting_activity)
21 | ExampleDataStore.coroutineScope = lifecycleScope
22 | supportFragmentManager
23 | .beginTransaction()
24 | .replace(R.id.ct_setting_container, SettingFragment())
25 | .commitAllowingStateLoss()
26 | }
27 |
28 | override fun onPreferenceStartFragment(caller: PreferenceFragmentCompat, pref: Preference): Boolean {
29 | pref.fragment?.let {
30 | val fragment = supportFragmentManager.fragmentFactory.instantiate(classLoader, it)
31 | supportFragmentManager.beginTransaction()
32 | .replace(R.id.ct_setting_container, fragment)
33 | .addToBackStack(null)
34 | .commitAllowingStateLoss()
35 | }
36 | return true
37 | }
38 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/setting/SettingFragment.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.setting
2 |
3 | import android.content.Intent
4 | import android.net.Uri
5 | import android.os.Bundle
6 | import android.provider.Settings
7 | import androidx.preference.Preference
8 | import androidx.preference.Preference.OnPreferenceChangeListener
9 | import androidx.preference.PreferenceFragmentCompat
10 | import androidx.preference.SwitchPreferenceCompat
11 | import com.chenyihong.exampledemo.R
12 |
13 | class SettingFragment : PreferenceFragmentCompat() {
14 |
15 | override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
16 | setPreferencesFromResource(R.xml.example_setting, rootKey)
17 | preferenceManager.preferenceDataStore = ExampleDataStore
18 | val notificationOpenStatus = findPreference("notifications_open_status")
19 | val autoLoginStatus = findPreference("auto_login_enable")
20 | val googleAccountStatus = findPreference("google_account_bind_status")
21 | val facebookAccountStatus = findPreference("facebook_account_bind_status")
22 | findPreference("system_system")?.setOnPreferenceClickListener {
23 | try {
24 | val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
25 | val uri: Uri = Uri.fromParts("package", requireActivity().packageName, null)
26 | intent.data = uri
27 | startActivity(intent)
28 | } catch (e: Exception) {
29 | e.printStackTrace()
30 | }
31 | true
32 | }
33 |
34 | val notificationOpenStatusValue = ExampleDataStore.getBoolean("notifications_open_status", false)
35 | val autoLoginStatusValue = ExampleDataStore.getBoolean("auto_login_enable", false)
36 | val googleAccountStatusValue = ExampleDataStore.getBoolean("google_account_bind_status", false)
37 | val facebookAccountStatusValue = ExampleDataStore.getBoolean("facebook_account_bind_status", false)
38 |
39 | notificationOpenStatus?.isChecked = notificationOpenStatusValue
40 | autoLoginStatus?.isChecked = autoLoginStatusValue
41 | googleAccountStatus?.run {
42 | isChecked = googleAccountStatusValue
43 | onPreferenceChangeListener = OnPreferenceChangeListener { preference, newValue ->
44 | googleAccountStatus.summaryOn = "xxxxx@gmail.com"
45 | true
46 | }
47 | }
48 | facebookAccountStatus?.run {
49 | isChecked = facebookAccountStatusValue
50 | onPreferenceChangeListener = OnPreferenceChangeListener { preference, newValue ->
51 | facebookAccountStatus.summaryOn = "xxxxxxfbaccount"
52 | true
53 | }
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/setting/UserInfoFragment.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.setting
2 |
3 | import android.os.Bundle
4 | import android.text.InputType
5 | import androidx.preference.EditTextPreference
6 | import androidx.preference.Preference
7 | import androidx.preference.PreferenceFragmentCompat
8 | import com.chenyihong.exampledemo.R
9 |
10 | class UserInfoFragment : PreferenceFragmentCompat() {
11 |
12 | override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
13 | setPreferencesFromResource(R.xml.example_user_info, rootKey)
14 | findPreference("user_info_nick_name")?.summaryProvider = Preference.SummaryProvider { preference ->
15 | preference.text ?: "Please enter a nickname"
16 | }
17 | findPreference("user_info_real_name")?.summaryProvider = Preference.SummaryProvider { preference ->
18 | preference.text ?: "Please enter real name"
19 | }
20 | findPreference("user_info_age")?.run {
21 | summaryProvider = Preference.SummaryProvider { preference ->
22 | preference.text ?: "Please enter your age"
23 | }
24 | setOnBindEditTextListener { it.inputType = InputType.TYPE_CLASS_NUMBER }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/shortcuts/CreateCameraShortcutActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.shortcuts
2 |
3 | import android.content.ComponentName
4 | import android.content.Intent
5 | import android.os.Bundle
6 | import androidx.appcompat.app.AppCompatActivity
7 | import androidx.core.content.pm.ShortcutInfoCompat
8 | import androidx.core.content.pm.ShortcutManagerCompat
9 | import androidx.core.graphics.drawable.IconCompat
10 | import androidx.databinding.DataBindingUtil
11 | import com.chenyihong.exampledemo.R
12 | import com.chenyihong.exampledemo.androidapi.camerax.CameraActivity
13 | import com.chenyihong.exampledemo.androidapi.gps.GpsSignalActivity
14 | import com.chenyihong.exampledemo.databinding.LayoutCreateShortcutsActivityBinding
15 |
16 | class CreateCameraShortcutActivity : AppCompatActivity() {
17 |
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 | val binding: LayoutCreateShortcutsActivityBinding = DataBindingUtil.setContentView(this, R.layout.layout_create_shortcuts_activity)
21 | binding.tvTips.text = "Do you want to add the Camera Launcher icon to your home screen?"
22 | binding.btnAddShortcut.setOnClickListener {
23 | createPinShortcuts()
24 | }
25 | binding.btnReject.setOnClickListener {
26 | finish()
27 | }
28 | }
29 |
30 | private fun createPinShortcuts() {
31 | if (ShortcutManagerCompat.isRequestPinShortcutSupported(this)) {
32 | val pinShortcutInfo = ShortcutInfoCompat.Builder(this, "camera")
33 | .setShortLabel(getString(R.string.camera_shortcuts_short_label))
34 | .setLongLabel(getString(R.string.camera_shortcuts_long_label))
35 | .setDisabledMessage(getString(R.string.shortcuts_disable_message))
36 | .setIcon(IconCompat.createWithResource(this, R.drawable.icon_camera))
37 | .setIntent(Intent(Intent.ACTION_VIEW).apply {
38 | component = ComponentName(packageName, CameraActivity::class.java.name)
39 | })
40 | .build()
41 | val pinnedShortcutCallbackIntent = ShortcutManagerCompat.createShortcutResultIntent(this, pinShortcutInfo)
42 | setResult(RESULT_OK, pinnedShortcutCallbackIntent)
43 | finish()
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/shortcuts/CreateLocationShortcutActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.shortcuts
2 |
3 | import android.content.ComponentName
4 | import android.content.Intent
5 | import android.os.Bundle
6 | import androidx.appcompat.app.AppCompatActivity
7 | import androidx.core.content.pm.ShortcutInfoCompat
8 | import androidx.core.content.pm.ShortcutManagerCompat
9 | import androidx.core.graphics.drawable.IconCompat
10 | import androidx.databinding.DataBindingUtil
11 | import com.chenyihong.exampledemo.R
12 | import com.chenyihong.exampledemo.androidapi.gps.GpsSignalActivity
13 | import com.chenyihong.exampledemo.databinding.LayoutCreateShortcutsActivityBinding
14 |
15 | class CreateLocationShortcutActivity : AppCompatActivity() {
16 |
17 | override fun onCreate(savedInstanceState: Bundle?) {
18 | super.onCreate(savedInstanceState)
19 | val binding: LayoutCreateShortcutsActivityBinding = DataBindingUtil.setContentView(this, R.layout.layout_create_shortcuts_activity)
20 | binding.tvTips.text = "Do you want to add the Location Launcher icon to your home screen?"
21 | binding.btnAddShortcut.setOnClickListener {
22 | createPinShortcuts()
23 | }
24 | binding.btnReject.setOnClickListener {
25 | finish()
26 | }
27 | }
28 |
29 | private fun createPinShortcuts() {
30 | if (ShortcutManagerCompat.isRequestPinShortcutSupported(this)) {
31 | val pinShortcutInfo = ShortcutInfoCompat.Builder(this, "location")
32 | .setShortLabel(getString(R.string.location_shortcuts_short_label))
33 | .setLongLabel(getString(R.string.location_shortcuts_long_label))
34 | .setDisabledMessage(getString(R.string.shortcuts_disable_message))
35 | .setIcon(IconCompat.createWithResource(this, R.drawable.icon_location))
36 | .setIntent(Intent(Intent.ACTION_VIEW).apply {
37 | component = ComponentName(packageName, GpsSignalActivity::class.java.name)
38 | })
39 | .build()
40 | val pinnedShortcutCallbackIntent = ShortcutManagerCompat.createShortcutResultIntent(this, pinShortcutInfo)
41 | setResult(RESULT_OK, pinnedShortcutCallbackIntent)
42 | finish()
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/toolbar/ToolbarActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.toolbar
2 |
3 | import android.os.Bundle
4 | import android.view.Menu
5 | import android.view.MenuItem
6 | import androidx.databinding.DataBindingUtil
7 | import com.chenyihong.exampledemo.R
8 | import com.chenyihong.exampledemo.databinding.LayoutToolbarActivityBinding
9 | import com.chenyihong.exampledemo.androidapi.gesturedetector.BaseGestureDetectorActivity
10 |
11 | const val TAG = "ToolBalSimpleTag"
12 |
13 | class ToolbarActivity : BaseGestureDetectorActivity() {
14 |
15 | override fun onCreateOptionsMenu(menu: Menu?): Boolean {
16 | menuInflater.inflate(R.menu.example_menu, menu)
17 | return true
18 | }
19 |
20 | override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
21 | // 如果需要在运行时对菜单进行调整(删除或增加),在此处理
22 | return super.onPrepareOptionsMenu(menu)
23 | }
24 |
25 | override fun onOptionsItemSelected(item: MenuItem): Boolean {
26 | // 在此处理菜单项的点击事件
27 | when (item.itemId) {
28 | R.id.action_search -> {
29 | showToast("click search menu")
30 | }
31 | R.id.action_scan -> {
32 | showToast("click scan menu")
33 | }
34 | R.id.action_setting -> {
35 | showToast("click setting menu")
36 | }
37 | }
38 | return super.onOptionsItemSelected(item)
39 | }
40 |
41 | override fun onCreate(savedInstanceState: Bundle?) {
42 | super.onCreate(savedInstanceState)
43 | val binding: LayoutToolbarActivityBinding = DataBindingUtil.setContentView(this, R.layout.layout_toolbar_activity)
44 | setSupportActionBar(binding.toolbar)
45 | supportActionBar?.run {
46 | setHomeAsUpIndicator(R.drawable.icon_back)
47 | setDisplayHomeAsUpEnabled(true)
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/trafficstats/NetSpeedUtils.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.trafficstats
2 |
3 | import android.net.TrafficStats
4 | import com.chenyihong.exampledemo.base.ExampleApplication
5 | import java.util.Timer
6 | import java.util.TimerTask
7 |
8 | object NetSpeedUtils {
9 |
10 | var netSpeedCallback: NetSpeedCallback? = null
11 |
12 | private var timer: Timer? = null
13 | private var timerTask: TimerTask? = null
14 |
15 | private var lastTotalReceiveBytes: Long = 0
16 | private var lastTotalTransferBytes: Long = 0
17 |
18 | /**
19 | * 根据应用uid获取设备启动以来,该应用接收到的总字节数
20 | */
21 | fun getTotalReceiveBytes(): Long {
22 | var receiveBytes: Long = TrafficStats.UNSUPPORTED.toLong()
23 | ExampleApplication.exampleContext?.run {
24 | receiveBytes = TrafficStats.getUidRxBytes(applicationInfo.uid)
25 | }
26 | return if (receiveBytes == TrafficStats.UNSUPPORTED.toLong()) 0 else receiveBytes / 1024
27 | }
28 |
29 | /**
30 | * 根据应用uid获取设备启动以来,该应用传输的总字节数
31 | */
32 | fun getTotalTransferBytes(): Long {
33 | var transferBytes: Long = TrafficStats.UNSUPPORTED.toLong()
34 | ExampleApplication.exampleContext?.run {
35 | transferBytes = TrafficStats.getUidTxBytes(applicationInfo.uid)
36 | }
37 | return if (transferBytes == TrafficStats.UNSUPPORTED.toLong()) 0 else transferBytes / 1024
38 | }
39 |
40 | private fun calculateNetSpeed() {
41 | val nowTotalReceiveBytes = getTotalReceiveBytes()
42 | val nowTotalTransferBytes = getTotalTransferBytes()
43 |
44 | val downloadSpeed = nowTotalReceiveBytes - lastTotalReceiveBytes
45 | val uploadSpeed = nowTotalTransferBytes - lastTotalTransferBytes
46 |
47 | lastTotalReceiveBytes = nowTotalReceiveBytes
48 | lastTotalTransferBytes = nowTotalTransferBytes
49 |
50 | netSpeedCallback?.onNetSpeedChange("$downloadSpeed kb/s", "$uploadSpeed kb/s")
51 | }
52 |
53 | fun startMeasuringNetSpeed() {
54 | if (timer == null && timerTask == null) {
55 | timer = Timer()
56 | timerTask = object : TimerTask() {
57 | override fun run() {
58 | calculateNetSpeed()
59 | }
60 | }
61 | timer?.run { timerTask?.let { schedule(it, 0L, 1000L) } }
62 | }
63 | }
64 |
65 | fun stopMeasuringNetSpeed() {
66 | timerTask?.cancel()
67 | timerTask = null
68 | timer?.cancel()
69 | timer = null
70 | }
71 |
72 | interface NetSpeedCallback {
73 | fun onNetSpeedChange(downloadSpeed: String, uploadSpeed: String)
74 | }
75 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/trafficstats/TrafficStatsActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.trafficstats
2 |
3 | import android.annotation.SuppressLint
4 | import android.graphics.Bitmap
5 | import android.os.Bundle
6 | import android.util.Log
7 | import android.view.ViewGroup
8 | import android.webkit.*
9 | import androidx.databinding.DataBindingUtil
10 | import com.chenyihong.exampledemo.R
11 | import com.chenyihong.exampledemo.androidapi.gesturedetector.BaseGestureDetectorActivity
12 | import com.chenyihong.exampledemo.databinding.LayoutTrafficStatsActivityBinding
13 |
14 | const val TAG = "TrafficStatsTag"
15 |
16 | class TrafficStatsActivity : BaseGestureDetectorActivity() {
17 |
18 | private lateinit var binding: LayoutTrafficStatsActivityBinding
19 |
20 | @SuppressLint("SetTextI18n")
21 | override fun onCreate(savedInstanceState: Bundle?) {
22 | super.onCreate(savedInstanceState)
23 | binding = DataBindingUtil.setContentView(this, R.layout.layout_traffic_stats_activity)
24 | binding.includeTitle.tvTitle.text = "TrafficStatsExample"
25 | NetSpeedUtils.netSpeedCallback = object : NetSpeedUtils.NetSpeedCallback {
26 | override fun onNetSpeedChange(downloadSpeed: String, uploadSpeed: String) {
27 | binding.tvNetSpeed.run { post { text = "downloadSpeed:$downloadSpeed , uploadSpeed:$uploadSpeed" } }
28 | }
29 | }
30 | binding.btnStartMeasureNetSpeed.setOnClickListener {
31 | NetSpeedUtils.startMeasuringNetSpeed()
32 | }
33 | binding.btnStopMeasureNetSpeed.setOnClickListener {
34 | NetSpeedUtils.stopMeasuringNetSpeed()
35 | }
36 | initWebViewSetting(binding.webView)
37 |
38 | binding.webView.loadUrl("https://go.minigame.vip/")
39 | }
40 |
41 | @SuppressLint("JavascriptInterface", "SetJavaScriptEnabled")
42 | private fun initWebViewSetting(webView: WebView?) {
43 | webView?.run {
44 | settings.cacheMode = WebSettings.LOAD_DEFAULT
45 | settings.domStorageEnabled = true
46 | settings.allowContentAccess = true
47 | settings.allowFileAccess = true
48 | settings.useWideViewPort = true
49 | settings.loadWithOverviewMode = true
50 | settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
51 | settings.javaScriptEnabled = true
52 | settings.javaScriptCanOpenWindowsAutomatically = true
53 | settings.setSupportMultipleWindows(true)
54 |
55 | webViewClient = object : WebViewClient() {
56 | override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
57 | super.onPageStarted(view, url, favicon)
58 | Log.i(TAG, "WebViewActivity onPageStarted url:$url")
59 | }
60 |
61 | override fun onPageFinished(view: WebView?, url: String?) {
62 | super.onPageFinished(view, url)
63 | Log.i(TAG, "WebViewActivity onPageFinished view:$view url:$url")
64 | }
65 | }
66 | }
67 | }
68 |
69 | override fun onDestroy() {
70 | super.onDestroy()
71 | binding.webView.clearHistory()
72 | binding.webView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null)
73 | binding.root.run {
74 | if (this is ViewGroup) {
75 | this.removeView(binding.webView)
76 | }
77 | }
78 | binding.webView.destroy()
79 | }
80 |
81 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/wifi/WIFIAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.wifi
2 |
3 | import android.view.LayoutInflater
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import androidx.appcompat.widget.AppCompatImageView
7 | import androidx.appcompat.widget.AppCompatTextView
8 | import androidx.recyclerview.widget.RecyclerView
9 | import com.chenyihong.exampledemo.R
10 |
11 | class WIFIAdapter : RecyclerView.Adapter() {
12 |
13 | private val wifiData = ArrayList()
14 |
15 | var itemClickListener: ItemClickListener? = null
16 |
17 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WIFIViewHolder {
18 | return WIFIViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.layout_wifi_item, parent, false))
19 | }
20 |
21 | override fun onBindViewHolder(holder: WIFIViewHolder, position: Int) {
22 | wifiData[position].run {
23 | holder.tvWifiName.text = wifiSSID
24 | holder.tvWifiSSID.text = wifiBSSID
25 | holder.ivWifiStrength.setImageResource(getStrengthIcon(wifiStrength))
26 | holder.ivNeedPassword.setImageResource(if (needPassword) R.drawable.icon_lock else R.drawable.icon_unlock)
27 | }
28 | holder.itemView.setOnClickListener {
29 | itemClickListener?.onItemClick(wifiData[position])
30 | }
31 | }
32 |
33 | override fun getItemCount(): Int {
34 | return wifiData.size
35 | }
36 |
37 | fun setNewData(wifiData: ArrayList?) {
38 | val lastItemCount = itemCount
39 | if (lastItemCount != 0) {
40 | this.wifiData.clear()
41 | notifyItemRangeRemoved(0, lastItemCount)
42 | }
43 | wifiData?.let { this.wifiData.addAll(it) }
44 | notifyItemChanged(0, itemCount)
45 | }
46 |
47 | private fun getStrengthIcon(wifiStrength: Int): Int {
48 | return when (wifiStrength) {
49 | 0 -> R.drawable.wifi_strength_0
50 | 1 -> R.drawable.wifi_strength_1
51 | 2 -> R.drawable.wifi_strength_2
52 | else -> R.drawable.wifi_strength_3
53 | }
54 | }
55 |
56 | interface ItemClickListener {
57 | fun onItemClick(wifiInfo: WIFIEntity)
58 | }
59 |
60 | class WIFIViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
61 | val tvWifiName: AppCompatTextView = itemView.findViewById(R.id.tv_wifi_name)
62 | val tvWifiSSID: AppCompatTextView = itemView.findViewById(R.id.tv_wifi_ssid)
63 | val ivNeedPassword: AppCompatImageView = itemView.findViewById(R.id.iv_need_password)
64 | val ivWifiStrength: AppCompatImageView = itemView.findViewById(R.id.iv_wifi_strength)
65 | }
66 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/androidapi/wifi/WIFIEntity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.androidapi.wifi
2 |
3 | data class WIFIEntity(
4 | val wifiSSID: String,
5 | val wifiBSSID: String,
6 | val needPassword: Boolean,
7 | val capabilities: String,
8 | val wifiStrength: Int
9 | ) {
10 |
11 | override fun toString(): String {
12 | return "WIFIEntity(wifiSSID='$wifiSSID', wifiBSSID='$wifiBSSID', needPassword=$needPassword, capabilities='$capabilities', wifiStrength=$wifiStrength)"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/base/MimeType.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.base
2 |
3 | object MimeType {
4 |
5 | const val TEXT_PLAIN = "text/plain"
6 | const val TEXT_RTF = "text/rtf"
7 | const val TEXT_HTML = "text/html"
8 | const val TEXT_JSON = "text/json"
9 |
10 | const val IMAGE_HEAD = "image/"
11 | const val IMAGE_JPEG = "image/jpeg"
12 | const val IMAGE_PNG = "image/png"
13 | const val IMAGE_GIT = "image/gif"
14 | const val IMAGE_ALL = "image/*"
15 |
16 | const val VIDEO_HEAD = "video/"
17 | const val VIDEO_MP4 = "video/mp4"
18 | const val VIDEO_3GP = "video/3gp"
19 | const val VIDEO_All = "video/*"
20 |
21 | const val ALL = "*/*"
22 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/customview/CustomChartViewActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.customview
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Bundle
5 | import androidx.databinding.DataBindingUtil
6 | import com.chenyihong.exampledemo.R
7 | import com.chenyihong.exampledemo.databinding.LayoutCustomChartViewActivityBinding
8 | import com.chenyihong.exampledemo.androidapi.gesturedetector.BaseGestureDetectorActivity
9 |
10 | class CustomChartViewActivity : BaseGestureDetectorActivity() {
11 |
12 | @SuppressLint("SetTextI18n")
13 | override fun onCreate(savedInstanceState: Bundle?) {
14 | super.onCreate(savedInstanceState)
15 | val binding: LayoutCustomChartViewActivityBinding = DataBindingUtil.setContentView(this, R.layout.layout_custom_chart_view_activity)
16 | binding.includeTitle.tvTitle.text = "Custom Chart View"
17 | }
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/entity/LineEntity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.entity
2 |
3 | data class LineEntity(
4 | val xValue: Float,
5 | val yValue: Float
6 | )
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/entity/OptionsChildEntity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.entity
2 |
3 | data class OptionsChildEntity(val testFunctionName: String, val testFunction: () -> Unit) {
4 |
5 | override fun toString(): String {
6 | return "OptionsChildEntity(testFunctionName=$testFunctionName, testFunction=$testFunction)"
7 | }
8 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/entity/OptionsEntity.kt:
--------------------------------------------------------------------------------
1 | package com.minigame.testapp.ui.entity
2 |
3 | import com.chenyihong.exampledemo.entity.OptionsChildEntity
4 |
5 | data class OptionsEntity(val moduleName: String, var expanded: Boolean = false, val containerTest: ArrayList) {}
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/entity/PersonEntity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.entity
2 |
3 | import android.os.Parcelable
4 | import kotlinx.parcelize.Parcelize
5 |
6 | @Parcelize
7 | data class PersonEntity(
8 | val name: String,
9 | val age: Int,
10 | val gender: Int,
11 | val weight: Float,
12 | val height: Float
13 | ) : Parcelable {
14 |
15 | override fun toString(): String {
16 | return "PersonEntity(name='$name', age=$age, gender=$gender, weight=$weight, height=$height)"
17 | }
18 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/flavor/FlavorExampleActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.flavor
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Bundle
5 | import androidx.databinding.DataBindingUtil
6 | import com.chenyihong.exampledemo.BuildConfig
7 | import com.chenyihong.exampledemo.R
8 | import com.chenyihong.exampledemo.androidapi.gesturedetector.BaseGestureDetectorActivity
9 | import com.chenyihong.exampledemo.databinding.LayoutFlavorExampleActivityBinding
10 |
11 | class FlavorExampleActivity : BaseGestureDetectorActivity() {
12 |
13 | @SuppressLint("SetTextI18n")
14 | override fun onCreate(savedInstanceState: Bundle?) {
15 | super.onCreate(savedInstanceState)
16 |
17 | val binding = DataBindingUtil.setContentView(this, R.layout.layout_flavor_example_activity)
18 | binding.includeTitle.tvTitle.text = "Flavor ${BuildConfig.FLAVOR}"
19 | binding.tvFlavorBuildConfigValue.text = BuildConfig.example_value
20 | binding.tvFlavorResValue.text = getString(R.string.example_value)
21 | binding.tvVersionInfo.text = "VersionCode:${BuildConfig.VERSION_CODE} VersionName:${BuildConfig.VERSION_NAME}"
22 | }
23 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/tripartite/admob/AppOpenAdActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.tripartite.admob
2 |
3 | import android.content.Intent
4 | import android.os.Bundle
5 | import android.os.Handler
6 | import android.os.Looper
7 | import androidx.appcompat.app.AppCompatActivity
8 | import com.chenyihong.exampledemo.R
9 | import com.chenyihong.exampledemo.base.ExampleApplication
10 | import com.chenyihong.exampledemo.home.HomeActivity
11 |
12 | class AppOpenAdActivity : AppCompatActivity() {
13 |
14 | private val handler = Handler(Looper.myLooper() ?: Looper.getMainLooper())
15 | private val enterRunnable = Runnable {
16 | // 停止自动显示,避免进入主页后自动展示广告打断用户行为
17 | (application as ExampleApplication).appOpenAdManager?.stopAutoShow()
18 | enterHomePage()
19 | }
20 |
21 | override fun onCreate(savedInstanceState: Bundle?) {
22 | super.onCreate(savedInstanceState)
23 | setContentView(R.layout.layout_app_open_activity)
24 | (application as ExampleApplication).appOpenAdManager?.showAppOpenAd(this, object : AppOpenAdManager.AppOpenAdShowCallback {
25 | override fun onAppOpenAdShow() {
26 | // 开屏广告已显示,停止计时线程
27 | handler.removeCallbacks(enterRunnable)
28 | }
29 |
30 | override fun onAppOpenAdShowComplete() {
31 | // 开屏广告播放完毕(成功或失败),停止计时线程并进入主页
32 | handler.removeCallbacks(enterRunnable)
33 | enterHomePage()
34 | }
35 | }, true)
36 | // 三秒内没有显示出广告,自动进入主页
37 | handler.postDelayed(enterRunnable, 3000)
38 | }
39 |
40 | private fun enterHomePage() {
41 | startActivity(Intent(this, HomeActivity::class.java))
42 | finish()
43 | }
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/tripartite/share/TripartiteShareActivity.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.tripartite.share
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.Intent
5 | import android.os.Bundle
6 | import androidx.databinding.DataBindingUtil
7 | import com.chenyihong.exampledemo.R
8 | import com.chenyihong.exampledemo.databinding.LayoutShareActivityBinding
9 | import com.chenyihong.exampledemo.androidapi.gesturedetector.BaseGestureDetectorActivity
10 |
11 | class TripartiteShareActivity : BaseGestureDetectorActivity() {
12 |
13 | @SuppressLint("SetTextI18n")
14 | override fun onCreate(savedInstanceState: Bundle?) {
15 | super.onCreate(savedInstanceState)
16 | val binding = DataBindingUtil.setContentView(this, R.layout.layout_share_activity)
17 |
18 | binding.includeTitle.tvTitle.text = "Tripartite Share"
19 | binding.btnFacebookShare.setOnClickListener {
20 | startActivity(Intent(this, FacebookShareActivity::class.java))
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/utils/DensityUtil.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.utils
2 |
3 | import android.content.res.Resources
4 | import android.util.TypedValue
5 |
6 | object DensityUtil {
7 |
8 | /**
9 | * dp convert to px
10 | *
11 | * @param dpValue dp
12 | */
13 | @JvmStatic
14 | fun dp2Px(dpValue: Int): Int {
15 | return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue.toFloat(), Resources.getSystem().displayMetrics).toInt()
16 | }
17 |
18 | /**
19 | * px convert to dp
20 | *
21 | * @param pxValue px
22 | */
23 | @JvmStatic
24 | fun px2Dp(pxValue: Int): Int {
25 | return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, pxValue.toFloat(), Resources.getSystem().displayMetrics).toInt()
26 | }
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/utils/ShapeDrawableUtils.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.utils
2 |
3 | import android.graphics.drawable.GradientDrawable
4 | import java.util.ArrayList
5 |
6 | object ShapeDrawableUtils {
7 |
8 | /**
9 | * get shape
10 | *
11 | * @param radius corner radius
12 | * @param backgroundColor background color
13 | */
14 | @JvmStatic
15 | fun getRectAngleGradientDrawable(radius: Float, backgroundColor: Int): GradientDrawable {
16 | return getRectAngleGradientDrawable(radius, backgroundColor, 0, 0, true, needRightTopCorner = true, needRightBottomCorner = true, needLeftBottomCorner = true)
17 | }
18 |
19 | /**
20 | * get shape
21 | *
22 | * @param radius corner radius
23 | * @param backgroundColor background color
24 | * @param width view width
25 | * @param height view height
26 | * @param needLeftCorner set left corner or not
27 | * @param needRightCorner set right corner or not
28 | */
29 | @JvmStatic
30 | fun getRectAngleGradientDrawable(radius: Float, backgroundColor: Int, width: Int, height: Int, needLeftCorner: Boolean, needRightCorner: Boolean): GradientDrawable {
31 | return getRectAngleGradientDrawable(radius, backgroundColor, width, height, needLeftCorner, needRightCorner, needRightCorner, needLeftCorner)
32 | }
33 |
34 | /**
35 | * get shape
36 | *
37 | * @param radius corner radius
38 | * @param backgroundColor background color
39 | * @param width view width
40 | * @param height view height
41 | * @param needLeftTopCorner set left top corner or not
42 | * @param needRightTopCorner set right top corner or not
43 | * @param needRightBottomCorner set right bottom corner or not
44 | * @param needLeftBottomCorner set left bottom corner or not
45 | */
46 | @JvmStatic
47 | fun getRectAngleGradientDrawable(radius: Float, backgroundColor: Int, width: Int, height: Int,
48 | needLeftTopCorner: Boolean, needRightTopCorner: Boolean,
49 | needRightBottomCorner: Boolean, needLeftBottomCorner: Boolean): GradientDrawable {
50 | val drawable = GradientDrawable()
51 | drawable.shape = GradientDrawable.RECTANGLE
52 | val radiusArray = ArrayList()
53 | if (needLeftTopCorner) {
54 | radiusArray.add(radius)
55 | radiusArray.add(radius)
56 | } else {
57 | radiusArray.add(0f)
58 | radiusArray.add(0f)
59 | }
60 | if (needRightTopCorner) {
61 | radiusArray.add(radius)
62 | radiusArray.add(radius)
63 | } else {
64 | radiusArray.add(0f)
65 | radiusArray.add(0f)
66 | }
67 | if (needRightBottomCorner) {
68 | radiusArray.add(radius)
69 | radiusArray.add(radius)
70 | } else {
71 | radiusArray.add(0f)
72 | radiusArray.add(0f)
73 | }
74 | if (needLeftBottomCorner) {
75 | radiusArray.add(radius)
76 | radiusArray.add(radius)
77 | } else {
78 | radiusArray.add(0f)
79 | radiusArray.add(0f)
80 | }
81 | val radii = FloatArray(radiusArray.size)
82 | for (i in radiusArray.indices) {
83 | radii[i] = radiusArray[i]
84 | }
85 | drawable.cornerRadii = radii
86 | if (width != 0 && height != 0) {
87 | drawable.setSize(width, height)
88 | }
89 | drawable.setColor(backgroundColor)
90 | return drawable
91 | }
92 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/chenyihong/exampledemo/web/JsInteractive.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo.web
2 |
3 | interface JsInteractive {
4 |
5 | fun jsCallAndroid()
6 |
7 | fun jsCallAndroidWithParams(params: String)
8 |
9 | fun getPersonJsonArray()
10 | }
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_in_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
15 |
16 |
17 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/slide_out_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
15 |
16 |
17 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/facebook.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/facebook.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/google.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/google.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_android.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/icon_android.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_back.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/icon_back.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_biometrics.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/icon_biometrics.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_camera.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/icon_camera.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_juejin.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/icon_juejin.jpeg
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_location.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/icon_location.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_lock.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/icon_lock.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_scan.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/icon_scan.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_scan_32_black.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/icon_scan_32_black.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_search.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/icon_search.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_search_48.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/icon_search_48.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_setting.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/icon_setting.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_thumb_up.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/icon_thumb_up.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon_unlock.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/icon_unlock.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/layer_progress.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 | -
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | -
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/login.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/login.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/notification.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/notification.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_float_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_float_bg1.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_oval.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_red_oval.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_vollume_controller.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/wifi_strength_0.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/wifi_strength_0.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/wifi_strength_1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/wifi_strength_1.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/wifi_strength_2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/wifi_strength_2.webp
--------------------------------------------------------------------------------
/app/src/main/res/drawable/wifi_strength_3.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/drawable/wifi_strength_3.webp
--------------------------------------------------------------------------------
/app/src/main/res/font/noto_sans.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/font/noto_sans_bold.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/font/noto_sanssc_bold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/font/noto_sanssc_bold.otf
--------------------------------------------------------------------------------
/app/src/main/res/font/noto_sanssc_regular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/font/noto_sanssc_regular.otf
--------------------------------------------------------------------------------
/app/src/main/res/font/noto_serif.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/font/noto_serif_bold.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_admob_example_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
12 |
23 |
24 |
34 |
35 |
46 |
47 |
57 |
58 |
68 |
69 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_animatorset_example_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
12 |
13 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_app_open_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_auto_edge_hide_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
12 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_back_press_api_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
12 |
21 |
22 |
30 |
31 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_back_press_api_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
12 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_camera_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
17 |
18 |
27 |
28 |
36 |
37 |
45 |
46 |
54 |
55 |
63 |
64 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_connectivity_example_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
10 |
13 |
14 |
24 |
25 |
35 |
36 |
46 |
47 |
57 |
58 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_create_shortcuts_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
10 |
18 |
19 |
30 |
31 |
42 |
43 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_custom_chart_view_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
12 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_custom_shadow_view_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
12 |
21 |
22 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_facebook_share_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
12 |
21 |
22 |
30 |
31 |
40 |
41 |
49 |
50 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_flavor_example_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
12 |
13 |
22 |
23 |
32 |
33 |
42 |
43 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_fragment_result_api_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
12 |
21 |
22 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_fragment_result_api_dialog_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
18 |
19 |
27 |
28 |
37 |
38 |
47 |
48 |
56 |
57 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_fragment_result_api_fragment_a.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
12 |
21 |
22 |
31 |
32 |
40 |
41 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_fragment_result_api_fragment_b.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
12 |
21 |
22 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_full_screen_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_full_screen_example_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
12 |
21 |
22 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_gaid_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
12 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_gesture_detector_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
18 |
19 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_home_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
12 |
13 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_immersion_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
16 |
17 |
27 |
28 |
38 |
39 |
48 |
49 |
58 |
59 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_options_child_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
17 |
28 |
29 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_options_parent_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
27 |
28 |
34 |
35 |
49 |
50 |
56 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_search_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
21 |
22 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_search_example_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
12 |
21 |
22 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_setting_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_share_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
12 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_system_share_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
12 |
21 |
22 |
30 |
31 |
40 |
41 |
49 |
50 |
59 |
60 |
68 |
69 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_text_content_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
17 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_title.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
10 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_toolbar_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
10 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_traffic_stats_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
12 |
13 |
23 |
24 |
32 |
33 |
41 |
42 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_tripartite_login_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
12 |
22 |
23 |
32 |
33 |
41 |
42 |
50 |
51 |
52 |
62 |
63 |
72 |
73 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_volume_contoller_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
19 |
20 |
29 |
30 |
38 |
39 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_web_view_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
10 |
14 |
15 |
25 |
26 |
36 |
37 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_wifi_example_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
10 |
13 |
14 |
23 |
24 |
32 |
33 |
39 |
40 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_wifi_input_password_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_wifi_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
19 |
20 |
30 |
31 |
40 |
41 |
50 |
51 |
56 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/example_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/example_seach_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/icon_back.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/mipmap-hdpi/icon_back.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/icon_back.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/mipmap-mdpi/icon_back.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/icon_back.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/mipmap-xhdpi/icon_back.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/icon_back.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/mipmap-xxhdpi/icon_back.webp
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/icon_back.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/app/src/main/res/mipmap-xxxhdpi/icon_back.webp
--------------------------------------------------------------------------------
/app/src/main/res/values-night/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
25 |
26 |
38 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | - Male
59 | - Female
60 |
61 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFBB86FC
4 | #FF6200EE
5 | #FF3700B3
6 | #FF03DAC5
7 | #FF018786
8 | #FF000000
9 | #FFFFFFFF
10 |
11 | #1Affffff
12 | #23242A
13 | #C2C7CC
14 | #66808080
15 |
16 | #696464
17 | #808080
18 | #FFD200
19 | #FF2600
20 | #49E284
21 | #00A5FF
22 | #0083FF
23 |
--------------------------------------------------------------------------------
/app/src/main/res/values/font_certs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - @array/com_google_android_gms_fonts_certs_dev
5 | - @array/com_google_android_gms_fonts_certs_prod
6 |
7 |
8 | -
9 | MIIEqDCCA5CgAwIBAgIJANWFuGx90071MA0GCSqGSIb3DQEBBAUAMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAeFw0wODA0MTUyMzM2NTZaFw0zNTA5MDEyMzM2NTZaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBANbOLggKv+IxTdGNs8/TGFy0PTP6DHThvbbR24kT9ixcOd9W+EaBPWW+wPPKQmsHxajtWjmQwWfna8mZuSeJS48LIgAZlKkpFeVyxW0qMBujb8X8ETrWy550NaFtI6t9+u7hZeTfHwqNvacKhp1RbE6dBRGWynwMVX8XW8N1+UjFaq6GCJukT4qmpN2afb8sCjUigq0GuMwYXrFVee74bQgLHWGJwPmvmLHC69EH6kWr22ijx4OKXlSIx2xT1AsSHee70w5iDBiK4aph27yH3TxkXy9V89TDdexAcKk/cVHYNnDBapcavl7y0RiQ4biu8ymM8Ga/nmzhRKya6G0cGw8CAQOjgfwwgfkwHQYDVR0OBBYEFI0cxb6VTEM8YYY6FbBMvAPyT+CyMIHJBgNVHSMEgcEwgb6AFI0cxb6VTEM8YYY6FbBMvAPyT+CyoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJANWFuGx90071MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEBABnTDPEF+3iSP0wNfdIjIz1AlnrPzgAIHVvXxunW7SBrDhEglQZBbKJEk5kT0mtKoOD1JMrSu1xuTKEBahWRbqHsXclaXjoBADb0kkjVEJu/Lh5hgYZnOjvlba8Ld7HCKePCVePoTJBdI4fvugnL8TsgK05aIskyY0hKI9L8KfqfGTl1lzOv2KoWD0KWwtAWPoGChZxmQ+nBli+gwYMzM1vAkP+aayLe0a1EQimlOalO762r0GXO0ks+UeXde2Z4e+8S/pf7pITEI/tP+MxJTALw9QUWEv9lKTk+jkbqxbsh8nfBUapfKqYn0eidpwq2AzVp3juYl7//fKnaPhJD9gs=
10 |
11 |
12 |
13 | -
14 | MIIEQzCCAyugAwIBAgIJAMLgh0ZkSjCNMA0GCSqGSIb3DQEBBAUAMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDAeFw0wODA4MjEyMzEzMzRaFw0zNjAxMDcyMzEzMzRaMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBAKtWLgDYO6IIrgqWbxJOKdoR8qtW0I9Y4sypEwPpt1TTcvZApxsdyxMJZ2JORland2qSGT2y5b+3JKkedxiLDmpHpDsz2WCbdxgxRczfey5YZnTJ4VZbH0xqWVW/8lGmPav5xVwnIiJS6HXk+BVKZF+JcWjAsb/GEuq/eFdpuzSqeYTcfi6idkyugwfYwXFU1+5fZKUaRKYCwkkFQVfcAs1fXA5V+++FGfvjJ/CxURaSxaBvGdGDhfXE28LWuT9ozCl5xw4Yq5OGazvV24mZVSoOO0yZ31j7kYvtwYK6NeADwbSxDdJEqO4k//0zOHKrUiGYXtqw/A0LFFtqoZKFjnkCAQOjgdkwgdYwHQYDVR0OBBYEFMd9jMIhF1Ylmn/Tgt9r45jk14alMIGmBgNVHSMEgZ4wgZuAFMd9jMIhF1Ylmn/Tgt9r45jk14aloXikdjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLR29vZ2xlIEluYy4xEDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNVBAMTB0FuZHJvaWSCCQDC4IdGZEowjTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4IBAQBt0lLO74UwLDYKqs6Tm8/yzKkEu116FmH4rkaymUIE0P9KaMftGlMexFlaYjzmB2OxZyl6euNXEsQH8gjwyxCUKRJNexBiGcCEyj6z+a1fuHHvkiaai+KL8W1EyNmgjmyy8AW7P+LLlkR+ho5zEHatRbM/YAnqGcFh5iZBqpknHf1SKMXFh4dd239FJ1jWYfbMDMy3NS5CTMQ2XFI1MvcyUTdZPErjQfTbQe3aDQsQcafEQPD+nqActifKZ0Np0IS9L9kR/wbNvyz6ENwPiTrjV2KRkEjH78ZMcUQXg0L3BYHJ3lc69Vs5Ddf9uUGGMYldX3WfMBEmh/9iFBDAaTCK
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/values/preloaded_fonts.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - @font/noto_sans
5 | - @font/noto_sans_bold
6 | - @font/noto_serif
7 | - @font/noto_serif_bold
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ExampleDemo
3 | Search information
4 | 905315689902-m8eun8m90h1arir0821797c3drnfu6hc.apps.googleusercontent.com
5 | 692740238633583
6 | fb692740238633583
7 | b13b05e4936981d1fa5843f5685818d1
8 |
9 | This shortcut is disabled
10 |
11 | Camera
12 |
13 | Location
14 |
15 | Using camera
16 | Take pictures or videos with camera
17 |
18 | Using biometrics
19 | Use biometrics for authentication
20 |
21 | Using search
22 | Get content of interest using search
23 |
24 | Using positioning
25 | Get location information by positioning
26 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 |
26 |
27 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/data_extraction_rules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
12 |
13 |
16 |
17 |
20 |
21 |
24 |
25 |
26 |
27 |
28 |
29 |
32 |
33 |
36 |
37 |
40 |
41 |
44 |
45 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/example_setting.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
14 |
15 |
20 |
21 |
25 |
26 |
27 |
30 |
31 |
36 |
37 |
42 |
43 |
48 |
49 |
54 |
55 |
59 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/example_user_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
9 |
12 |
13 |
16 |
17 |
20 |
21 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/file_path.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
9 |
12 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/full_backup_content.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
12 |
15 |
16 |
19 |
20 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/searchable.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/shortcuts.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
13 |
17 |
18 |
19 |
26 |
27 |
31 |
32 |
36 |
37 |
--------------------------------------------------------------------------------
/app/src/test/java/com/chenyihong/exampledemo/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.chenyihong.exampledemo
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 |
4 | repositories {
5 | maven { url 'https://maven.aliyun.com/repository/central' }
6 | maven { url 'https://maven.aliyun.com/repository/google' }
7 | maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
8 |
9 | mavenCentral()
10 | google()
11 | }
12 |
13 | dependencies {
14 | classpath('com.android.tools.build:gradle:8.0.0')
15 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0")
16 |
17 | classpath("com.google.gms:google-services:4.3.15")
18 |
19 | // NOTE: Do not place your application dependencies here; they belong
20 | // in the individual module build.gradle files
21 | }
22 | }
23 |
24 | allprojects {
25 | repositories {
26 | mavenCentral()
27 | google()
28 |
29 | maven { url 'https://maven.aliyun.com/repository/central' }
30 | maven { url 'https://maven.aliyun.com/repository/google' }
31 | }
32 | }
33 |
34 | task clean(type: Delete) {
35 | delete rootProject.buildDir
36 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 | android.nonTransitiveRClass=true
21 | android.defaults.buildfeatures.buildconfig=true
22 | android.nonFinalResIds=true
23 | # Kotlin code style for this project: "official" or "obsolete":
24 | kotlin.code.style=official
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ChenYiHong930921/example-demo/465a7b95acf856a0be0b1611dba8ede5b49285ea/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Apr 18 15:49:50 CST 2023
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = "ExampleDemo"
2 | include ':app'
3 |
--------------------------------------------------------------------------------