init base

master
yimiao 3 years ago
parent 5a9a10b489
commit d4b6a8a119

1
app/.gitignore vendored

@ -0,0 +1 @@
/build

@ -0,0 +1,40 @@
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.yinuo.commonlibtest"
minSdkVersion 23
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation project(path: ':commonLib')
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

@ -0,0 +1,26 @@
package com.yinuo.commonlibtest;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.yinuo.commonlibtest", appContext.getPackageName());
}
}

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yinuo.commonlibtest">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.CommonLibTest">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

@ -0,0 +1,14 @@
package com.yinuo.commonlibtest;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

@ -0,0 +1,16 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.CommonLibTest" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_200</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/black</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_200</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>

@ -0,0 +1,3 @@
<resources>
<string name="app_name">CommonLibTest</string>
</resources>

@ -0,0 +1,16 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.CommonLibTest" parent="Theme.MaterialComponents.DayNight.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>
<!-- Customize your theme here. -->
</style>
</resources>

@ -0,0 +1,17 @@
package com.yinuo.commonlibtest;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}

@ -0,0 +1,27 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
apply from: "commonLibConfig.gradle"
buildscript {
ext.kotlin_version = "1.5.21"
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:4.2.2"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
mavenCentral()
jcenter() // Warning: this repository is going to shut down soon
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

@ -0,0 +1 @@
/build

@ -0,0 +1,53 @@
plugins {
id 'com.android.library'
id 'kotlin-android'
id 'kotlin-android-extensions'
id 'kotlin-kapt'
}
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
buildToolsVersion rootProject.ext.android.buildToolsVersion
defaultConfig {
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext.android.versionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.navigation:navigation-fragment:2.3.0'
implementation 'androidx.navigation:navigation-ui:2.3.0'
// kotlin
implementation rootProject.ext.dependencies.kotlin
implementation rootProject.ext.dependencies.kotlin_android
//luban
implementation rootProject.ext.dependencies.luban
}

@ -0,0 +1,131 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
# 有了verbose这句话混淆后就会生成映射文件
# 包含有类名->混淆后类名的映射关系
# 然后使用printmapping指定映射文件的名称
-verbose
-printmapping priguardMapping.txt
# 保留所有的本地native方法不被混淆
-keepclasseswithmembernames class * {
native <methods>;
}
# 保护代码中的Annotation不被混淆
# 这在JSON实体映射时非常重要比如fastJson
-keepattributes *Annotation*
# 避免混淆泛型
# 这在JSON实体映射时非常重要比如fastJson
-keepattributes Signature
# 抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable
# 对R文件下的所有类及其方法都不能被混淆
-keepclassmembers class **.R$* {
*;
}
# 保留了继承自ActivityApplication这些类的子类
# 因为这些子类有可能被外部调用
# 比如第一行就保证了所有Activity的子类不要被混淆
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.view.View
# 枚举类不能被混淆
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# 保留自定义控件(继承自View)不能被混淆
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set*(***);
*** get* ();
}
# 保留Parcelable序列化的类不能被混淆
-keep class * implements android.os.Parcelable{
public static final android.os.Parcelable$Creator *;
}
# 保留Serializable 序列化的类不被混淆
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# AndroidX混淆
-keep class com.google.android.material.** {*;}
-keep class androidx.** {*;}
-keep public class * extends androidx.**
-keep interface androidx.** {*;}
-dontwarn com.google.android.material.**
-dontnote com.google.android.material.**
-dontwarn androidx.**
# 保留BaseFragment公共成员和方法不被混淆
-keep class com.yinuo.commonlib.utils.*{*;}
# 保留BaseFragment公共成员和方法不被混淆
-keep class com.yinuo.commonlib.view.fragment.BaseFragment{
public<fields>;
public<methods>;
}
# 保留BaseNavigationFragment公共成员和方法不被混淆
-keep class com.yinuo.commonlib.view.fragment.BaseNavigationFragment{
public<fields>;
public<methods>;
}
# 保留BaseActivity公共成员和方法不被混淆
-keep class com.yinuo.commonlib.view.activity.BaseActivity{
public<fields>;
public<methods>;
}
# 保留CommonTitleView的内部类不被混淆
-keep class com.yinuo.commonlib.view.CommonTitleView$*{
*;
}
# 保留BaseNavigationFragment公共成员和方法不被混淆
-keep class com.yinuo.commonlib.view.SlideRecyclerView{
public<fields>;
public<methods>;
}

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yinuo.commonlib">
</manifest>

@ -0,0 +1,118 @@
package com.yinuo.commonlib.utils
import android.annotation.SuppressLint
import android.content.Context
import android.text.TextUtils
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.ArrayList
object BaseUtils {
private const val TAG: String = "BaseUtils"
/**
* 如果使用大写HH标识使用24小时显示格式,如果使用小写hh就表示使用12小时制格式
*/
const val DATE_TO_STRING_DETAIL_PATTERN = "yyyy-MM-dd HH:mm:ss"
/**
* -- 显示格式
* */
const val DATE_TO_STRING_SHORT_PATTERN = "yyyy.MM.dd"
/**
* -- 显示格式
* */
const val DATE_TO_STRING_LONG_PATTERN = "yyyy_MM_dd HH:mm:ss"
/**
* 60
*/
const val SECONDS = 60
/**
* 60分钟
*/
const val MINUS = 60
fun <T> isListEmpty(list: List<T>?): Boolean {
return list == null || list.isEmpty()
}
@SuppressLint("SimpleDateFormat")
fun getNowTimeFormat(format:String): String {
val formatter = SimpleDateFormat(format)
return formatter.format(getNow())
}
/**
* 得到现在时间
*
* @return
*/
private fun getNow(): Date {
return Date()
}
/**
* 将字符串List转化为用 | 分割的字符串
*/
fun getStringSeparateByLine(list: List<String>): String {
var result = ""
for (item in list.withIndex()) {
result = if (item.index == (list.size - 1)) {
"$result${item.value}"
} else {
"$result${item.value}|"
}
}
return result
}
/**
* | 分割符转化为list
*/
fun getListByString(source: String): List<String> {
if (TextUtils.isEmpty(source)) {
return ArrayList()
}
return source.split("|")
}
/**
* 将int型的数据转化成 XX:XX:XX" 形式的字符串
*/
fun getDurationTimeByInt(source: Int): String {
var temp = source
var h = 0
var m = 0
var s = 0
var result = ""
if (temp >= SECONDS * MINUS) {
h = temp / (SECONDS * MINUS)
temp -= h * (SECONDS * MINUS)
}
if (temp >= SECONDS) {
m = temp / SECONDS
temp -= m * SECONDS
}
s = temp
result = when {
h > 0 -> {
"$h:$m:$s\""
}
m > 0 -> {
"$m:$s\""
}
else -> {
"$s\""
}
}
return result
}
fun getExternalStoragePath(context: Context): String? {
return context.getExternalFilesDir(null)?.path
}
}

@ -0,0 +1,16 @@
package com.yinuo.commonlib.utils
import android.content.Context
object DisplayUtils {
fun dp2px(context: Context, dpVale: Float): Int {
val density = context.resources.displayMetrics.density
return ((dpVale * density + 0.5f).toInt())
}
fun px2dp(context: Context, pxVale: Float): Int {
val density = context.resources.displayMetrics.density
return ((pxVale / density + 0.5f).toInt())
}
}

@ -0,0 +1,111 @@
package com.yinuo.commonlib.utils
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import top.zibin.luban.Luban
import top.zibin.luban.OnCompressListener
import java.io.File
import java.io.FileOutputStream
import java.text.SimpleDateFormat
import java.util.*
object PhotoUtils {
private const val TAG = "PhotoUtils";
/**
* 根据时间生成照片文件
*/
fun generatePhotoFileByTime(context: Context, photoPath: String): File {
val rootPath: String = context.applicationContext.getExternalFilesDir(null)?.path ?: ""
val savePhotoFolderPath: String = rootPath + photoPath
val savePhotoFolder = File(savePhotoFolderPath)
if (!savePhotoFolder.exists()) {
//创建路径,需要权限
savePhotoFolder.mkdirs()
}
val photoName = SimpleDateFormat("yyyy_MM_dd_hh_mm_ss_SSS").format(Date()) + ".png"
return File(savePhotoFolder, photoName)
}
fun initPicPath(context: Context?, photoPath: String): String {
val rootPath: String = context?.getExternalFilesDir(null)?.path ?: ""
val savePhotoFilePath: String = rootPath + photoPath
val file = File(savePhotoFilePath)
if (!file.exists()) {
//创建路径,需要权限
file.mkdirs()
}
val photoName = SimpleDateFormat("yyyy_MM_dd_hh_mm_ss_SSS").format(Date()) + ".png"
return "$savePhotoFilePath/$photoName"
}
/**
* 得到保存图片的文件夹地址
*/
fun getImageParentPath(context: Context, photoPath: String): String {
val rootPath: String = context.getExternalFilesDir(null)?.path ?: ""
val savePhotoFilePath: String = rootPath + photoPath
val file = File(savePhotoFilePath)
if (!file.exists()) {
//创建路径,需要权限
file.mkdirs()
}
return savePhotoFilePath
}
/**
* 压缩图片使用Luban框架压缩处理
*/
fun compressPicture(
context: Context,
file: File,
targetDir: String,
listener: OnCompressListener
) {
Luban.with(context.applicationContext)
.load(file)
.ignoreBy(100)
.setTargetDir(targetDir)
.setCompressListener(listener).launch()
}
/**
*把其他格式的图片转换成png格式的图片耗时操作
* originImageFile原图片文件
* imgSavePath图片要保存的地址/sdcard/0/emulator/data/xxx.xxx.xx/file/test.png
*/
fun tans2PNGSave(originImageFile: File?, imgSavePath: String?, callBack: TransformCallBack) {
GlobalScope.launch(Dispatchers.IO) {
val decodeFile = BitmapFactory.decodeFile(originImageFile?.absolutePath)
var out: FileOutputStream? = null
try {
out = FileOutputStream(File(imgSavePath))
decodeFile.compress(Bitmap.CompressFormat.PNG, 90, out)
out.flush()
out.close()
} catch (e: Exception) {
Log.e(TAG, "tans2PNGSave error==" + e.message)
} finally {
out?.close()
}
GlobalScope.launch(Dispatchers.Main) {
//通知主线程图片保存成功
callBack.onSuccess()
}
}
}
interface TransformCallBack {
fun onSuccess()
fun onError();
}
}

@ -0,0 +1,30 @@
package com.yinuo.commonlib.utils
import android.annotation.SuppressLint
import android.content.Context
import android.content.SharedPreferences
/**
* sharedPreference管理类
*/
object SpManager {
const val HAS_INIT = "has_init"
private var sp: SharedPreferences? = null
private var editor: SharedPreferences.Editor? = null
@SuppressLint("CommitPrefEdits")
fun init(context: Context, name: String, mod: Int) {
sp = context.getSharedPreferences(name, mod)
editor = sp!!.edit()
}
fun putBoolean(key: String, boolean: Boolean) {
editor!!.putBoolean(key, boolean)
editor!!.apply()
}
fun getBoolean(key: String): Boolean {
return sp!!.getBoolean(key, false)
}
}

@ -0,0 +1,233 @@
package com.yinuo.commonlib.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.navigation.Navigation;
import com.yinuo.commonlib.R;
import com.yinuo.commonlib.utils.DisplayUtils;
public class CommonTitleView extends FrameLayout implements View.OnClickListener {
private Context mContext;
private ImageView ivBack;
private TextView tv_title;
private ImageView ivAdd;
private TextView tv_edit;
private int showStyle;
private static final int STYLE_LEFT = 1;
private static final int STYLE_LEFT_MIDDLE = 2;
private static final int STYLE_LEFT_MIDDLE_RIGHT = 3;
private static final int STYLE_MIDDLE = 4;
private static final int STYLE_MIDDLE_RIGHT = 5;
private static final int STYLE_RIGHT = 6;
private static final int STYLE_EDIT = 7;
private String title;
//是否要固定高度的模式不受match parent\warp content等影响
private boolean isFixedHeight;
//设置固定的高度值,默认是48dp
private int fixedHeight;
private static final int DEFAULT_HEIGHT = 48;
private View rlBackHotZone;
private View rlAddHotZone;
private View rlEditZone;
public CommonTitleView(Context context) {
this(context, null);
}
public CommonTitleView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CommonTitleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
init(attrs);
}
private void init(AttributeSet attrs) {
initAttrs(attrs);
LayoutInflater.from(mContext).inflate(R.layout.common_title_view, this, true);
ivBack = findViewById(R.id.iv_back);
ivAdd = findViewById(R.id.iv_add);
tv_title = findViewById(R.id.tv_title);
rlBackHotZone = findViewById(R.id.rl_back_hot_zone);
rlAddHotZone = findViewById(R.id.rl_add_hot_zone);
tv_edit = findViewById(R.id.tv_edit);
rlEditZone = findViewById(R.id.rl_edit_hot_zone);
initStyle();
setTitle(title);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (isFixedHeight) {
int makeMeasureSpec = MeasureSpec.makeMeasureSpec(fixedHeight, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, makeMeasureSpec);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
private void initStyle() {
switch (showStyle) {
case STYLE_LEFT:
ivBack.setVisibility(VISIBLE);
rlBackHotZone.setOnClickListener(this);
tv_title.setVisibility(INVISIBLE);
tv_title.setText("");
ivAdd.setVisibility(INVISIBLE);
rlAddHotZone.setOnClickListener(null);
break;
case STYLE_LEFT_MIDDLE:
ivBack.setVisibility(VISIBLE);
rlBackHotZone.setOnClickListener(this);
tv_title.setVisibility(VISIBLE);
tv_title.setText("");
ivAdd.setVisibility(INVISIBLE);
rlAddHotZone.setOnClickListener(null);
break;
case STYLE_MIDDLE_RIGHT:
ivBack.setVisibility(INVISIBLE);
rlBackHotZone.setOnClickListener(null);
tv_title.setVisibility(VISIBLE);
tv_title.setText("");
ivAdd.setVisibility(VISIBLE);
rlAddHotZone.setOnClickListener(this);
break;
case STYLE_RIGHT:
ivBack.setVisibility(INVISIBLE);
rlBackHotZone.setOnClickListener(null);
tv_title.setVisibility(INVISIBLE);
tv_title.setText("");
ivAdd.setVisibility(VISIBLE);
rlAddHotZone.setOnClickListener(this);
break;
case STYLE_LEFT_MIDDLE_RIGHT:
ivBack.setVisibility(VISIBLE);
rlBackHotZone.setOnClickListener(this);
tv_title.setVisibility(VISIBLE);
tv_title.setText("");
ivAdd.setVisibility(VISIBLE);
rlAddHotZone.setOnClickListener(this);
break;
case STYLE_EDIT:
ivBack.setVisibility(VISIBLE);
rlBackHotZone.setOnClickListener(this);
tv_title.setVisibility(VISIBLE);
tv_title.setText("");
ivAdd.setVisibility(GONE);
rlAddHotZone.setVisibility(GONE);
rlAddHotZone.setOnClickListener(null);
tv_edit.setVisibility(VISIBLE);
rlEditZone.setVisibility(VISIBLE);
rlEditZone.setOnClickListener(this);
break;
case STYLE_MIDDLE:
default:
ivBack.setVisibility(INVISIBLE);
rlBackHotZone.setOnClickListener(null);
tv_title.setVisibility(VISIBLE);
tv_title.setText("");
ivAdd.setVisibility(INVISIBLE);
rlAddHotZone.setOnClickListener(null);
break;
}
}
private void initAttrs(AttributeSet attrs) {
TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.CommonTitleView);
showStyle = typedArray.getInt(R.styleable.CommonTitleView_show_style, STYLE_MIDDLE);
title = typedArray.getString(R.styleable.CommonTitleView_title);
isFixedHeight = typedArray.getBoolean(R.styleable.CommonTitleView_is_fixed_height, true);
fixedHeight = typedArray.getInteger(R.styleable.CommonTitleView_fixed_height, DisplayUtils.INSTANCE.dp2px(mContext, DEFAULT_HEIGHT));
typedArray.recycle();
}
public void setTitle(String title) {
this.title = title;
tv_title.setText(title);
}
@Override
public void onClick(View v) {
int viewId = v.getId();
if (viewId == R.id.rl_back_hot_zone) {
if (backButtonListener != null) {
backButtonListener.onClick();
} else {
Navigation.findNavController(this).navigateUp();
}
} else if (viewId == R.id.rl_add_hot_zone) {
if (addListener != null) {
addListener.onClick();
}
} else if (viewId == R.id.rl_edit_hot_zone) {
if (editListener != null) {
editListener.onClick();
}
}
}
public interface BackButtonListener {
void onClick();
}
private BackButtonListener backButtonListener;
public void setBackButtonListener(BackButtonListener backButtonListener) {
this.backButtonListener = backButtonListener;
}
public interface AddListener {
void onClick();
}
private AddListener addListener;
public void setAddListener(AddListener addListener) {
this.addListener = addListener;
}
public interface EditListener {
void onClick();
}
private EditListener editListener;
public void setEditListener(EditListener editListener) {
this.editListener = editListener;
}
public int getEditState() {
if (tv_edit.getText().equals(mContext.getResources().getString(R.string.edit))) {
return 0;
} else if (tv_edit.getText().equals(mContext.getResources().getString(R.string.save))) {
return 1;
} else {
return -1;
}
}
public void setEditText(int state) {
if (state == 0) {
tv_edit.setText(mContext.getResources().getString(R.string.edit));
} else if (state == 1) {
tv_edit.setText(mContext.getResources().getString(R.string.save));
} else {
tv_edit.setText("");
}
}
}

@ -0,0 +1,155 @@
package com.yinuo.commonlib.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import androidx.annotation.Nullable;
import com.yinuo.commonlib.R;
public class MikeView extends View {
//进度条格数
private final int COUNT = 16;
//宽、高、间隔、进度条居上距离
private int mVoiceRectW = 1;
private int mVoiceRectH = 10;
private int mInterval = 3;
private int mVoiceRectMarginTop = 83;
//mic 文字 进度条 背景
private Paint mImagePaint;
private Paint mVoiceRectPaint;
private Paint mBackgroundPaint;
private Bitmap mVoiceRecording;//mic图片
//屏幕宽高
private int SCREEN_HEIGHT = 0;
private int SCREEN_WIDTH = 0;
private int mVoiceRectStart = 0, mDescriptionW = 0;//进度条开始左边位置、文字长度
private int mCurrentPosition = 0;//当前位置
private int mBackgroundRound = 3;//背景圆角
private int mImageW = 42;//新mic图片宽
private int mImageH = 42;//新mic图片高
private int mMarginTop = 25, mTextMarginBottom = 11;//mic图片居上距离 文字居底部距离
public MikeView(Context context) {
this(context, null);
}
public MikeView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public MikeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
DisplayMetrics dm = getResources().getDisplayMetrics();
mImageW = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mImageW, dm);
mImageH = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mImageH, dm);
mMarginTop = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mMarginTop, dm);
mTextMarginBottom = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mTextMarginBottom, dm);
mVoiceRectW = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mVoiceRectW, dm);
mVoiceRectH = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mVoiceRectH, dm);
mInterval = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mInterval, dm);
mVoiceRectMarginTop = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mVoiceRectMarginTop, dm);
mBackgroundRound = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, mBackgroundRound, dm);
mImagePaint = new Paint();
mVoiceRectPaint = new Paint();
mVoiceRectPaint.setColor(Color.WHITE);
mBackgroundPaint = new Paint();
mBackgroundPaint.setColor(Color.TRANSPARENT);//背景颜色
mVoiceRecording = BitmapFactory.decodeResource(getResources(), R.drawable.mike);
mVoiceRecording = scaleBitmap(mVoiceRecording, mImageW, mImageH);
setWillNotDraw(false);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (SCREEN_HEIGHT == 0 || SCREEN_WIDTH == 0) {
SCREEN_HEIGHT = getHeight();
SCREEN_WIDTH = getWidth();
}
if (mVoiceRectStart <= 0) {
mVoiceRectStart = SCREEN_WIDTH / 2 - (COUNT * mVoiceRectW + (COUNT - 1) * mInterval) / 2;
}
canvas.drawRoundRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, mBackgroundRound, mBackgroundRound, mBackgroundPaint);//画灰色背景和圆角
canvas.drawBitmap(mVoiceRecording, SCREEN_WIDTH / 2 - mVoiceRecording.getWidth() / 2, mMarginTop, mImagePaint);//画mic图片
//画前几个是白色 后几个是灰色
for (int i = 0; i < COUNT; i++) {
if (i < mCurrentPosition) {
mVoiceRectPaint.setColor(Color.WHITE);
} else {
mVoiceRectPaint.setColor(Color.parseColor("#73FFFFFF"));
}
canvas.drawRect(i * mVoiceRectW + (i * mInterval) + mVoiceRectStart, mVoiceRectMarginTop, i * mVoiceRectW + (i * mInterval) + mVoiceRectW + mVoiceRectStart, mVoiceRectMarginTop + mVoiceRectH, mVoiceRectPaint);
}
}
public void setIndex(int p) {
if (p < 0) {
p = 0;
}
if (p >= COUNT) {
p = COUNT - 1;
}
mCurrentPosition = p;
postInvalidate();
}
public void setIndex(double percent) {
int p = (int) (COUNT * percent);
setIndex(p);
}
/**
* bitmap
*
* @param origin
* @param newWidth
* @param newHeight
* @return bitmap
*/
private Bitmap scaleBitmap(Bitmap origin, int newWidth, int newHeight) {
if (origin == null) {
return null;
}
int height = origin.getHeight();
int width = origin.getWidth();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);// 使用后乘
Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
if (!origin.isRecycled()) {
origin.recycle();
}
return newBM;
}
}

@ -0,0 +1,217 @@
package com.yinuo.commonlib.view;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.Scroller;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
/**
* RecyclerView
* <p>
* Created by DavidChen on 2018/5/29.
*/
public class SlideRecyclerView extends RecyclerView {
private static final String TAG = "SlideRecyclerView";
private static final int INVALID_POSITION = -1; // 触摸到的点不在子View范围内
private static final int INVALID_CHILD_WIDTH = -1; // 子ItemView不含两个子View
private static final int SNAP_VELOCITY = 600; // 最小滑动速度
private VelocityTracker mVelocityTracker; // 速度追踪器
private int mTouchSlop; // 认为是滑动的最小距离(一般由系统提供)
private Rect mTouchFrame; // 子View所在的矩形范围
private Scroller mScroller;
private float mLastX; // 滑动过程中记录上次触碰点X
private float mFirstX, mFirstY; // 首次触碰范围
private boolean mIsSlide; // 是否滑动子View
private ViewGroup mFlingView; // 触碰的子View
private int mPosition; // 触碰的view的位置
private int mMenuViewWidth; // 菜单按钮宽度
public SlideRecyclerView(Context context) {
this(context, null);
}
public SlideRecyclerView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public SlideRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
mScroller = new Scroller(context);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
int x = (int) e.getX();
int y = (int) e.getY();
obtainVelocity(e);
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN:
if (!mScroller.isFinished()) { // 如果动画还没停止,则立即终止动画
mScroller.abortAnimation();
}
mFirstX = mLastX = x;
mFirstY = y;
mPosition = pointToPosition(x, y); // 获取触碰点所在的position
if (mPosition != INVALID_POSITION) {
View view = mFlingView;
// 获取触碰点所在的view
mFlingView = (ViewGroup) getChildAt(mPosition - ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition());
// 这里判断一下如果之前触碰的view已经打开而当前碰到的view不是那个view则立即关闭之前的view此处并不需要担动画没完成冲突因为之前已经abortAnimation
if (view != null && mFlingView != view && view.getScrollX() != 0) {
view.scrollTo(0, 0);
}
// 这里进行了强制的要求RecyclerView的子ViewGroup必须要有2个子view,这样菜单按钮才会有值,
// 需要注意的是:如果不定制RecyclerView的子View则要求子View必须要有固定的width。
// 比如使用LinearLayout作为根布局而content部分width已经是match_parent此时如果菜单view用的是wrap_contentmenu的宽度就会为0。
if (mFlingView.getChildCount() == 2) {
mMenuViewWidth = mFlingView.getChildAt(1).getWidth();
} else {
mMenuViewWidth = INVALID_CHILD_WIDTH;
}
}
break;
case MotionEvent.ACTION_MOVE:
mVelocityTracker.computeCurrentVelocity(1000);
// 此处有俩判断,满足其一则认为是侧滑:
// 1.如果x方向速度大于y方向速度且大于最小速度限制
// 2.如果x方向的侧滑距离大于y方向滑动距离且x方向达到最小滑动距离
float xVelocity = mVelocityTracker.getXVelocity();
float yVelocity = mVelocityTracker.getYVelocity();
if (Math.abs(xVelocity) > SNAP_VELOCITY && Math.abs(xVelocity) > Math.abs(yVelocity)
|| Math.abs(x - mFirstX) >= mTouchSlop
&& Math.abs(x - mFirstX) > Math.abs(y - mFirstY)) {
mIsSlide = true;
return true;
}
break;
case MotionEvent.ACTION_UP:
releaseVelocity();
break;
}
return super.onInterceptTouchEvent(e);
}
@Override
public boolean onTouchEvent(MotionEvent e) {
if (mIsSlide && mPosition != INVALID_POSITION) {
float x = e.getX();
obtainVelocity(e);
switch (e.getAction()) {
case MotionEvent.ACTION_DOWN: // 因为没有拦截,所以不会被调用到
break;
case MotionEvent.ACTION_MOVE:
// 随手指滑动
if (mMenuViewWidth != INVALID_CHILD_WIDTH) {
float dx = mLastX - x;
if (mFlingView.getScrollX() + dx <= mMenuViewWidth
&& mFlingView.getScrollX() + dx > 0) {
mFlingView.scrollBy((int) dx, 0);
}
mLastX = x;
}
break;
case MotionEvent.ACTION_UP:
if (mMenuViewWidth != INVALID_CHILD_WIDTH) {
int scrollX = mFlingView.getScrollX();
mVelocityTracker.computeCurrentVelocity(1000);
// 此处有两个原因决定是否打开菜单:
// 1.菜单被拉出宽度大于菜单宽度一半;
// 2.横向滑动速度大于最小滑动速度;
// 注意:之所以要小于负值,是因为向左滑则速度为负值
if (mVelocityTracker.getXVelocity() < -SNAP_VELOCITY) { // 向左侧滑达到侧滑最低速度,则打开
mScroller.startScroll(scrollX, 0, mMenuViewWidth - scrollX, 0, Math.abs(mMenuViewWidth - scrollX));
} else if (mVelocityTracker.getXVelocity() >= SNAP_VELOCITY) { // 向右侧滑达到侧滑最低速度,则关闭
mScroller.startScroll(scrollX, 0, -scrollX, 0, Math.abs(scrollX));
} else if (scrollX >= mMenuViewWidth / 2) { // 如果超过删除按钮一半,则打开
mScroller.startScroll(scrollX, 0, mMenuViewWidth - scrollX, 0, Math.abs(mMenuViewWidth - scrollX));
} else { // 其他情况则关闭
mScroller.startScroll(scrollX, 0, -scrollX, 0, Math.abs(scrollX));
}
invalidate();
}
mMenuViewWidth = INVALID_CHILD_WIDTH;
mIsSlide = false;
mPosition = INVALID_POSITION;
releaseVelocity(); // 这里之所以会调用是因为如果前面拦截了就不会执行ACTION_UP,需要在这里释放追踪
break;
}
return true;
} else {
// 此处防止RecyclerView正常滑动时还有菜单未关闭
closeMenu();
// Velocity这里的释放是防止RecyclerView正常拦截了但是在onTouchEvent中却没有被释放
// 有三种情况1.onInterceptTouchEvent并未拦截在onInterceptTouchEvent方法中DOWN和UP一对获取和释放
// 2.onInterceptTouchEvent拦截DOWN获取但事件不是被侧滑处理需要在这里进行释放
// 3.onInterceptTouchEvent拦截DOWN获取事件被侧滑处理则在onTouchEvent的UP中释放。
releaseVelocity();
}
return super.onTouchEvent(e);
}
private void releaseVelocity() {
if (mVelocityTracker != null) {
mVelocityTracker.clear();
mVelocityTracker.recycle();
mVelocityTracker = null;
}
}
private void obtainVelocity(MotionEvent event) {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
}
public int pointToPosition(int x, int y) {
if (null == getLayoutManager()) return INVALID_POSITION;
int firstPosition = ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition();
Rect frame = mTouchFrame;
if (frame == null) {
mTouchFrame = new Rect();
frame = mTouchFrame;
}
final int count = getChildCount();
for (int i = count - 1; i >= 0; i--) {
final View child = getChildAt(i);
if (child.getVisibility() == View.VISIBLE) {
child.getHitRect(frame);
if (frame.contains(x, y)) {
return firstPosition + i;
}
}
}
return INVALID_POSITION;
}
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
mFlingView.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
invalidate();
}
}
/**
* view
* item
*/
public void closeMenu() {
if (mFlingView != null && mFlingView.getScrollX() != 0) {
mFlingView.scrollTo(0, 0);
}
}
}

@ -0,0 +1,32 @@
package com.yinuo.commonlib.view;
import android.graphics.Rect;
import android.view.View;
import androidx.recyclerview.widget.RecyclerView;
import org.jetbrains.annotations.NotNull;
public class SpaceItemDecoration extends RecyclerView.ItemDecoration {
/**
*
*/
private static final int DEFAULT_MEDIA_SIZE = 3;
/**
*
*/
private static final int DEFAULT_MEDIA_OFFSET = 30;
@Override
public void getItemOffsets(@NotNull Rect outRect, @NotNull View view, RecyclerView parent, @NotNull RecyclerView.State state) {
int temp = parent.getChildAdapterPosition(view) % DEFAULT_MEDIA_SIZE;
outRect.left = DEFAULT_MEDIA_OFFSET * (temp);
if (parent.getChildAdapterPosition(view) >= DEFAULT_MEDIA_SIZE) {
outRect.top = DEFAULT_MEDIA_OFFSET;
} else {
outRect.top = 0;
}
}
}

@ -0,0 +1,28 @@
package com.yinuo.commonlib.view.activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.yinuo.commonlib.R;
public class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initStatusBar();
}
private void initStatusBar() {
Window window = getWindow();
//After LOLLIPOP not translucent status bar
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//Then call setStatusBarColor.
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(getResources().getColor(R.color.title_bar_bg_color));
}
}

@ -0,0 +1,18 @@
package com.yinuo.commonlib.view.fragment;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import org.jetbrains.annotations.NotNull;
public class BaseFragment extends Fragment {
public Context mContext;
@Override
public void onAttach(@NonNull @NotNull Context context) {
super.onAttach(context);
mContext = context;
}
}

@ -0,0 +1,59 @@
package com.yinuo.commonlib.view.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
abstract class BaseNavigationFragment : BaseFragment() {
private var isNavigationViewInit = false//记录是否已经初始化过一次视图
private var lastView: View? = null//记录上次创建的view
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
doPrepare()
//如果fragment的view已经创建则不再重新创建
if (lastView == null) {
lastView = getRootView(
inflater,
container,
savedInstanceState
)
}
return lastView
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
if (!isNavigationViewInit) {//初始化过视图则不再进行view和data初始化
super.onViewCreated(view, savedInstanceState)
initView()
initData()
initOthers()
isNavigationViewInit = true
}
}
abstract fun getRootView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View?
abstract fun initData()
abstract fun initView()
abstract fun initOthers()
abstract fun doPrepare()
fun getIsNavigationViewInit():Boolean{
return isNavigationViewInit
}
fun setIsNavigationViewInit(isNavigationViewInit:Boolean){
this.isNavigationViewInit=isNavigationViewInit
}
}

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="#E9E9E9"
android:alpha="0.8">
<path
android:fillColor="@android:color/white"
android:pathData="M19,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.11,0 2,-0.9 2,-2L21,5c0,-1.1 -0.89,-2 -2,-2zM10,17l-5,-5 1.41,-1.41L10,14.17l7.59,-7.59L19,8l-9,9z"/>
</vector>

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="#E9E9E9"
android:alpha="0.8">
<path
android:fillColor="@android:color/white"
android:pathData="M19,5v14H5V5h14m0,-2H5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2z"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 786 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 786 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 859 B

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/title_bar_bg_color"
android:gravity="center_vertical"
android:orientation="horizontal">
<RelativeLayout
android:id="@+id/rl_back_hot_zone"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingStart="@dimen/font_20dp"
android:paddingEnd="@dimen/font_20dp">
<ImageView
android:id="@+id/iv_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:src="@drawable/ic_back" />
</RelativeLayout>
<TextView
android:id="@+id/tv_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:textColor="@color/white"
android:textSize="@dimen/font_16dp" />
<RelativeLayout
android:id="@+id/rl_edit_hot_zone"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingStart="@dimen/font_20dp"
android:paddingEnd="@dimen/font_20dp"
android:visibility="gone">
<TextView
android:id="@+id/tv_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="@string/edit"
android:textColor="@color/white"
android:textSize="@dimen/font_14dp" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_add_hot_zone"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingStart="@dimen/font_20dp"
android:paddingEnd="@dimen/font_20dp">
<ImageView
android:id="@+id/iv_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:src="@drawable/ic_add" />
</RelativeLayout>
</LinearLayout>

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CommonTitleView">
<attr name="title" format="string"></attr>
<attr name="show_style" format="enum">
<enum name="left" value="1" />
<enum name="left_middle" value="2" />
<enum name="left_middle_right" value="3" />
<enum name="middle" value="4" />
<enum name="middle_right" value="5" />
<enum name="right" value="6" />
<enum name="edit" value="7" />
</attr>
<attr name="is_fixed_height" format="boolean"></attr>
<attr name="fixed_height" format="integer"></attr>
</declare-styleable>
</resources>

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="red">#FF0000</color>
<color name="bg_delete_btn">#FF5151</color>
<color name="bg_export_btn">#FFAA60</color>
<color name="font_666">#666666</color>
<color name="font_333">#333333</color>
<color name="font_999">#999999</color>
<color name="bg_F5">#F5F5F5</color>
<color name="bg_E9">#E9E9E9</color>
<color name="title_bar_bg_color">#0786F0</color>
<color name="btn_bg_start">#3BA6FF</color>
<color name="btn_bg_end">#0786F0</color>
<color name="yellow_button_color">#FFAA61</color>
<color name="home_template_text_color">#2E69FF</color>
<color name="home_record_text_color">#FF973B</color>
<color name="color_33">#333333</color>
<color name="color_f5">#F5F5F5</color>
<color name="color_66">#666666</color>
<color name="color_99">#999999</color>
</resources>

@ -0,0 +1,50 @@
<resources>
<dimen name="font_0.5dp">0.5dp</dimen>
<dimen name="font_1dp">1dp</dimen>
<dimen name="font_2dp">2dp</dimen>
<dimen name="font_3dp">3dp</dimen>
<dimen name="font_4dp">4dp</dimen>
<dimen name="font_8dp">8dp</dimen>
<dimen name="font_5dp">5dp</dimen>
<dimen name="font_6dp">6dp</dimen>
<dimen name="font_7dp">7dp</dimen>
<dimen name="font_9dp">9dp</dimen>
<dimen name="font_10dp">10dp</dimen>
<dimen name="font_11dp">11dp</dimen>
<dimen name="font_12dp">12dp</dimen>
<dimen name="font_13dp">13dp</dimen>
<dimen name="font_14dp">14dp</dimen>
<dimen name="font_15dp">15dp</dimen>
<dimen name="font_16dp">16dp</dimen>
<dimen name="font_17dp">17dp</dimen>
<dimen name="font_18dp">18dp</dimen>
<dimen name="font_19dp">19dp</dimen>
<dimen name="font_20dp">20dp</dimen>
<dimen name="font_21dp">21dp</dimen>
<dimen name="font_22dp">22dp</dimen>
<dimen name="font_23dp">23dp</dimen>
<dimen name="font_24dp">24dp</dimen>
<dimen name="font_26dp">26dp</dimen>
<dimen name="font_27dp">27dp</dimen>
<dimen name="font_28dp">28dp</dimen>
<dimen name="font_30dp">30dp</dimen>
<dimen name="font_29dp">29dp</dimen>
<dimen name="font_40dp">40dp</dimen>
<dimen name="font_42dp">42dp</dimen>
<dimen name="font_46dp">46dp</dimen>
<dimen name="font_65dp">65dp</dimen>
<dimen name="font_70dp">70dp</dimen>
<dimen name="font_72dp">72dp</dimen>
<dimen name="font_74dp">74dp</dimen>
<dimen name="font_79dp">79dp</dimen>
<dimen name="font_80dp">80dp</dimen>
<dimen name="font_90dp">90dp</dimen>
<dimen name="font_84dp">84dp</dimen>
<dimen name="font_100dp">100dp</dimen>
<dimen name="font_115dp">115dp</dimen>
<dimen name="font_152dp">152dp</dimen>
<dimen name="font_160dp">160dp</dimen>
<dimen name="fab_margin">16dp</dimen>
<dimen name="action_height">48dp</dimen>
<dimen name="font_size">15dp</dimen>
</resources>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="edit">编辑</string>
<string name="save">保存</string>
</resources>

@ -0,0 +1,64 @@
ext {
android = [
compileSdkVersion: 30,
buildToolsVersion: "30.0.3",
minSdkVersion : 23,
targetSdkVersion : 28,
versionCode : 1,
versionName : "1.0"
]
sign = [
keystore_path : "../yinuoapp.jks",
keystore_pwd : "123456",
keystore_alias: "yinuo"
]
compileOptions = [
sourceCompatibility: JavaVersion.VERSION_1_8,
targetCompatibility: JavaVersion.VERSION_1_8,
]
versions = [
appcompat : "1.2.0",
material : "1.2.1",
okhttp : "4.9.1",
retrofit : "2.4.0",
rxjava : "2.1.16",
rxandroid : "2.0.2",
kotlin : "1.5.10",
converter_gson : "2.4.0",
retrofit_rxjava : "2.9.0",
room : "2.3.0",
jxl : "2.6.12",
navigation_fragment_ktx: "2.3.0",
navigation_ui_ktx : "2.3.0",
glide : "4.11.0",
photo_view : "2.3.0",
luban : "1.1.8",
kotlin_android : "1.4.1"
]
dependencies = [
okhttp : "com.squareup.okhttp3:okhttp:${versions.okhttp}",
retrofit : "com.squareup.retrofit2:retrofit:${versions.retrofit}",
rxjava : "io.reactivex.rxjava2:rxjava:${versions.rxjava}",
rxandroid : "io.reactivex.rxjava2:rxandroid:${versions.rxandroid}",
kotlin : "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${versions.kotlin}",
kotlin_android : "org.jetbrains.kotlinx:kotlinx-coroutines-android:${versions.kotlin_android}",
converter_gson : "com.squareup.retrofit2:converter-gson:${versions.converter_gson}",
retrofit_rxjava : "com.squareup.retrofit2:adapter-rxjava2:${versions.retrofit_rxjava}",
room : "androidx.room:room-runtime:${versions.room}",
room_compiler : "androidx.room:room-compiler:${versions.room}",
room_ktx : "androidx.room:room-ktx:${versions.room}",
room_rxjava : "androidx.room:room-rxjava2:${versions.room}",
jxl : "net.sourceforge.jexcelapi:jxl:${versions.jxl}",
navigation_fragment_ktx: "androidx.navigation:navigation-fragment-ktx:${versions.navigation_fragment_ktx}",
navigation_ui_ktx : "androidx.navigation:navigation-ui-ktx:${versions.navigation_ui_ktx}",
navigation_arg : "androidx.navigation:navigation-safe-args-gradle-plugin:${versions.navigation_ui_ktx}",
glide : "com.github.bumptech.glide:glide:${versions.glide}",
annotationProcessor : "com.github.bumptech.glide:compiler:${versions.glide}",
photo_view : "com.github.chrisbanes:PhotoView:${versions.photo_view}",
luban : "top.zibin:Luban:${versions.luban}"
]
}

@ -0,0 +1,17 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app"s APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true

Binary file not shown.

@ -0,0 +1,6 @@
#Thu Jul 15 16:06:54 CST 2021
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

172
gradlew vendored

@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

84
gradlew.bat vendored

@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

@ -0,0 +1,3 @@
rootProject.name = "CommonLibTest"
include ':app'
include ':commonLib'
Loading…
Cancel
Save