| @@ -11,6 +11,8 @@ | |||
| <set> | |||
| <option value="$PROJECT_DIR$" /> | |||
| <option value="$PROJECT_DIR$/app" /> | |||
| <option value="$PROJECT_DIR$/lib" /> | |||
| <option value="$PROJECT_DIR$/lib/common" /> | |||
| </set> | |||
| </option> | |||
| <option name="resolveModulePerSourceSet" value="false" /> | |||
| @@ -4,6 +4,7 @@ | |||
| <option name="filePathToZoomLevelMap"> | |||
| <map> | |||
| <entry key="..\:/Work/XKL/XklLocal/app/src/main/res/layout/activity_fullscreen.xml" value="0.10144927536231885" /> | |||
| <entry key="..\:/Work/XKL/XklLocal/app/src/main/res/layout/activity_main.xml" value="0.1" /> | |||
| </map> | |||
| </option> | |||
| </component> | |||
| @@ -0,0 +1,17 @@ | |||
| gradle 版本管理 | |||
| ext.android : app版本信息 | |||
| ext.version : 依赖包版本信息 | |||
| ext.dependencies_required : 必须的依赖项 | |||
| ext.dependencies_testImplementation : 测试依赖 | |||
| ext.dependencies_androidTestImplementation : 测试依赖 | |||
| ext.dependencies_custom : 自己添加的依赖项,按需定制 | |||
| app: | |||
| module : 按模块进行业务划分 | |||
| common: | |||
| app: 获取application | |||
| base: 存放业务的基础类 | |||
| eventbus: livedata的事件总线 | |||
| util : 工具类,包含Kotlin的扩展属性 | |||
| @@ -2,16 +2,17 @@ plugins { | |||
| id 'com.android.application' | |||
| id 'kotlin-android' | |||
| } | |||
| def androidConfig = rootProject.ext.android | |||
| android { | |||
| compileSdk rootProject.ext.compile_sdk_version | |||
| compileSdk androidConfig.compile_sdk_version | |||
| buildToolsVersion androidConfig.build_tools_version | |||
| defaultConfig { | |||
| applicationId "com.xkl.cdl" | |||
| minSdk 21 | |||
| targetSdk 30 | |||
| versionCode 1 | |||
| versionName "1.0" | |||
| applicationId androidConfig.applicationId | |||
| minSdk androidConfig.min_sdk_version | |||
| targetSdk androidConfig.target_sdk_version | |||
| versionCode androidConfig.version_code | |||
| versionName androidConfig.version_name | |||
| testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | |||
| } | |||
| @@ -60,11 +61,11 @@ android { | |||
| } | |||
| dependencies { | |||
| implementation 'androidx.core:core-ktx:1.3.2' | |||
| implementation 'androidx.appcompat:appcompat:1.2.0' | |||
| implementation 'com.google.android.material:material:1.3.0' | |||
| testImplementation 'junit:junit:4.+' | |||
| androidTestImplementation 'androidx.test.ext:junit:1.1.2' | |||
| androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' | |||
| implementation 'androidx.constraintlayout:constraintlayout:2.0.4' | |||
| implementation 'androidx.legacy:legacy-support-v4:1.0.0' | |||
| rootProject.ext.dependencies_required.each{ k, v -> implementation v} | |||
| testImplementation rootProject.ext.dependencies_testImplementation.junit | |||
| rootProject.ext.dependencies_androidTestImplementation.each{ k,v -> androidTestImplementation v} | |||
| } | |||
| @@ -10,14 +10,11 @@ | |||
| android:supportsRtl="true" | |||
| android:theme="@style/Theme.XklLocal"> | |||
| <activity | |||
| android:name=".FullscreenActivity" | |||
| android:name=".module.main.MainActivity" | |||
| android:configChanges="orientation|keyboardHidden|screenSize" | |||
| android:exported="true" | |||
| android:label="@string/app_name" | |||
| android:theme="@style/Theme.XklLocal.Fullscreen"> | |||
| android:exported="true" > | |||
| <intent-filter> | |||
| <action android:name="android.intent.action.MAIN" /> | |||
| <category android:name="android.intent.category.LAUNCHER" /> | |||
| </intent-filter> | |||
| </activity> | |||
| @@ -1,165 +0,0 @@ | |||
| package com.xkl.cdl | |||
| import androidx.appcompat.app.AppCompatActivity | |||
| import android.annotation.SuppressLint | |||
| import android.os.Build | |||
| import android.os.Bundle | |||
| import android.os.Handler | |||
| import android.view.MotionEvent | |||
| import android.view.View | |||
| import android.view.WindowInsets | |||
| import android.widget.LinearLayout | |||
| import android.widget.TextView | |||
| import com.xkl.cdl.databinding.ActivityFullscreenBinding | |||
| /** | |||
| * An example full-screen activity that shows and hides the system UI (i.e. | |||
| * status bar and navigation/system bar) with user interaction. | |||
| */ | |||
| class FullscreenActivity : AppCompatActivity() { | |||
| private lateinit var binding: ActivityFullscreenBinding | |||
| private lateinit var fullscreenContent: TextView | |||
| private lateinit var fullscreenContentControls: LinearLayout | |||
| private val hideHandler = Handler() | |||
| @SuppressLint("InlinedApi") | |||
| private val hidePart2Runnable = Runnable { | |||
| // Delayed removal of status and navigation bar | |||
| if (Build.VERSION.SDK_INT >= 30) { | |||
| fullscreenContent.windowInsetsController?.hide(WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars()) | |||
| } else { | |||
| // Note that some of these constants are new as of API 16 (Jelly Bean) | |||
| // and API 19 (KitKat). It is safe to use them, as they are inlined | |||
| // at compile-time and do nothing on earlier devices. | |||
| fullscreenContent.systemUiVisibility = | |||
| View.SYSTEM_UI_FLAG_LOW_PROFILE or | |||
| View.SYSTEM_UI_FLAG_FULLSCREEN or | |||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE or | |||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or | |||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or | |||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | |||
| } | |||
| } | |||
| private val showPart2Runnable = Runnable { | |||
| // Delayed display of UI elements | |||
| supportActionBar?.show() | |||
| fullscreenContentControls.visibility = View.VISIBLE | |||
| } | |||
| private var isFullscreen: Boolean = false | |||
| private val hideRunnable = Runnable { hide() } | |||
| /** | |||
| * Touch listener to use for in-layout UI controls to delay hiding the | |||
| * system UI. This is to prevent the jarring behavior of controls going away | |||
| * while interacting with activity UI. | |||
| */ | |||
| private val delayHideTouchListener = View.OnTouchListener { view, motionEvent -> | |||
| when (motionEvent.action) { | |||
| MotionEvent.ACTION_DOWN -> if (AUTO_HIDE) { | |||
| delayedHide(AUTO_HIDE_DELAY_MILLIS) | |||
| } | |||
| MotionEvent.ACTION_UP -> view.performClick() | |||
| else -> { | |||
| } | |||
| } | |||
| false | |||
| } | |||
| @SuppressLint("ClickableViewAccessibility") | |||
| override fun onCreate(savedInstanceState: Bundle?) { | |||
| super.onCreate(savedInstanceState) | |||
| binding = ActivityFullscreenBinding.inflate(layoutInflater) | |||
| setContentView(binding.root) | |||
| supportActionBar?.setDisplayHomeAsUpEnabled(true) | |||
| isFullscreen = true | |||
| // Set up the user interaction to manually show or hide the system UI. | |||
| fullscreenContent = binding.fullscreenContent | |||
| fullscreenContent.setOnClickListener { toggle() } | |||
| fullscreenContentControls = binding.fullscreenContentControls | |||
| // Upon interacting with UI controls, delay any scheduled hide() | |||
| // operations to prevent the jarring behavior of controls going away | |||
| // while interacting with the UI. | |||
| binding.dummyButton.setOnTouchListener(delayHideTouchListener) | |||
| } | |||
| override fun onPostCreate(savedInstanceState: Bundle?) { | |||
| super.onPostCreate(savedInstanceState) | |||
| // Trigger the initial hide() shortly after the activity has been | |||
| // created, to briefly hint to the user that UI controls | |||
| // are available. | |||
| delayedHide(100) | |||
| } | |||
| private fun toggle() { | |||
| if (isFullscreen) { | |||
| hide() | |||
| } else { | |||
| show() | |||
| } | |||
| } | |||
| private fun hide() { | |||
| // Hide UI first | |||
| supportActionBar?.hide() | |||
| fullscreenContentControls.visibility = View.GONE | |||
| isFullscreen = false | |||
| // Schedule a runnable to remove the status and navigation bar after a delay | |||
| hideHandler.removeCallbacks(showPart2Runnable) | |||
| hideHandler.postDelayed(hidePart2Runnable, UI_ANIMATION_DELAY.toLong()) | |||
| } | |||
| private fun show() { | |||
| // Show the system bar | |||
| if (Build.VERSION.SDK_INT >= 30) { | |||
| fullscreenContent.windowInsetsController?.show(WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars()) | |||
| } else { | |||
| fullscreenContent.systemUiVisibility = | |||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or | |||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | |||
| } | |||
| isFullscreen = true | |||
| // Schedule a runnable to display UI elements after a delay | |||
| hideHandler.removeCallbacks(hidePart2Runnable) | |||
| hideHandler.postDelayed(showPart2Runnable, UI_ANIMATION_DELAY.toLong()) | |||
| } | |||
| /** | |||
| * Schedules a call to hide() in [delayMillis], canceling any | |||
| * previously scheduled calls. | |||
| */ | |||
| private fun delayedHide(delayMillis: Int) { | |||
| hideHandler.removeCallbacks(hideRunnable) | |||
| hideHandler.postDelayed(hideRunnable, delayMillis.toLong()) | |||
| } | |||
| companion object { | |||
| /** | |||
| * Whether or not the system UI should be auto-hidden after | |||
| * [AUTO_HIDE_DELAY_MILLIS] milliseconds. | |||
| */ | |||
| private const val AUTO_HIDE = true | |||
| /** | |||
| * If [AUTO_HIDE] is set, the number of milliseconds to wait after | |||
| * user interaction before hiding the system UI. | |||
| */ | |||
| private const val AUTO_HIDE_DELAY_MILLIS = 3000 | |||
| /** | |||
| * Some older devices needs a small delay between UI widget updates | |||
| * and a change of the status and navigation bar. | |||
| */ | |||
| private const val UI_ANIMATION_DELAY = 300 | |||
| } | |||
| } | |||
| @@ -1,51 +0,0 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||
| xmlns:tools="http://schemas.android.com/tools" | |||
| android:layout_width="match_parent" | |||
| android:layout_height="match_parent" | |||
| android:background="?attr/fullscreenBackgroundColor" | |||
| android:theme="@style/ThemeOverlay.XklLocal.FullscreenContainer" | |||
| tools:context=".FullscreenActivity"> | |||
| <!-- The primary full-screen view. This can be replaced with whatever view | |||
| is needed to present your content, e.g. VideoView, SurfaceView, | |||
| TextureView, etc. --> | |||
| <TextView | |||
| android:id="@+id/fullscreen_content" | |||
| android:layout_width="match_parent" | |||
| android:layout_height="match_parent" | |||
| android:gravity="center" | |||
| android:keepScreenOn="true" | |||
| android:text="@string/dummy_content" | |||
| android:textColor="?attr/fullscreenTextColor" | |||
| android:textSize="50sp" | |||
| android:textStyle="bold" /> | |||
| <!-- This FrameLayout insets its children based on system windows using | |||
| android:fitsSystemWindows. --> | |||
| <FrameLayout | |||
| android:layout_width="match_parent" | |||
| android:layout_height="match_parent" | |||
| android:fitsSystemWindows="true"> | |||
| <LinearLayout | |||
| android:id="@+id/fullscreen_content_controls" | |||
| style="@style/Widget.Theme.XklLocal.ButtonBar.Fullscreen" | |||
| android:layout_width="match_parent" | |||
| android:layout_height="wrap_content" | |||
| android:layout_gravity="bottom|center_horizontal" | |||
| android:orientation="horizontal" | |||
| tools:ignore="UselessParent"> | |||
| <Button | |||
| android:id="@+id/dummy_button" | |||
| style="?android:attr/buttonBarButtonStyle" | |||
| android:layout_width="0dp" | |||
| android:layout_height="wrap_content" | |||
| android:layout_weight="1" | |||
| android:text="@string/dummy_button" /> | |||
| </LinearLayout> | |||
| </FrameLayout> | |||
| </FrameLayout> | |||
| @@ -13,9 +13,4 @@ | |||
| <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item> | |||
| <!-- Customize your theme here. --> | |||
| </style> | |||
| <style name="ThemeOverlay.XklLocal.FullscreenContainer" parent=""> | |||
| <item name="fullscreenBackgroundColor">@color/light_blue_900</item> | |||
| <item name="fullscreenTextColor">@color/light_blue_A400</item> | |||
| </style> | |||
| </resources> | |||
| @@ -2,4 +2,6 @@ | |||
| <string name="app_name">XklLocal</string> | |||
| <string name="dummy_button">Dummy Button</string> | |||
| <string name="dummy_content">DUMMY\nCONTENT</string> | |||
| <!-- TODO: Remove or change this placeholder text --> | |||
| <string name="hello_blank_fragment">Hello blank fragment</string> | |||
| </resources> | |||
| @@ -1,11 +1,3 @@ | |||
| <resources> | |||
| <style name="Widget.Theme.XklLocal.ActionBar.Fullscreen" parent="Widget.AppCompat.ActionBar"> | |||
| <item name="android:background">@color/black_overlay</item> | |||
| </style> | |||
| <style name="Widget.Theme.XklLocal.ButtonBar.Fullscreen" parent=""> | |||
| <item name="android:background">@color/black_overlay</item> | |||
| <item name="android:buttonBarStyle">?android:attr/buttonBarStyle</item> | |||
| </style> | |||
| </resources> | |||
| @@ -14,14 +14,4 @@ | |||
| <!-- Customize your theme here. --> | |||
| </style> | |||
| <style name="Theme.XklLocal.Fullscreen" parent="Theme.XklLocal"> | |||
| <item name="android:actionBarStyle">@style/Widget.Theme.XklLocal.ActionBar.Fullscreen</item> | |||
| <item name="android:windowActionBarOverlay">true</item> | |||
| <item name="android:windowBackground">@null</item> | |||
| </style> | |||
| <style name="ThemeOverlay.XklLocal.FullscreenContainer" parent=""> | |||
| <item name="fullscreenBackgroundColor">@color/light_blue_600</item> | |||
| <item name="fullscreenTextColor">@color/light_blue_A200</item> | |||
| </style> | |||
| </resources> | |||
| @@ -19,5 +19,38 @@ task clean(type: Delete) { | |||
| //在项目级别定义某些属性并在所有模块之间共享这些属性 | |||
| ext { | |||
| compile_sdk_version = 30 //使用rootProject.ext.compile_sdk_version | |||
| android = [ | |||
| compile_sdk_version: 30, //使用rootProject.ext.android.compile_sdk_version | |||
| build_tools_version: "30.0.2", | |||
| min_sdk_version : 21, | |||
| target_sdk_version : 30, | |||
| version_code : 100, | |||
| version_name : "100", | |||
| applicationId : "com.xkl.cdl" | |||
| ] | |||
| versions = [ | |||
| core_ktx_version : "1.3.2", | |||
| appcompat_version: "1.2.0", | |||
| material_version : "1.3.0", | |||
| ] | |||
| //必须依赖 | |||
| dependencies_required = [ | |||
| //为属于Android框架的通用库提供扩展程序 | |||
| core_ktx : "androidx.core:core-ktx:${versions.core_ktx_version}", | |||
| //Androidx 依赖 | |||
| appcompat: "androidx.appcompat:appcompat:${versions.appcompat_version}", | |||
| //material_design | |||
| material : "com.google.android.material:material:${versions.material_version}", | |||
| ] | |||
| dependencies_testImplementation = [ | |||
| junit: "junit:junit:4.+" | |||
| ] | |||
| dependencies_androidTestImplementation = [ | |||
| test_ext_junit : "androidx.test.ext:junit:1.1.2", | |||
| test_espresson_core: "androidx.test.espresso:espresso-core:3.3.0" | |||
| ] | |||
| //按需依赖项 | |||
| dependencies_custom = [] | |||
| } | |||
| @@ -9,3 +9,4 @@ dependencyResolutionManagement { | |||
| } | |||
| rootProject.name = "XklLocal" | |||
| include ':app' | |||
| include ':lib:common' | |||