Browse Source

base

master
suliang 2 years ago
parent
commit
6cb51f74c1
32 changed files with 615 additions and 275 deletions
  1. 1
    0
      .idea/gradle.xml
  2. 2
    0
      .idea/misc.xml
  3. 4
    0
      ProjectErrors.md
  4. 2
    0
      README.md
  5. 55
    23
      app/build.gradle
  6. 6
    2
      app/src/main/AndroidManifest.xml
  7. 1
    1
      app/src/main/java/com/xkl/cdl/module/m_center_learn/LearnCenterFragment.kt
  8. 1
    1
      app/src/main/java/com/xkl/cdl/module/m_memo/MemoFragment.kt
  9. 1
    1
      app/src/main/java/com/xkl/cdl/module/m_my/MyFragment.kt
  10. 1
    1
      app/src/main/java/com/xkl/cdl/module/m_statics/StaticsFragment.kt
  11. 46
    0
      app/src/main/java/com/xkl/cdl/module/splash/SplashActivity.kt
  12. BIN
      app/src/main/res/drawable/illustration_splash.png
  13. 12
    0
      app/src/main/res/drawable/theme_splash_bg.xml
  14. 40
    0
      app/src/main/res/layout/activity_splash.xml
  15. 1
    1
      app/src/main/res/layout/fragment_learn_center.xml
  16. 1
    1
      app/src/main/res/layout/fragment_memo.xml
  17. 1
    1
      app/src/main/res/layout/fragment_my.xml
  18. 1
    1
      app/src/main/res/layout/fragment_statics.xml
  19. BIN
      app/src/main/res/mipmap-xxxhdpi/splash_logo.png
  20. 26
    10
      app/src/main/res/values/themes.xml
  21. 31
    8
      build.gradle
  22. 38
    5
      lib/common/build.gradle
  23. 52
    18
      lib/common/src/main/java/com/suliang/common/base/activity/BaseActivity.kt
  24. 25
    0
      lib/common/src/main/java/com/suliang/common/base/activity/BaseActivityVM.kt
  25. 129
    0
      lib/common/src/main/java/com/suliang/common/base/adapter/BaseAdapter.kt
  26. 6
    0
      lib/common/src/main/java/com/suliang/common/base/adapter/BaseAdapterViewHolder.kt
  27. 33
    1
      lib/common/src/main/java/com/suliang/common/base/fragment/BaseFragment.kt
  28. 17
    0
      lib/common/src/main/java/com/suliang/common/base/fragment/BaseFragmentVM.kt
  29. 36
    0
      lib/common/src/main/java/com/suliang/common/extension/BindingExtension.kt
  30. 44
    0
      lib/common/src/main/java/com/suliang/common/util/ActivityStackManager.kt
  31. 0
    200
      lib/common/src/main/java/com/suliang/common/util/Constants.kt
  32. 2
    0
      settings.gradle

+ 1
- 0
.idea/gradle.xml View File

@@ -7,6 +7,7 @@
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="Embedded JDK" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />

+ 2
- 0
.idea/misc.xml View File

@@ -3,8 +3,10 @@
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
<entry key="..\:/Work/XKL/XklLocal/app/src/main/res/drawable/theme_splash_bg.xml" value="0.22" />
<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" />
<entry key="..\:/Work/XKL/XklLocal/app/src/main/res/layout/activity_splash.xml" value="0.1" />
</map>
</option>
</component>

+ 4
- 0
ProjectErrors.md View File

@@ -0,0 +1,4 @@
项目中遇到的错误:
使用jectPack时的依赖:
· androidx.appcompat: appcompat 依赖中已经带了livedata、viewmodel等,可以不用再依赖,再依赖时出现了异常编译错误,未解决
且 依赖版本不同,对应的livedata等版本也不同

+ 2
- 0
README.md View File

@@ -7,6 +7,8 @@ ext.dependencies_testImplementation : 测试依赖
ext.dependencies_androidTestImplementation : 测试依赖
ext.dependencies_custom : 自己添加的依赖项,按需定制

androidx.appcompat:appcompat 自带jetpack中的lifecycle、viewmodel、livedata

app:
module : 按模块进行业务划分


+ 55
- 23
app/build.gradle View File

@@ -1,6 +1,7 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
}
def androidConfig = rootProject.ext.android
android {
@@ -26,27 +27,27 @@ android {

//配置产品变种 与 构建变体
//flavorDimensions :变种维度
flavorDimensions "version"
productFlavors{ //产品变种
demo{
dimension "version"
//applicationId后追加 .demo 也可以重新定义applicationId 属性
applicationIdSuffix ".demo"
versionNameSuffix "-demo"
}
full {
dimension "version"
applicationIdSuffix ".full"
versionNameSuffix '-full'
}
}
// flavorDimensions "version"
// productFlavors{ //产品变种
// demo{
// dimension "version"
// //applicationId后追加 .demo 也可以重新定义applicationId 属性
// applicationIdSuffix ".demo"
// versionNameSuffix "-demo"
// }
// full {
// dimension "version"
// applicationIdSuffix ".full"
// versionNameSuffix '-full'
// }
// }
//变体过滤器
variantFilter { variant ->
def names = variant.flavors*.name
if (name.contains("demo")){
setIgnore(true)
}
}
// variantFilter { variant ->
// def names = variant.flavors*.name
// if (name.contains("demo")){
// setIgnore(true)
// }
// }

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
@@ -57,15 +58,46 @@ android {
}
buildFeatures {
viewBinding true
dataBinding true
}
}

dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation project(path: ':lib:common')
rootProject.ext.dependencies_required.each{ k, v -> implementation v}
testImplementation rootProject.ext.dependencies_testImplementation.junit
rootProject.ext.dependencies_androidTestImplementation.each{ k,v -> androidTestImplementation v}
// kapt rootProject.ext.dependencies_kapt.lifecycle_compiler
def lifecycle_version = "2.5.0-alpha02"
def arch_version = "2.1.0"
//
// // ViewModel
// implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// // ViewModel utilities for Compose
// implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
// // LiveData
// implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// // Lifecycles only (without ViewModel or LiveData)
// implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
//
// // Saved state module for ViewModel
// implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
//
// // Annotation processor
//// kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// // alternately - if using Java8, use the following instead of lifecycle-compiler
// implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// // optional - helpers for implementing LifecycleOwner in a Service
// implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
//
// // optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
// implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
//
// // optional - ReactiveStreams support for LiveData
// implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version"
//
// // optional - Test helpers for LiveData
// testImplementation "androidx.arch.core:core-testing:$arch_version"

}

+ 6
- 2
app/src/main/AndroidManifest.xml View File

@@ -10,14 +10,18 @@
android:supportsRtl="true"
android:theme="@style/Theme.XklLocal">
<activity
android:name=".module.main.MainActivity"
android:name=".module.splash.SplashActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:exported="true" >
android:exported="true"
android:theme="@style/Theme.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".module.main.MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize"/>
</application>

</manifest>

app/src/main/java/com/xkl/cdl/module/center_learn/LearnCenterFragment.kt → app/src/main/java/com/xkl/cdl/module/m_center_learn/LearnCenterFragment.kt View File

@@ -1,4 +1,4 @@
package com.xkl.cdl.module.center_learn
package com.xkl.cdl.module.m_center_learn

import android.os.Bundle
import androidx.fragment.app.Fragment

app/src/main/java/com/xkl/cdl/module/memo/MemoFragment.kt → app/src/main/java/com/xkl/cdl/module/m_memo/MemoFragment.kt View File

@@ -1,4 +1,4 @@
package com.xkl.cdl.module.memo
package com.xkl.cdl.module.m_memo

import android.os.Bundle
import androidx.fragment.app.Fragment

app/src/main/java/com/xkl/cdl/module/my/MyFragment.kt → app/src/main/java/com/xkl/cdl/module/m_my/MyFragment.kt View File

@@ -1,4 +1,4 @@
package com.xkl.cdl.module.my
package com.xkl.cdl.module.m_my

import android.os.Bundle
import androidx.fragment.app.Fragment

app/src/main/java/com/xkl/cdl/module/statics/StaticsFragment.kt → app/src/main/java/com/xkl/cdl/module/m_statics/StaticsFragment.kt View File

@@ -1,4 +1,4 @@
package com.xkl.cdl.module.statics
package com.xkl.cdl.module.m_statics

import android.os.Bundle
import androidx.fragment.app.Fragment

+ 46
- 0
app/src/main/java/com/xkl/cdl/module/splash/SplashActivity.kt View File

@@ -0,0 +1,46 @@
package com.xkl.cdl.module.splash

import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import androidx.databinding.ObservableField
import com.suliang.common.base.activity.BaseActivity
import com.xkl.cdl.databinding.ActivitySplashBinding

class SplashActivity : BaseActivity<ActivitySplashBinding>() {

val textvalue = ObservableField<String>()

private val handler = object : Handler(Looper.getMainLooper()){
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
binding.text.text = textvalue.get()
}
}

override fun onCreate(savedInstanceState: Bundle?) {
if(!isTaskRoot){
finish()
return
}
super.onCreate(savedInstanceState)
}
var count = 1

override fun initActivity(savedInstanceState: Bundle?) {

val x = Tvalue(textvalue)
binding.name = x

handler.postDelayed(object : Runnable{
override fun run() {
count ++
textvalue.set("$count")
handler.postDelayed(this,1000)
}
},1000)

}
}
data class Tvalue(val value : ObservableField<String>)

BIN
app/src/main/res/drawable/illustration_splash.png View File


+ 12
- 0
app/src/main/res/drawable/theme_splash_bg.xml View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item android:drawable="@color/white"/>

<item android:gravity="center" android:bottom="100dp">
<bitmap
android:src="@mipmap/splash_logo"
android:scaleType="centerInside"/>
</item>

</layer-list>

+ 40
- 0
app/src/main/res/layout/activity_splash.xml View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>
<variable
name="name"
type="com.xkl.cdl.module.splash.Tvalue" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.splash.SplashActivity">

<ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintVertical_bias="0.6"
app:layout_constraintDimensionRatio="1125:813"
android:src="@drawable/illustration_splash"
/>
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@={name.value}"
android:textSize="18dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

+ 1
- 1
app/src/main/res/layout/fragment_learn_center.xml View File

@@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.center_learn.LearnCenterFragment">
tools:context=".module.m_center_learn.LearnCenterFragment">

<!-- TODO: Update blank fragment layout -->
<TextView

+ 1
- 1
app/src/main/res/layout/fragment_memo.xml View File

@@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.memo.MemoFragment">
tools:context=".module.m_memo.MemoFragment">

<!-- TODO: Update blank fragment layout -->
<TextView

+ 1
- 1
app/src/main/res/layout/fragment_my.xml View File

@@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.my.MyFragment">
tools:context=".module.m_my.MyFragment">

<!-- TODO: Update blank fragment layout -->
<TextView

+ 1
- 1
app/src/main/res/layout/fragment_statics.xml View File

@@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".module.statics.StaticsFragment">
tools:context=".module.m_statics.StaticsFragment">

<!-- TODO: Update blank fragment layout -->
<TextView

BIN
app/src/main/res/mipmap-xxxhdpi/splash_logo.png View File


+ 26
- 10
app/src/main/res/values/themes.xml View File

@@ -1,17 +1,33 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.XklLocal" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<style name="Theme.XklLocal" parent="Theme.MaterialComponents.Light.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<item name="colorPrimary">@color/white</item> <!--AppBar背景色-->
<!-- <item name="colorPrimaryVariant">@color/white</item>-->
<item name="colorOnPrimary">@color/black</item>
<!-- &lt;!&ndash; Secondary brand color. &ndash;&gt;-->
<!-- <item name="colorSecondary">@color/white</item>-->
<!-- <item name="colorSecondaryVariant">@color/white</item>-->
<!-- <item name="colorOnSecondary">@color/white</item>-->
<!-- &lt;!&ndash; Status bar color. &ndash;&gt;-->
<item name="android:statusBarColor" tools:targetApi="l">@color/white</item>
<!-- Customize your theme here. -->
<item name="android:textAllCaps">false</item>
<item name="android:windowActionBar">false</item>
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:windowEnableSplitTouch">false</item>
<item name="android:splitMotionEvents">false</item>
<item name="android:windowBackground">@android:color/transparent</item>

</style>

<!--启动页背景图层-->
<style name="Theme.Splash" parent="Theme.XklLocal">
<item name="android:windowBackground">@drawable/theme_splash_bg</item>
</style>

</resources>

+ 31
- 8
build.gradle View File

@@ -3,6 +3,8 @@ buildscript {
repositories {
google()
mavenCentral()

maven { url 'https://jitpack.io' }
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.1"
@@ -20,27 +22,40 @@ task clean(type: Delete) {
//在项目级别定义某些属性并在所有模块之间共享这些属性
ext {
android = [
compile_sdk_version: 30, //使用rootProject.ext.android.compile_sdk_version
compile_sdk_version: 31, //使用rootProject.ext.android.compile_sdk_version
build_tools_version: "30.0.2",
min_sdk_version : 21,
target_sdk_version : 30,
target_sdk_version : 31,
version_code : 100,
version_name : "100",
applicationId : "com.xkl.cdl"
]
versions = [
core_ktx_version : "1.3.2",
appcompat_version: "1.2.0",
appcompat_version: "1.4.1",
material_version : "1.3.0",
lifecycle_version: "2.5.0-alpha02"
]
//必须依赖
dependencies_required = [
//为属于Android框架的通用库提供扩展程序
core_ktx : "androidx.core:core-ktx:${versions.core_ktx_version}",
core_ktx : "androidx.core:core-ktx:${versions.core_ktx_version}",
//Androidx 依赖
appcompat: "androidx.appcompat:appcompat:${versions.appcompat_version}",
appcompat : "androidx.appcompat:appcompat:${versions.appcompat_version}",
//material_design
material : "com.google.android.material:material:${versions.material_version}",
material : "com.google.android.material:material:${versions.material_version}",
//constraintlayout
constraintlayout : "androidx.constraintlayout:constraintlayout:2.0.4",
//lifecycle
// lifecycle : "androidx.lifecycle:lifecycle-runtime-ktx:${versions.lifecycle_version}",
// //lifecycle saved state module for viewmodel
//// lifecycle_viewmodel_savestate: "androidx.lifecycle:lifecycle-viewmodel-savedstate:${versions.lifecycle_version}",
// //ViewModel
// viewmodel : "androidx.lifecycle:lifecycle-viewmodel-ktx:${versions.lifecycle_version}",
// //livedata
// livedata : "androidx.lifecycle:lifecycle-livedata-ktx:${versions.lifecycle_version}",
//java8 lifecycle_compiler
// lifecycle_compiler : "androidx.lifecycle:lifecycle-common-java8:${versions.lifecycle_version}"
]
dependencies_testImplementation = [
junit: "junit:junit:4.+"
@@ -49,8 +64,16 @@ ext {
test_ext_junit : "androidx.test.ext:junit:1.1.2",
test_espresson_core: "androidx.test.espresso:espresso-core:3.3.0"
]
//按需依赖项
dependencies_custom = []
//依赖项
dependencies_custom = [
//设置状态栏和导航栏的框架 https://github.com/Zackratos/UltimateBarX
UltimateBarX: "com.gitee.zackratos:UltimateBarX:0.8.0",
]
//注解
// dependencies_kapt = [
// lifecycle_compiler: "androidx.lifecycle:lifecycle-compiler:${versions.lifecycle_version}",
//
// ]


}

+ 38
- 5
lib/common/build.gradle View File

@@ -30,11 +30,9 @@ android {
kotlinOptions {
jvmTarget = '1.8'
}
viewBinding{
enabled true
}
dataBinding{
enabled true
buildFeatures {
viewBinding true
dataBinding true
}
}

@@ -42,4 +40,39 @@ dependencies {
rootProject.ext.dependencies_required.each{ k,v -> implementation v}
testImplementation rootProject.ext.dependencies_testImplementation.junit
rootProject.ext.dependencies_androidTestImplementation.each{ k,v -> androidTestImplementation v}
// api rootProject.ext.dependencies_custom.UltimateBarX

// kapt rootProject.ext.dependencies_kapt.lifecycle_compiler

def lifecycle_version = "2.5.0-alpha02"
def arch_version = "2.1.0"

// // ViewModel
// implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// // ViewModel utilities for Compose
// implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
// // LiveData
// implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// // Lifecycles only (without ViewModel or LiveData)
// implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
//
// // Saved state module for ViewModel
// implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
//
// // Annotation processor
//// kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// // alternately - if using Java8, use the following instead of lifecycle-compiler
// implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// // optional - helpers for implementing LifecycleOwner in a Service
// implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
//
// // optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
// implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
//
// // optional - ReactiveStreams support for LiveData
// implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version"
//
// // optional - Test helpers for LiveData
// testImplementation "androidx.arch.core:core-testing:$arch_version"

}

+ 52
- 18
lib/common/src/main/java/com/suliang/common/base/activity/BaseActivity.kt View File

@@ -1,48 +1,82 @@
package com.suliang.common.base.activity

import android.os.Bundle
import android.view.LayoutInflater
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.databinding.ViewDataBindingKtx
import java.lang.reflect.Method
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelProviders
import androidx.viewbinding.ViewBinding
import com.suliang.common.extension.initBinding
import com.suliang.common.util.ActivityStackManager
import java.lang.reflect.ParameterizedType

/**
* 基类Activity
*/
abstract class BaseActivity<VB : ViewDataBinding> : AppCompatActivity() {
lateinit var databinding: VB
abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity() {

lateinit var binding: VB

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
addStackManager()
initFirst()
initActivity(savedInstanceState) }

protected open fun initFirst() {
setLayoutBefore()
initBinding()
binding = initBinding(layoutInflater)
setContentView(binding.root)
initStatusBar()
setLayoutAfter()
}


/**
* 状态栏初始化方法
*/
open fun initStatusBar() {
// statusBarOnly {
// fitWindow = true
// color = Color.WHITE
// light = true
// }
}

override fun onDestroy() {
super.onDestroy()
ActivityStackManager.removeActivity(this)
}


private fun addStackManager() {
ActivityStackManager.addActivity(this)
}

/** 布局前操作 : 空实现 */
public fun setLayoutBefore() {
public open fun setLayoutBefore() {

}

/**
* 实例化 binding和 设置布局
* 布局后操作:空实现
*/
private fun initBinding() {
// https://www.jianshu.com/p/e3d2421a0277
// val genericSuperClass = this::class.java.genericSuperclass as ParameterizedType //超类
// val type = genericSuperClass.actualTypeArguments[0].javaClass
// val infate: Method = type.getDeclaredMethod("inflate")
public open fun setLayoutAfter() {

}

/**
* 布局后操作:空实现
* onCreate中给与app中用户的具体实现
* @param savedInstanceState Bundle?
*/
public fun setLayoutAfter() {
abstract fun initActivity(savedInstanceState: Bundle?)

}
// @SuppressWarnings("unchecked")
// fun initBinding(inflater: LayoutInflater): VB {
// val vbClass =
// (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments.filterIsInstance<Class<VB>>()
// val inflate = vbClass[0].getDeclaredMethod("inflate", LayoutInflater::class.java)
// return inflate.invoke(null, inflater) as VB
// }

public abstract fun layoutRes(): Int
}

+ 25
- 0
lib/common/src/main/java/com/suliang/common/base/activity/BaseActivityVM.kt View File

@@ -0,0 +1,25 @@
package com.suliang.common.base.activity

import android.os.Bundle
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModel
import androidx.viewbinding.ViewBinding

/**
* Activity DataBinding 与 ViewModel基类,封装DataBinding和ViewModel
* @property VB : ViewDataBinding
* @property VM: ViewModel
*/
abstract class BaseActivityVM<VB : ViewDataBinding, VM:ViewModel> : BaseActivity<VB>() {

private lateinit var vm : VM

override fun initFirst() {
vm = initViewModel()
super.initFirst()
binding.lifecycleOwner = this
}

abstract fun initViewModel() : VM

}

+ 129
- 0
lib/common/src/main/java/com/suliang/common/base/adapter/BaseAdapter.kt View File

@@ -0,0 +1,129 @@
package com.suliang.common.base.adapter

import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView

abstract class BaseAdapter<T> :
RecyclerView.Adapter<BaseAdapterViewHolder>() {

companion object{
val TYPE_EMPTY = -1
}

//数据源
private var mData: MutableList<T> = mutableListOf<T>()

/** 是否需要显示空布局 */
var needShowEmptyView = false

/**
* 当前位置是否需要显示空布局,主要是为0的时候,这个判断才会有效
* @param position Int
*/
private fun enableEmptyPosition(position:Int): Boolean{
return position == 0 && mData.isEmpty() && needShowEmptyView
}

override fun getItemCount(): Int {
return if (needShowEmptyView && mData.isEmpty()) 1 else mData.size
}

override fun getItemViewType(position: Int): Int {
if (enableEmptyPosition(position)){
return TYPE_EMPTY
}
return super.getItemViewType(position)
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseAdapterViewHolder {
return when(viewType){
TYPE_EMPTY -> coverEmptyViewHolder(parent)
else -> coverViewHolder(parent,viewType)
}
}

override fun onBindViewHolder(holder: BaseAdapterViewHolder, position: Int) {
if (enableEmptyPosition(position)){
onBindEmptyViewHolder(holder)
}else{
onBindVH(holder,position)
}
}

/** 创建空布局的ViewHolder 如果needShowEmpty = false 则可以不创建 */
abstract fun coverEmptyViewHolder(parent: ViewGroup): BaseAdapterViewHolder
/** 空布局的数据绑定 */
abstract fun onBindEmptyViewHolder(holder: BaseAdapterViewHolder)
/** 创建 正常item的 ViewHolder */
abstract fun coverViewHolder(parent: ViewGroup,viewType: Int): BaseAdapterViewHolder
/** 绑定 正常item 的数据 */
abstract fun onBindVH(holder: BaseAdapterViewHolder,position: Int)



/**
* 设置数据,并更新列表
* @param data List<T>?
*/
fun setData(data: MutableList<T>?) {
data?.let { it -> //不为空
mData = it
} ?: let { //为空
mData = mutableListOf()
}
notifyItemRangeChanged(0, mData.size)
}









/**
* 添加单条数据
* @param data T?
* @param position Int?
*/
fun addData(data: T?, position: Int?) {
data?.let {
val size = mData.size
val startPosition = position?.let { it ->
when {
it < 0 -> 0
it >= size -> size
else -> it
}
} ?: size
mData.add(startPosition,data)
notifyItemInserted(startPosition)
notifyItemRangeChanged(startPosition,mData.size + 1)
}
}

/**
* 添加数据集
* @param data List<T>? 数据集
* @param position Int? 添加到指定位置,可空
*/
fun addData(data: List<T>?, position: Int? = null) {
if (!data.isNullOrEmpty()) {
val size = mData.size
val startPosition = position?.let { it ->
when {
it < 0 -> 0
it >= size -> size
else -> it
}
} ?: size
mData.addAll(startPosition, data)
//通知有新的item插入进来了
notifyItemInserted(startPosition)
//范围性更新,直接调用onBindViewHolder
notifyItemRangeChanged(startPosition, mData.size + 1 )
}
}

}

+ 6
- 0
lib/common/src/main/java/com/suliang/common/base/adapter/BaseAdapterViewHolder.kt View File

@@ -0,0 +1,6 @@
package com.suliang.common.base.adapter

import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.RecyclerView

class BaseAdapterViewHolder(binding: ViewDataBinding) : RecyclerView.ViewHolder(binding.root)

+ 33
- 1
lib/common/src/main/java/com/suliang/common/base/fragment/BaseFragment.kt View File

@@ -1,4 +1,36 @@
package com.suliang.common.base.fragment

class BaseFragment {
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import com.suliang.common.extension.initBinding
/**
* Fragment ViewBinding基类,封装ViewDataBinding
* @property VB : ViewDataBinding
* @property VM: ViewModel
*/
abstract class BaseFragment<VB: ViewDataBinding>: Fragment(){
lateinit var binding: VB

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = initBinding(inflater,container)
return super.onCreateView(inflater, container, savedInstanceState)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initFirst()
initFragment()
}

abstract fun initFirst()
abstract fun initFragment()

}

+ 17
- 0
lib/common/src/main/java/com/suliang/common/base/fragment/BaseFragmentVM.kt View File

@@ -0,0 +1,17 @@
package com.suliang.common.base.fragment

import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModel
/**
* Fragment DataBinding 与 ViewModel基类,封装DataBinding和ViewModel
* @property VB : ViewDataBinding
* @property VM: ViewModel
*/
abstract class BaseFragmentVM<VB:ViewDataBinding,VM:ViewModel>:BaseFragment<VB>() {
lateinit var viewModel: VM
override fun initFirst() {
viewModel = initViewModel()
}

abstract fun initViewModel():VM
}

+ 36
- 0
lib/common/src/main/java/com/suliang/common/extension/BindingExtension.kt View File

@@ -0,0 +1,36 @@
package com.suliang.common.extension

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.viewbinding.ViewBinding
import java.lang.reflect.ParameterizedType

/**
* 扩展方法,获取到ViewBinding的子类VB实例,主要用于Activity
* @receiver VB
* @param inflater LayoutInflater
* @param vbPosition Int 在超类泛型中的vb位置
* @return VB
*/
@SuppressWarnings("unchecked")
inline fun <VB : ViewBinding> Any.initBinding(inflater: LayoutInflater,vbPosition:Int = 0): VB {
val vbClass =
(javaClass.genericSuperclass as ParameterizedType).actualTypeArguments.filterIsInstance<Class<VB>>()
val inflate = vbClass[vbPosition].getDeclaredMethod("inflate", LayoutInflater::class.java)
return inflate.invoke(null, inflater) as VB
}

/**
* 扩展方法,获取ViewBinding的实例 主要用于Fragment、ListItem等
* @receiver Any
* @param inflater LayoutInflater
* @param container ViewGroup?
* @param vbPosition Int
* @return VB
*/
@SuppressWarnings("unchecked")
inline fun <VB: ViewBinding> Any.initBinding(inflater: LayoutInflater, container:ViewGroup?,vbPosition:Int = 0):VB{
val vbClass = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments.filterIsInstance<Class<VB>>()
val inflater = vbClass[vbPosition].getDeclaredMethod("inflate",LayoutInflater::class.java,ViewGroup::class.java,Boolean::class.java)
return inflater.invoke(null,inflater,container,false) as VB
}

+ 44
- 0
lib/common/src/main/java/com/suliang/common/util/ActivityStackManager.kt View File

@@ -0,0 +1,44 @@
package com.suliang.common.util

import android.app.Activity
import java.util.*

/**
* Activity 栈管理
*/
object ActivityStackManager {

@Volatile
private var activityStack: Stack<Activity> = Stack()

/**
* 入栈
* @param activity Activity
*/
fun addActivity(activity: Activity) {
activityStack.add(activity)
}

/**
* 出栈
* @param activity Activity
*/
fun removeActivity(activity: Activity) {
activityStack.remove(activity)
}

/**
* 结束指定类名的Activity
* @param cls Class<*>
*/
fun finishActivity(cls: Class<*>) {
run {
activityStack.forEach { activity ->
if (activity.javaClass == cls) {
activity.finish()
return@run
}
}
}
}
}

+ 0
- 200
lib/common/src/main/java/com/suliang/common/util/Constants.kt View File

@@ -1,200 +0,0 @@
package com.suliang.common.util

import java.io.File

/**
* author suliang
* create 2020/12/11 9:43
* Describe: 常量类
*/
object Constants {
const val PLATFORM = "android" //平台
const val YOUTH_VERSION = 1 //青少版
const val CHILDREN_VERSION = 2 //幼儿版


// public static final String ENVIRONMENT_PRODUCTION = "production" ; //正式环境
// public static final String ENVIRONMENT_DEVELOPMENT = "development"; //开发环境
// public static final String ENVIRONMENT_TEST = "test"; //测试环境
const val ACCOUNT = "account"
const val USER_INFO = "userinfo"
const val TOKEN = "token"

/** 默认发音 */
const val DEFAULT_SOUND = "default_sound"

/** 更换fragment中的颜色 */
const val ACTION_NOTIFY_FRAGMENT_SKIN = "notify_skin"

//项目subjectId
const val SUBJECT_ENGLISH: Long = 3 //英语
const val SUBJECT_CHINESE: Long = 1 //语文

//课程类型的coursepack --> categoryId
const val CATEGORY_ENGLISH_WORD: Long = 1 //英语: 单词速记
const val CATEGORY_ENGLISH_SOUNDMARK: Long = 4 //英语: 音标
const val CATEGORY_ENGLISH_SPOKEN: Long = 13 //英语: 口语
const val CATEGORY_CHINESE_COMPOSITION: Long = 2 //语文: 作文
const val CATEGORY_CHINESE_LITERACY: Long = 3 //语文: 识字
const val CATEGORY_CHINESE_PINYIN: Long = 5 //语文: 拼音

//项目的课程类型: course --> typeId
const val COURSE_TYPE_DISCERN = 1 //认读、口语
const val COURSE_TYPE_VOICE = 2 //辨音
const val COURSE_TYPE_SPELL = 3 //拼写
const val COURSE_TYPE_POINTS = 4 //作文知识点
const val COURSE_TYPE_LITERACY = 5 //识字
const val COURSE_TYPE_SOUNDMARK = 6 //音标
const val COURSE_TYPE_PINYIN = 7 //拼音
const val COURSE_TYPE_SPOKEN = 8 //口语

//作文课时类型
const val COMPOSITION_TYPE_VIDEO = 1 //视频
const val COMPOSITION_TYPE_KNOWLEDGE = 2 //知识点学习
const val COMPOSITION_TYPE_EXAM = 3 //知识点测试
const val COMPOSITION_TYPE_READING = 4 //课堂练习
const val COMPOSITION_TYPE_TASK = 5 //课外练习

//口语课时类型
const val SPOKEN_LESSON_TYPE_WORD = 1 //口语词汇
const val SPOKEN_LESSON_TYPE_SENTENCE = 2 //口语句型
const val SPOKEN_LESSON_TYPE_DIALOGUE = 3 //口语对话

//课程包过期信息状态值
const val EXPIRY_NOMAL = 1 //正常态
const val EXPIRY_WILL_OVER = 2 //快过期 小于39天
const val EXPIRY_OVER = 3 //已过期

//课程包内容是否下载状态值
const val CONTENT_NOT_DOWN = 0 //未下载
const val CONTENT_DOWNING = 1 //下载中
const val CONTENT_NOMAL = 2 //正常态(已下载)
val FILE_ENGLISH = "english" + File.separator + "pack" //英语项目包
val FILE_CHINESE = "chinese" + File.separator + "pack" //作文项目包

//课程数据包解压后保存的名称
const val DBFILENAME = "course_data.db"
const val FILE_VOICE = "voice" //音频地址
const val VOICE_COMMON_KONGGE = "kongge.mp3"
const val VOICE_COMMON_MISTAKE = "mistake.mp3"
const val VOICE_COMMON_DI = "di.mp3" //叮咚
const val FILE_UPLOAD_FAIL = "error" //上传失败地址
const val FILE_IMG = "glide" //图片缓存地址

/********发音默认type */
const val SOUND_TYPE_US = 1 //美
const val SOUND_TYPE_UK = 2 //英
const val SOUND_TYPE_CN = 3 //中文
const val TEST_QUEST_TYPE_FIELD = 1 //测试题选项类型 :字段名
const val TEST_QUEST_TYPE_ID = 2 //测试题选项类型: 选项id

// 分组(1:普通测试(词汇测试,不做redis统计关联) 2:章节学前测试 3:章节学后测试 4:学前总测试 5:学后总测试 6:备忘录测试(不做redis统计关联);7:作文知识点测试,8:服务中心的课程测试)
const val TEST_TYPE_NORMAL = 1 //普通测试(词汇测试,不做redis统计关联)
const val TEST_TYPE_BEFORE = 2 //学前测试
const val TEST_TYPE_AFTER = 3 //学后测试
const val TEST_TYPE_BEFORE_TOTAL = 4 //学前总测试
const val TEST_TYPE_AFTER_TOTAL = 5 //学后总测试
const val TEST_TYPE_MEMO = 6 //备忘录测试
const val TEST_TYPE_COMPOSITION = 7 //作文知识点测试
const val TEST_TYPE_SERVICE_CENTER = 8 //服务中心的课程测试
const val TEST_DB_DATA_WORD = 1 // data_word
const val TEST_DB_DATA_EXAM = 2 // data_exam
const val TEST_CORRECT = 1 //答题正确
const val TEST_ERROR = -1 //答题错误
const val TEST_UNANSWER = 0 //答题未答
const val TEST_TO_NEXT_TIME_CORRECT = 500 //认读辨音 正确 0.5秒跳下一题
const val TEST_TO_NEXT_TIME_ERROR = 2000 //认读辨音 答错 2秒
const val TEST_TO_NEXT_TIME_UNANSWER = 2000 //认读辨音 未答 2秒
const val TEST_TO_NEXT_TIME_SPELL = 1500 //辨音错误到下一题需要1.5秒
const val TEST_WORD_COUNT_DOWN_TIME_DISCERN = 6000 //认读单个单词倒计时时间 6秒
const val TEST_WORD_COUNT_DOWN_TIME_SPELL_SINGLE = 1600 //拼写单个单词字母的倒计时时间
const val TEST_WORD_COUNT_DOWN_TOME_COMPOSITION = 15000 //作文测试倒计时时间
const val SCORE_1 = 80 //小于score_1 悲伤
const val SCORE_2 = 90 //大于等于score1 小于 score_2 加油
const val SCORE_SPOKEN_DIALOGUE_1 = 60 //口语对话练习课时后测试通过标准 80以上优秀,中间良好
const val TEST_COUNT_TOTAL = 25 //总测试 50题
const val TEST_COUNT_NORAM = 20 //章节测试 25题
const val TEST_COUNT_VOCABULARY = 100 //词汇量测试

//测试的题目类型
const val TEST_QUEST_TYPE_CHOICE = 1 //选择题
const val TEST_QUEST_TYPE_GAP_FILLING = 2 //填空题
const val TEST_QUEST_TYPE_JUDGE = 3 //判断题
const val TEST_QUEST_TYPE_SPOKEN_DIALOGUE = 4 //口语对话测试

//课时状态
const val LESSON_STATE_NORMAL = 0 //普通状态

// public static final int LESSON_STATE_SELECT = 1 ; //选中状态
const val LESSON_STATE_LOCKED = 1 //锁定状态

//答题左侧按钮状态
const val ANSWER = 0 //答案
const val CORRECT = 1 //正确
const val NEXT = 2 //下一条

//有效时间 : 18秒
const val VALID_TIME: Long = 18000

//最后一课时 虚拟下一课时标记(主要用于判断最后一课时学后测试是否有通过)
const val LAST_LESSON_NEXT_FLAG = "-1_-1"

//学习
const val LEARN_FLAG = 1

//复习
const val REVIEW_FLAG = 2

//拼写中
const val STATE_SPELLING = 1

//纠错中
const val STATE_MODIFYING = 2

//不可操作状态
const val STATE_UNENABLE = 3

//拼写结果: 全对
const val RESULT_ALL_RIGHT = 1

//拼写结果:错误;可容错
const val RESULT_ERROR_CAN_MODIFY = 2

//拼写结果: 错误,无容错
const val RESULT_ERROR = 3

//拼写修改完成
const val RESULT_MODIFY_OVER = 4

// 0: 自己按顺序加载状态页 1复习页 2学前总测页 3 目录页 4学后总测未测 5、学后总测未通过 6、学后总测已通过
const val PAGE_LOADING_NORAML = 0
const val PAGE_LOADING_REVIEW = 1
const val PAGE_LOADING_BEFORE = 2
const val PAGE_LOADING_CATALOG = 3
const val PAGE_LOADING_AFTER_NOT = 4
const val PAGE_LOADING_AFTER_NO_PASS = 5
const val PAGE_LOADING_AFTER_PASS = 6

//收藏类型
const val COMPOSITON_COLLECT_VIDEO_BLACK_BOOK = 1 //收藏类型:视频版本
const val COMPOSITON_COLLECT_READING = 2 //阅读材料

//模块联通通知类型
const val NOTIFY_ENGLISH_REVIEW = 1 //英语有复习
const val NOTIFY_ENGLISH_ERROR = 2 //英语学习有错误
const val NOTIFY_COMPOSITION_REVIEW = 3 //作文有复习
const val NOTIFY_COMPOSITION_ERROR = 4 //作文学习有错误
const val NOTIFY_LEARN_RECORD_CHANGE = 5 //学习记录有变化

//游戏
const val GAME_GAPFILLING = 1 //填空
const val GAME_CHOOSE = 2 //消消乐
const val GAME_TRANSLATE = 3 //翻译排序

//口语自动播放模式
const val SPOKEN_AUTO_PLAY_MODEL = 1 //自动播放模式
const val SPOKEN_AUTO_FLOWER_MODEL = 2 //跟读模式

//收藏本: 句子type 2
const val COLLECT_TYPE_SENTENCE: Long = 2
}

+ 2
- 0
settings.gradle View File

@@ -5,6 +5,8 @@ dependencyResolutionManagement {
google()
mavenCentral()
jcenter() // Warning: this repository is going to shut down soon

maven { url 'https://jitpack.io' }
}
}
rootProject.name = "XklLocal"

Loading…
Cancel
Save