提交 20712d6b 编写于 作者: B Blankj

see 11/15 log

上级 ea8f9aa1
* `18/11/12` [fix] SPUtils bug when use in multi threads. Publish v1.21.3.
* `18/11/15` [add] module of bus-gradle-plugin and change style of gradle.
* `18/11/14` [add] BusUtils.
* `18/11/13` [add] AdaptScreenUtils.
* `18/11/12` [fix] SPUtils bug when use in multi threads.
* `18/10/25` [fix] SpanUtils#setLineHeight bug of multi lines. Publish v1.21.2.
* `18/10/24` [fix] SpanUtils#appendImage on VIVO. Publish v1.21.1.
* `18/10/16` [add] BusUtils, DeviceUtils#isAdbEnabled. Publish v1.21.0.
......
![logo][logo]
[![auc][aucsvg]][auc] [![api][apisvg]][api] [![build][buildsvg]][build] [![Insight][insightsvg]][insight] [![License][licensesvg]][license]
[![auc][aucSvg]][auc] [![api][apiSvg]][api] [![build][buildSvg]][build] [![Insight][insightSvg]][insight] [![License][licenseSvg]][license]
## [README of English][readme]
......@@ -32,28 +32,28 @@
## Contact
[![Blog][blogsvg]][blog] [![jianshu][jianshusvg]][jianshu] [![weibo][weibosvg]][weibo] [![QQGroup][qqgroupsvg]][qqgroup]
[![Blog][blogSvg]][blog] [![jianshu][jianshuSvg]][jianshu] [![weibo][weiboSvg]][weibo] [![QQGroup][qqgroupSvg]][qqgroup]
## [Update Log][update_log.md]
## [Update Log][updateLog.md]
[logo]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/logo.png
[aucsvg]: https://img.shields.io/badge/AndroidUtilCode-v1.21.2-brightgreen.svg
[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.21.2-brightgreen.svg
[auc]: https://github.com/Blankj/AndroidUtilCode
[apisvg]: https://img.shields.io/badge/API-14+-brightgreen.svg
[apiSvg]: https://img.shields.io/badge/API-14+-brightgreen.svg
[api]: https://android-arsenal.com/api?level=14
[buildsvg]: https://travis-ci.org/Blankj/AndroidUtilCode.svg?branch=master
[buildSvg]: https://travis-ci.org/Blankj/AndroidUtilCode.svg?branch=master
[build]: https://travis-ci.org/Blankj/AndroidUtilCode
[insightsvg]: https://www.insight.io/repoBadge/github.com/Blankj/AndroidUtilCode
[insightSvg]: https://www.insight.io/repoBadge/github.com/Blankj/AndroidUtilCode
[insight]: https://insight.io/github.com/Blankj/AndroidUtilCode
[licensesvg]: https://img.shields.io/badge/License-Apache--2.0-brightgreen.svg
[licenseSvg]: https://img.shields.io/badge/License-Apache--2.0-brightgreen.svg
[license]: https://github.com/Blankj/AndroidUtilCode/blob/master/LICENSE
[readme]: https://github.com/Blankj/AndroidUtilCode
......@@ -65,18 +65,18 @@
[subutil]: https://github.com/Blankj/AndroidUtilCode/blob/master/subutil/README.md
[subutil-cn]: https://github.com/Blankj/AndroidUtilCode/blob/master/subutil/README-CN.md
[update_log.md]: https://github.com/Blankj/AndroidUtilCode/blob/master/update_log.md
[changeLog.md]: https://github.com/Blankj/AndroidUtilCode/blob/master/CHANGELOG.md
[donate]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/donate.png
[blogsvg]: https://img.shields.io/badge/Blog-@Blankj-34a48e.svg
[blogSvg]: https://img.shields.io/badge/Blog-@Blankj-34a48e.svg
[blog]: http://blankj.com
[jianshusvg]: https://img.shields.io/badge/简书-@Blankj-34a48e.svg
[jianshuSvg]: https://img.shields.io/badge/简书-@Blankj-34a48e.svg
[jianshu]: http://www.jianshu.com/u/46702d5c6978
[weibosvg]: https://img.shields.io/badge/weibo-@__Blankj-34a48e.svg
[weiboSvg]: https://img.shields.io/badge/weibo-@__Blankj-34a48e.svg
[weibo]: http://weibo.com/3076228982
[qqgroupsvg]: https://img.shields.io/badge/QQ群-25206533-34a48e.svg
[qqgroupSvg]: https://img.shields.io/badge/QQ群-25206533-34a48e.svg
[qqgroup]: https://shang.qq.com/wpa/qunwpa?idkey=d906789f84484465e2736f7b524366b4c23afeda38733d5c7b10fc3f6e406e9b
![logo][logo]
[![auc][aucsvg]][auc] [![api][apisvg]][api] [![build][buildsvg]][build] [![Insight][insightsvg]][insight] [![License][licensesvg]][license]
[![auc][aucSvg]][auc] [![api][apiSvg]][api] [![build][buildSvg]][build] [![Insight][insightSvg]][insight] [![License][licenseSvg]][license]
## [README of Chinese][readme-cn]
......@@ -32,7 +32,7 @@ If this project helps you a lot and you want to support the project's developmen
## Contact
[![Blog][blogsvg]][blog] [![jianshu][jianshusvg]][jianshu] [![weibo][weibosvg]][weibo] [![QQGroup][qqgroupsvg]][qqgroup]
[![Blog][blogSvg]][blog] [![jianshu][jianshuSvg]][jianshu] [![weibo][weiboSvg]][weibo] [![QQGroup][qqgroupSvg]][qqgroup]
## [Update Log][update_log.md]
......@@ -41,19 +41,19 @@ If this project helps you a lot and you want to support the project's developmen
[logo]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/logo.png
[aucsvg]: https://img.shields.io/badge/AndroidUtilCode-v1.21.2-brightgreen.svg
[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.21.2-brightgreen.svg
[auc]: https://github.com/Blankj/AndroidUtilCode
[apisvg]: https://img.shields.io/badge/API-14+-brightgreen.svg
[apiSvg]: https://img.shields.io/badge/API-14+-brightgreen.svg
[api]: https://android-arsenal.com/api?level=14
[buildsvg]: https://travis-ci.org/Blankj/AndroidUtilCode.svg?branch=master
[buildSvg]: https://travis-ci.org/Blankj/AndroidUtilCode.svg?branch=master
[build]: https://travis-ci.org/Blankj/AndroidUtilCode
[insightsvg]: https://www.insight.io/repoBadge/github.com/Blankj/AndroidUtilCode
[insightSvg]: https://www.insight.io/repoBadge/github.com/Blankj/AndroidUtilCode
[insight]: https://insight.io/github.com/Blankj/AndroidUtilCode
[licensesvg]: https://img.shields.io/badge/License-Apache--2.0-brightgreen.svg
[licenseSvg]: https://img.shields.io/badge/License-Apache--2.0-brightgreen.svg
[license]: https://github.com/Blankj/AndroidUtilCode/blob/master/LICENSE
[readme]: https://github.com/Blankj/AndroidUtilCode
......@@ -65,18 +65,18 @@ If this project helps you a lot and you want to support the project's developmen
[subutil]: https://github.com/Blankj/AndroidUtilCode/blob/master/subutil/README.md
[subutil-cn]: https://github.com/Blankj/AndroidUtilCode/blob/master/subutil/README-CN.md
[update_log.md]: https://github.com/Blankj/AndroidUtilCode/blob/master/update_log.md
[changeLog.md]: https://github.com/Blankj/AndroidUtilCode/blob/master/CHANGELOG.md
[donate]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/donate.png
[blogsvg]: https://img.shields.io/badge/Blog-@Blankj-34a48e.svg
[blogSvg]: https://img.shields.io/badge/Blog-@Blankj-34a48e.svg
[blog]: http://blankj.com
[jianshusvg]: https://img.shields.io/badge/简书-@Blankj-34a48e.svg
[jianshuSvg]: https://img.shields.io/badge/简书-@Blankj-34a48e.svg
[jianshu]: http://www.jianshu.com/u/46702d5c6978
[weibosvg]: https://img.shields.io/badge/weibo-@__Blankj-34a48e.svg
[weiboSvg]: https://img.shields.io/badge/weibo-@__Blankj-34a48e.svg
[weibo]: http://weibo.com/3076228982
[qqgroupsvg]: https://img.shields.io/badge/QQ群-25206533-34a48e.svg
[qqgroupSvg]: https://img.shields.io/badge/QQ群-25206533-34a48e.svg
[qqgroup]: https://shang.qq.com/wpa/qunwpa?idkey=d906789f84484465e2736f7b524366b4c23afeda38733d5c7b10fc3f6e406e9b
{}
\ No newline at end of file
......@@ -6,4 +6,20 @@ plugins {
}
// in config.gradle
configAndroidDomain project
configAppDependencies project
\ No newline at end of file
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':utilcode-lib')
implementation project(':subutil-lib')
implementation dep.support.appcompat_v7
implementation dep.support.design
implementation dep.constraint
implementation dep.kotlin
implementation dep.free_proguard
implementation 'com.r0adkll:slidableactivity:2.0.5'
// LeakCanary
debugImplementation dep.leakcanary.android
releaseImplementation dep.leakcanary.android_no_op
// implementation 'com.blankj:utilcode:1.21.2'
}
\ No newline at end of file
......@@ -8,7 +8,6 @@ import android.support.v7.app.AppCompatActivity
import android.view.WindowManager
import com.blankj.androidutilcode.R
import com.blankj.utilcode.util.AdaptScreenUtils
import com.blankj.utilcode.util.LogUtils
class CloseAdaptActivity : AppCompatActivity() {
......@@ -26,8 +25,6 @@ class CloseAdaptActivity : AppCompatActivity() {
}
override fun getResources(): Resources {
val resources = super.getResources()
LogUtils.e(resources.displayMetrics)
return AdaptScreenUtils.adaptWidth(resources, 1080, false)
return AdaptScreenUtils.closeAdapt(super.getResources())
}
}
......@@ -9,7 +9,6 @@ import android.support.v7.app.AppCompatActivity
import android.view.WindowManager
import com.blankj.androidutilcode.R
import com.blankj.utilcode.util.AdaptScreenUtils
import com.blankj.utilcode.util.LogUtils
import kotlinx.android.synthetic.main.activity_adapt_height.*
class HeightActivity : AppCompatActivity() {
......@@ -30,8 +29,6 @@ class HeightActivity : AppCompatActivity() {
}
override fun getResources(): Resources {
val resources = super.getResources()
LogUtils.e(resources.displayMetrics)
return AdaptScreenUtils.adaptHeight(resources, 1920)
return AdaptScreenUtils.adaptHeight(super.getResources(), 1920)
}
}
......@@ -9,7 +9,6 @@ import android.support.v7.app.AppCompatActivity
import android.view.WindowManager
import com.blankj.androidutilcode.R
import com.blankj.utilcode.util.AdaptScreenUtils
import com.blankj.utilcode.util.LogUtils
import kotlinx.android.synthetic.main.activity_adapt_width.*
class WidthActivity : AppCompatActivity() {
......@@ -30,8 +29,6 @@ class WidthActivity : AppCompatActivity() {
}
override fun getResources(): Resources {
val resources = super.getResources()
LogUtils.e(resources.displayMetrics)
return AdaptScreenUtils.adaptWidth(resources, 1080)
return AdaptScreenUtils.adaptWidth(super.getResources(), 1080)
}
}
......@@ -42,4 +42,4 @@ allprojects {
task clean(type: Delete) {
delete rootProject.buildDir
}
\ No newline at end of file
}
......@@ -50,32 +50,49 @@ ext {
configAndroidDomain = this.&configAndroidDomain
configAppDependencies = this.&configAppDependencies
configUtilCodeDependencies = this.&configUtilCodeDependencies
configSubUtilDependencies = this.&configSubUtilDependencies
}
def configAndroidDomain(Project pro) {
def configAndroidDomain(Project pro, String applicationIdSuffix = "") {
configCommon(pro)
if (pro.plugins.hasPlugin("com.android.application")) {
configAppAndroidDomain(pro)
configAppAndroidDomain(pro, applicationIdSuffix)
} else {
configLibAndroidDomain(pro)
}
}
def configAppAndroidDomain(Project pro) {
configField(pro)
configSigning(pro)
configApkName(pro)
def configCommon(Project pro) {
pro.android {
compileSdkVersion rootProject.compileSdkVersion
defaultConfig {
applicationId rootProject.applicationId
minSdkVersion rootProject.minSdkVersion
targetSdkVersion rootProject.targetSdkVersion
versionCode rootProject.versionCode
versionName rootProject.versionName
}
lintOptions {
abortOnError false
}
testOptions.unitTests.all {
testLogging {
events 'passed', 'skipped', 'failed', 'standardOut', 'standardError'
}
}
}
}
def configAppAndroidDomain(Project pro, String applicationIdSuffix = "") {
configField(pro)
configSigning(pro)
configApkName(pro)
pro.android {
defaultConfig {
applicationId rootProject.applicationId + applicationIdSuffix
targetSdkVersion rootProject.targetSdkVersion
}
buildTypes {
release {
minifyEnabled true
......@@ -87,10 +104,6 @@ def configAppAndroidDomain(Project pro) {
main.res.srcDirs += 'src/main/res-core'
main.res.srcDirs += 'src/main/res-sub'
}
lintOptions {
abortOnError false
}
}
}
......@@ -131,13 +144,6 @@ def configApkName(Project pro) {
def configLibAndroidDomain(Project pro) {
pro.android {
compileSdkVersion rootProject.compileSdkVersion
defaultConfig {
minSdkVersion rootProject.minSdkVersion
versionCode rootProject.versionCode
versionName rootProject.versionName
}
buildTypes {
release {
minifyEnabled false
......@@ -145,16 +151,6 @@ def configLibAndroidDomain(Project pro) {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
testOptions.unitTests.all {
testLogging {
events 'passed', 'skipped', 'failed', 'standardOut', 'standardError'
}
}
}
afterEvaluate {
......@@ -164,50 +160,4 @@ def configLibAndroidDomain(Project pro) {
}
def configAppDependencies(Project pro) {
pro.dependencies {
implementation fileTree(include: ['*.jar'], dir: 'app/libs')
implementation project(':utilcode')
implementation project(':subutil')
implementation dep.support.appcompat_v7
implementation dep.support.design
implementation dep.constraint
implementation dep.free_proguard
implementation 'com.r0adkll:slidableactivity:2.0.5'
// LeakCanary
debugImplementation dep.leakcanary.android
releaseImplementation dep.leakcanary.android_no_op
// implementation 'com.blankj:utilcode:1.21.2'
}
}
def configUtilCodeDependencies(Project pro) {
pro.dependencies {
api dep.bus
api dep.kotlin
compileOnly dep.support.appcompat_v7
compileOnly dep.support.design
testImplementation dep.junit
testImplementation dep.robolectric
testImplementation dep.support.appcompat_v7
}
}
def configSubUtilDependencies(Project pro) {
pro.dependencies {
compileOnly dep.support.appcompat_v7
compileOnly dep.support.design
api dep.gson
api(dep.glide) {
exclude group: "com.android.support"
}
api dep.retrofit
testImplementation dep.junit
testImplementation dep.robolectric
}
}
//./gradlew utilcode:bintrayUpload
\ No newline at end of file
......@@ -63,6 +63,13 @@ install {
}
}
if (project.hasProperty("kotlin")) {
// Disable creating javadocs
tasks.withType(Javadoc) {
enabled = false
}
}
// This generates sources.jar
task sourcesJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
......@@ -71,6 +78,7 @@ task sourcesJar(type: Jar) {
task javadoc(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += configurations.compile
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}
......
plugins {
id "com.android.application"
id 'kotlin-android'
id 'kotlin-android-extensions'
// id "com.blankj.bus"
}
// in config.gradle
configAndroidDomain project
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
// implementation project(':applauncher')
// implementation project(':subutil')
implementation dep.support.appcompat_v7
implementation dep.support.design
implementation dep.constraint
implementation dep.kotlin
implementation dep.free_proguard
implementation 'com.r0adkll:slidableactivity:2.0.5'
// LeakCanary
debugImplementation dep.leakcanary.android
releaseImplementation dep.leakcanary.android_no_op
// implementation 'com.blankj:utilcode:1.21.2'
}
\ No newline at end of file
# 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
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.blankj.launcher">
<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/AppTheme">
<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>
\ No newline at end of file
package com.blankj.launcher
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
<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:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeWidth="1"
android:strokeColor="#00000000">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
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="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
<?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="#008577"
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>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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" />
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
<?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>
\ No newline at end of file
<?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>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
</resources>
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
apply plugin: 'com.android.library'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 14
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
# 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
package com.blankj.pkg;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.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.getTargetContext();
assertEquals("com.blankj.pkg.test", appContext.getPackageName());
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.blankj.pkg" />
<resources>
<string name="app_name">pkg</string>
</resources>
package com.blankj.pkg;
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);
}
}
\ No newline at end of file
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
// in config.gradle
configAndroidDomain project
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
api dep.support.appcompat_v7
api dep.support.design
api dep.constraint
api dep.kotlin
api dep.free_proguard
api 'com.r0adkll:slidableactivity:2.0.5'
}
\ No newline at end of file
# 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
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.blankj.base" />
package com.blankj.base;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 2016/10/24
* desc : base about activity
* </pre>
*/
public abstract class BaseActivity extends AppCompatActivity
implements IBaseView {
protected View mContentView;
protected Activity mActivity;
/**
* 上次点击时间
*/
private long lastClick = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivity = this;
Bundle bundle = getIntent().getExtras();
initData(bundle);
setBaseView(bindLayout());
initView(savedInstanceState, mContentView);
doBusiness();
}
@SuppressLint("ResourceType")
protected void setBaseView(@LayoutRes int layoutId) {
if (layoutId <= 0) return;
setContentView(mContentView = LayoutInflater.from(this).inflate(layoutId, null));
}
/**
* 判断是否快速点击
*
* @return {@code true}: 是<br>{@code false}: 否
*/
private boolean isFastClick() {
long now = System.currentTimeMillis();
if (now - lastClick >= 200) {
lastClick = now;
return false;
}
return true;
}
@Override
public void onClick(final View view) {
if (!isFastClick()) onWidgetClick(view);
}
}
package com.blankj.base;
import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.util.Log;
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 2017/03/30
* desc : base about application
* </pre>
*/
public class BaseApplication extends Application {
private static final String TAG = "BaseApplication";
private static BaseApplication sInstance;
public static BaseApplication getInstance() {
return sInstance;
}
@Override
public void onCreate() {
super.onCreate();
sInstance = this;
registerActivityLifecycleCallbacks(mCallbacks);
}
private ActivityLifecycleCallbacks mCallbacks = new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Log.d(TAG, "onActivityCreated() called with: activity = [" + activity + "], savedInstanceState = [" + savedInstanceState + "]");
}
@Override
public void onActivityStarted(Activity activity) {
Log.d(TAG, "onActivityStarted() called with: activity = [" + activity + "]");
}
@Override
public void onActivityResumed(Activity activity) {
Log.d(TAG, "onActivityResumed() called with: activity = [" + activity + "]");
}
@Override
public void onActivityPaused(Activity activity) {
Log.d(TAG, "onActivityPaused() called with: activity = [" + activity + "]");
}
@Override
public void onActivityStopped(Activity activity) {
Log.d(TAG, "onActivityStopped() called with: activity = [" + activity + "]");
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
Log.d(TAG, "onActivitySaveInstanceState() called with: activity = [" + activity + "], outState = [" + outState + "]");
}
@Override
public void onActivityDestroyed(Activity activity) {
Log.d(TAG, "onActivityDestroyed() called with: activity = [" + activity + "]");
}
};
}
package com.blankj.base;
import android.annotation.SuppressLint;
import android.support.annotation.LayoutRes;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.widget.FrameLayout;
import com.blankj.androidutilcode.R;
import com.blankj.androidutilcode.UtilsApp;
import com.blankj.utilcode.util.BarUtils;
import com.r0adkll.slidr.Slidr;
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 2017/06/27
* desc : base about back activity
* </pre>
*/
public abstract class BaseBackActivity extends BaseActivity {
protected CoordinatorLayout rootLayout;
protected Toolbar mToolbar;
protected AppBarLayout abl;
protected FrameLayout flActivityContainer;
@SuppressLint("ResourceType")
@Override
protected void setBaseView(@LayoutRes int layoutId) {
Slidr.attach(this);
mContentView = LayoutInflater.from(this).inflate(R.layout.activity_back, null);
setContentView(mContentView);
rootLayout = findViewById(R.id.root_layout);
abl = findViewById(R.id.abl);
mToolbar = findViewById(R.id.toolbar);
flActivityContainer = findViewById(R.id.activity_container);
if (layoutId > 0) {
flActivityContainer.addView(LayoutInflater.from(this).inflate(layoutId, flActivityContainer, false));
}
setSupportActionBar(mToolbar);
getToolBar().setDisplayHomeAsUpEnabled(true);
BarUtils.setStatusBarColor(this, ContextCompat.getColor(UtilsApp.getInstance(), R.color.colorPrimary), 0);
BarUtils.addMarginTopEqualStatusBarHeight(rootLayout);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
}
return super.onOptionsItemSelected(item);
}
protected ActionBar getToolBar() {
return getSupportActionBar();
}
}
package com.blankj.base;
import android.content.Intent;
import android.net.Uri;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.widget.FrameLayout;
import com.blankj.androidutilcode.Config;
import com.blankj.androidutilcode.R;
import com.blankj.utilcode.util.ActivityUtils;
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 2017/06/27
* desc : base about drawer activity
* </pre>
*/
public abstract class BaseDrawerActivity extends BaseActivity {
protected DrawerLayout rootLayout;
protected FrameLayout flActivityContainer;
NavigationView.OnNavigationItemSelectedListener mListener = new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.action_git_hub:
ActivityUtils.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(Config.GITHUB)));
break;
case R.id.action_blog:
ActivityUtils.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(Config.BLOG)));
break;
}
return false;
}
};
@Override
protected void setBaseView(@LayoutRes int layoutId) {
mContentView = LayoutInflater.from(this).inflate(R.layout.activity_drawer, null);
setContentView(mContentView);
rootLayout = findViewById(R.id.root_layout);
flActivityContainer = findViewById(R.id.activity_container);
flActivityContainer.addView(LayoutInflater.from(this).inflate(layoutId, flActivityContainer, false));
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(mListener);
}
}
package com.blankj.base;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.IdRes;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 2017/03/28
* desc : base about v4-fragment
* </pre>
*/
public abstract class BaseFragment extends Fragment
implements IBaseView {
private static final String TAG = "BaseFragment";
private static final String STATE_SAVE_IS_HIDDEN = "STATE_SAVE_IS_HIDDEN";
protected View mContentView;
protected Activity mActivity;
private long lastClick = 0;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
Log.d(TAG, "onCreate: ");
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
boolean isSupportHidden = savedInstanceState.getBoolean(STATE_SAVE_IS_HIDDEN);
FragmentTransaction ft = getFragmentManager().beginTransaction();
if (isSupportHidden) {
ft.hide(this);
} else {
ft.show(this);
}
ft.commitAllowingStateLoss();
}
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.d(TAG, "onCreateView: ");
setBaseView(inflater, bindLayout());
return mContentView;
}
protected void setBaseView(@NonNull LayoutInflater inflater, @LayoutRes int layoutId) {
if (layoutId <= 0) return;
mContentView = inflater.inflate(layoutId, null);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
Log.d(TAG, "onViewCreated: ");
super.onViewCreated(view, savedInstanceState);
Bundle bundle = getArguments();
initData(bundle);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
Log.d(TAG, "onActivityCreated: ");
super.onActivityCreated(savedInstanceState);
mActivity = getActivity();
initView(savedInstanceState, mContentView);
doBusiness();
}
@Override
public void onDestroyView() {
Log.d(TAG, "onDestroyView: ");
if (mContentView != null) {
((ViewGroup) mContentView.getParent()).removeView(mContentView);
}
super.onDestroyView();
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy: ");
super.onDestroy();
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
Log.d(TAG, "onSaveInstanceState: ");
super.onSaveInstanceState(outState);
outState.putBoolean(STATE_SAVE_IS_HIDDEN, isHidden());
}
private boolean isFastClick() {
long now = System.currentTimeMillis();
if (now - lastClick >= 200) {
lastClick = now;
return false;
}
return true;
}
@Override
public void onClick(View view) {
if (!isFastClick()) onWidgetClick(view);
}
public <T extends View> T findViewById(@IdRes int id) {
if (mContentView == null) throw new NullPointerException("ContentView is null.");
return mContentView.findViewById(id);
}
}
package com.blankj.androidutilcode.base
import android.support.v7.app.AppCompatActivity
class BaseKotlinActivity : AppCompatActivity() {
}
\ No newline at end of file
package com.blankj.base;
import android.util.Log;
/**
* <pre>
* author: blankj
* blog : http://blankj.com
* time : 2018/03/23
* desc : base about lazy fragment
* </pre>
*/
public abstract class BaseLazyFragment extends BaseFragment {
private static final String TAG = "BaseLazyFragment";
private boolean isDataLoaded;
public abstract void doLazyBusiness();
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
Log.d(TAG, "setUserVisibleHint: " + isVisibleToUser);
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser && mContentView != null && !isDataLoaded) {
doLazyBusiness();
isDataLoaded = true;
}
}
@Override
public void doBusiness() {
if (getUserVisibleHint()) {
doLazyBusiness();
isDataLoaded = true;
}
}
}
package com.blankj.base;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 2017/06/27
* desc :
* </pre>
*/
interface IBaseView extends View.OnClickListener {
/**
* 初始化数据
*
* @param bundle 传递过来的 bundle
*/
void initData(@Nullable final Bundle bundle);
/**
* 绑定布局
*
* @return 布局 Id
*/
int bindLayout();
/**
* 初始化 view
*/
void initView(final Bundle savedInstanceState, final View contentView);
/**
* 业务操作
*/
void doBusiness();
/**
* 视图点击事件
*
* @param view 视图
*/
void onWidgetClick(final View view);
}
package com.blankj.base.rv;
import android.support.annotation.IdRes;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.View;
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 2017/08/22
* desc :
* </pre>
*/
public class BaseViewHolder extends RecyclerView.ViewHolder {
private SparseArray<View> viewArray = new SparseArray<>();
public BaseViewHolder(View itemView) {
super(itemView);
}
@SuppressWarnings("unchecked")
public <T extends View> T getView(@IdRes final int viewId) {
View view = viewArray.get(viewId);
if (view == null) {
view = itemView.findViewById(viewId);
viewArray.put(viewId, view);
}
return (T) view;
}
}
package com.blankj.base.rv;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.LinearLayout;
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 2017/08/17
* desc :
* </pre>
*/
public class RecycleViewDivider extends RecyclerView.ItemDecoration {
public static final int HORIZONTAL = LinearLayout.HORIZONTAL;
public static final int VERTICAL = LinearLayout.VERTICAL;
protected Drawable mDivider;
protected int mOrientation;
protected final Rect mBounds = new Rect();
public RecycleViewDivider(Context context, int orientation, @DrawableRes int resId) {
this(context, orientation, ContextCompat.getDrawable(context, resId));
}
public RecycleViewDivider(Context context, int orientation, @NonNull Drawable divider) {
setOrientation(orientation);
mDivider = divider;
}
public void setOrientation(int orientation) {
if (orientation != HORIZONTAL && orientation != VERTICAL) {
throw new IllegalArgumentException(
"Invalid orientation. It should be either HORIZONTAL or VERTICAL");
}
mOrientation = orientation;
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (parent.getLayoutManager() == null) {
return;
}
if (mOrientation == VERTICAL) {
drawVertical(c, parent);
} else {
drawHorizontal(c, parent);
}
}
@SuppressLint("NewApi")
protected void drawVertical(Canvas canvas, RecyclerView parent) {
canvas.save();
final int left;
final int right;
if (parent.getClipToPadding()) {
left = parent.getPaddingLeft();
right = parent.getWidth() - parent.getPaddingRight();
canvas.clipRect(left, parent.getPaddingTop(), right,
parent.getHeight() - parent.getPaddingBottom());
} else {
left = 0;
right = parent.getWidth();
}
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
parent.getDecoratedBoundsWithMargins(child, mBounds);
final int bottom = mBounds.bottom + Math.round(ViewCompat.getTranslationY(child));
final int top = bottom - mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
canvas.restore();
}
@SuppressLint("NewApi")
protected void drawHorizontal(Canvas canvas, RecyclerView parent) {
canvas.save();
final int top;
final int bottom;
if (parent.getClipToPadding()) {
top = parent.getPaddingTop();
bottom = parent.getHeight() - parent.getPaddingBottom();
canvas.clipRect(parent.getPaddingLeft(), top,
parent.getWidth() - parent.getPaddingRight(), bottom);
} else {
top = 0;
bottom = parent.getHeight();
}
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
parent.getLayoutManager().getDecoratedBoundsWithMargins(child, mBounds);
final int right = mBounds.right + Math.round(ViewCompat.getTranslationX(child));
final int left = right - mDivider.getIntrinsicWidth();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
canvas.restore();
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if (mOrientation == VERTICAL) {
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
} else {
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
}
}
package com.blankj.base.rv.adapter;
import android.content.Context;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.blankj.base.rv.BaseViewHolder;
import com.blankj.base.rv.listener.OnItemClickListener;
import com.blankj.base.rv.listener.OnItemLongClickListener;
import java.util.List;
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 2017/08/22
* desc :
* </pre>
*/
public abstract class BaseAdapter<M> extends RecyclerView.Adapter<BaseViewHolder> {
protected static final int VIEW_TYPE_EMPTY = 0xfff0;
protected static final int VIEW_TYPE_HEADER = 0xfff1;
protected static final int VIEW_TYPE_FOOTER = 0xfff2;
protected static final int VIEW_TYPE_DEFAULT = 0xfff3;
private final SparseArray<View> mViewArray = new SparseArray<>();
protected List<M> mData;
protected Context mContext;
protected ViewGroup mParent;
protected LayoutInflater mInflater;
private OnItemClickListener mClickListener;
private OnItemLongClickListener mLongClickListener;
public void setData(@NonNull final List<M> data) {
mData = data;
}
@Override
public final int getItemViewType(int position) {
if (getDataSize() == 0 && mViewArray.get(VIEW_TYPE_EMPTY) != null) {
return VIEW_TYPE_EMPTY;
} else if (position == 0 && mViewArray.get(VIEW_TYPE_HEADER) != null) {
return VIEW_TYPE_HEADER;
} else if (position == getItemCount() - 1 && mViewArray.get(VIEW_TYPE_FOOTER) != null) {
return VIEW_TYPE_FOOTER;
} else {
return getCustomViewType(position);
}
}
protected int getCustomViewType(final int position) {
return VIEW_TYPE_DEFAULT;
}
protected abstract int bindLayout(final int viewType);
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (mParent == null) {
mParent = parent;
mContext = parent.getContext();
mInflater = LayoutInflater.from(mContext);
}
View itemView = mViewArray.get(viewType);
if (itemView == null) {
itemView = inflateLayout(bindLayout(viewType));
}
return new BaseViewHolder(itemView);
}
@Override
public final void onBindViewHolder(BaseViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case VIEW_TYPE_EMPTY:
case VIEW_TYPE_HEADER:
case VIEW_TYPE_FOOTER:
break;
default:
bindCustomViewHolder(holder, position);
break;
}
}
protected void bindCustomViewHolder(final BaseViewHolder holder, final int position) {
final int dataPos = position - (mViewArray.get(VIEW_TYPE_HEADER) == null ? 0 : 1);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mClickListener != null) {
mClickListener.onItemClick(v, dataPos);
}
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return mLongClickListener != null && mLongClickListener.onItemLongClick(v, dataPos);
}
});
bind(holder, mData.get(dataPos));
}
protected abstract void bind(final BaseViewHolder holder, final M data);
@Override
public int getItemCount() {
return getDataSize() + getExtraViewCount();
}
public void setEmptyView(@NonNull View emptyView) {
setView(VIEW_TYPE_EMPTY, emptyView);
}
public View getEmptyView() {
return getView(VIEW_TYPE_EMPTY);
}
public void removeEmptyView() {
removeView(VIEW_TYPE_EMPTY);
}
public void setHeaderView(@NonNull View headerView) {
setView(VIEW_TYPE_HEADER, headerView);
}
public View getHeaderView() {
return getView(VIEW_TYPE_HEADER);
}
public void removeHeaderView() {
removeView(VIEW_TYPE_HEADER);
}
public void setFooterView(@NonNull View footerView) {
setView(VIEW_TYPE_FOOTER, footerView);
}
public View getFooterView() {
return getView(VIEW_TYPE_FOOTER);
}
public void removeFooterView() {
removeView(VIEW_TYPE_FOOTER);
}
private void setView(final int type, @NonNull final View view) {
mViewArray.put(type, view);
notifyDataSetChanged();
}
private View getView(final int type) {
return mViewArray.get(type);
}
private void removeView(final int type) {
if (mViewArray.get(type) != null) {
mViewArray.delete(type);
notifyDataSetChanged();
}
}
private View inflateLayout(@LayoutRes final int layoutId) {
return mInflater.inflate(layoutId, mParent, false);
}
private int getExtraViewCount() {
int extraViewCount = 0;
if (mViewArray.get(VIEW_TYPE_HEADER) != null) {
extraViewCount++;
}
if (mViewArray.get(VIEW_TYPE_FOOTER) != null) {
extraViewCount++;
}
return extraViewCount;
}
public void setOnItemClickListener(final OnItemClickListener clickListener) {
mClickListener = clickListener;
}
public void setOnItemLongClickListener(final OnItemLongClickListener longClickListener) {
mLongClickListener = longClickListener;
}
private int getDataSize() {
return mData == null ? 0 : mData.size();
}
}
package com.blankj.base.rv.adapter;
import android.support.annotation.LayoutRes;
import java.util.List;
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 2017/08/22
* desc :
* </pre>
*/
public abstract class SingleAdapter<M> extends BaseAdapter<M> {
private final int mLayoutId;
public SingleAdapter(List<M> list, @LayoutRes int layoutId) {
setData(list);
mLayoutId = layoutId;
}
@Override
protected int bindLayout(final int viewType) {
return mLayoutId;
}
}
package com.blankj.base.rv.listener;
import android.view.View;
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 2017/08/21
* desc :
* </pre>
*/
public interface OnItemClickListener {
void onItemClick(final View view, final int position);
}
package com.blankj.base.rv.listener;
import android.view.View;
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 2017/08/21
* desc :
* </pre>
*/
public interface OnItemLongClickListener {
boolean onItemLongClick(final View view, final int position);
}
<resources>
<string name="app_name">Base</string>
</resources>
apply plugin: 'com.android.library'
configAndroidDomain project
dependencies {
// implementation project(':libbase')
}
\ No newline at end of file
# 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
<manifest package="com.blankj.resource" />
<resources>
<string name="app_name">resource</string>
</resources>
apply plugin: 'com.android.library'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 14
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
# 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
package com.blankj.pkgutilcode;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.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.getTargetContext();
assertEquals("com.blankj.pkgutilcode.test", appContext.getPackageName());
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.blankj.pkgutilcode" />
<resources>
<string name="app_name">pkgutilcode</string>
</resources>
package com.blankj.pkgutilcode;
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);
}
}
\ No newline at end of file
include ':app',
includeModule ':app',
':buildSrc',
':subutil',
':utilcode', ':bus-gradle-plugin'
\ No newline at end of file
':bus-gradle-plugin',
':libresource', ':pkgutilcode',
'launcher', 'subutil', 'utilcode'
//,'libbase'
def includeModule(String... names) {
names.each {
def fileName
if (it.startsWith(":")) {
fileName = it.substring(1, it.length())
} else {
fileName = it;
}
if (isModule(file(fileName))) {
include it
} else {
file(it).eachDir { dir ->
if (dir.name == 'build') return
include "$it-$dir.name"
project(":$it-${dir.name}").projectDir = dir
}
}
}
}
static boolean isModule(File file) {
File[] files = file.listFiles()
for (int i = 0; i < files.length; i++) {
if (files[i].name == 'build.gradle') {
return true;
}
}
}
......@@ -5,9 +5,21 @@ plugins {
// in config.gradle
configAndroidDomain project
configSubUtilDependencies project
readme {
readmeFile file('README.md')
readmeCnFile file('README-CN.md')
}
dependencies {
compileOnly dep.support.appcompat_v7
compileOnly dep.support.design
api dep.gson
api(dep.glide) {
exclude group: "com.android.support"
}
api dep.retrofit
testImplementation dep.junit
testImplementation dep.robolectric
}
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册