提交 acc19233 编写于 作者: B Blankj

see 11/18 log

上级 050efe26
* `18/11/18` [fix] ToastUtils don't show in the devices grater than API 24 when close the permission of notification. Publish v1.22.0.
* `18/11/17` [fix] AppUtils#isAppInstalled don't work in no launcher app.
* `18/11/16` [fix] ThreadUtils#cancel block the main thread.
* `18/11/15` [add] module of bus-gradle-plugin and change style of gradle.
* `18/11/14` [add] BusUtils.
* `18/11/13` [add] AdaptScreenUtils.
......
......@@ -41,7 +41,7 @@
[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.22.0-brightgreen.svg
[auc]: https://github.com/Blankj/AndroidUtilCode
[apiSvg]: https://img.shields.io/badge/API-14+-brightgreen.svg
......
......@@ -41,7 +41,7 @@ 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.22.0-brightgreen.svg
[auc]: https://github.com/Blankj/AndroidUtilCode
[apiSvg]: https://img.shields.io/badge/API-14+-brightgreen.svg
......
......@@ -21,5 +21,5 @@ dependencies {
// LeakCanary
debugImplementation dep.leakcanary.android
releaseImplementation dep.leakcanary.android_no_op
// implementation 'com.blankj:utilcode:1.21.2'
// implementation 'com.blankj:utilcode:1.22.0'
}
\ No newline at end of file
......@@ -8,7 +8,6 @@ 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;
......@@ -43,7 +42,7 @@ public abstract class BaseBackActivity extends BaseActivity {
mToolbar = findViewById(R.id.toolbar);
flActivityContainer = findViewById(R.id.activity_container);
if (layoutId > 0) {
flActivityContainer.addView(LayoutInflater.from(this).inflate(layoutId, flActivityContainer, false));
LayoutInflater.from(this).inflate(layoutId, flActivityContainer);
}
setSupportActionBar(mToolbar);
getToolBar().setDisplayHomeAsUpEnabled(true);
......@@ -52,14 +51,6 @@ public abstract class BaseBackActivity extends BaseActivity {
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();
}
......
......@@ -3,7 +3,6 @@ package com.blankj.androidutilcode.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;
......@@ -52,13 +51,13 @@ public abstract class BaseFragment extends Fragment
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.d(TAG, "onCreateView: ");
setBaseView(inflater, bindLayout());
setRootLayout(bindLayout());
return mContentView;
}
protected void setBaseView(@NonNull LayoutInflater inflater, @LayoutRes int layoutId) {
protected void setRootLayout(int layoutId) {
if (layoutId <= 0) return;
mContentView = inflater.inflate(layoutId, null);
mContentView = mActivity.getLayoutInflater().inflate(layoutId, null);
}
@Override
......
package com.blankj.androidutilcode.base
import android.support.v7.app.AppCompatActivity
class BaseKotlinActivity : AppCompatActivity() {
}
\ No newline at end of file
......@@ -5,8 +5,8 @@ ext {
compileSdkVersion = 27
minSdkVersion = 14
targetSdkVersion = 27
versionCode = 1_021_003
versionName = '1.21.3'// E.g. 1.9.72 => 1,009,072
versionCode = 1_022_000
versionName = '1.22.0'// E.g. 1.9.72 => 1,009,072
localDebugPlugin = false
......@@ -53,10 +53,10 @@ ext {
configAppDependencies = this.&configAppDependencies
}
def configAndroidDomain(Project pro, String applicationIdSuffix = "") {
def configAndroidDomain(Project pro) {
configCommon(pro)
if (pro.plugins.hasPlugin("com.android.application")) {
configAppAndroidDomain(pro, applicationIdSuffix)
configAppAndroidDomain(pro)
} else {
configLibAndroidDomain(pro)
}
......@@ -84,15 +84,16 @@ def configCommon(Project pro) {
}
def configAppAndroidDomain(Project pro, String applicationIdSuffix = "") {
configField(pro)
def configAppAndroidDomain(Project pro) {
configSigning(pro)
configApkName(pro)
String suffix = getSuffix(pro)
pro.android {
defaultConfig {
applicationId rootProject.applicationId + applicationIdSuffix
applicationId rootProject.applicationId + suffix
targetSdkVersion rootProject.targetSdkVersion
multiDexEnabled true
resValue "string", "app_name", rootProject.appName + suffix
}
buildTypes {
......@@ -115,10 +116,13 @@ def configAppAndroidDomain(Project pro, String applicationIdSuffix = "") {
}
}
def configField(Project pro) {
pro.android.defaultConfig {
resValue "string", "app_name", rootProject.appName
private static String getSuffix(Project pro) {
String[] splits = pro.name.split("-")
String suffix = ""
if (splits.length == 2) {
suffix = "." + splits[0]
}
return suffix
}
def configSigning(Project pro) {
......@@ -167,4 +171,4 @@ def configLibAndroidDomain(Project pro) {
}
}
//./gradlew utilcode:bintrayUpload
\ No newline at end of file
//./gradlew clean utilcode-lib:bintrayUpload
\ No newline at end of file
......@@ -2,7 +2,7 @@ plugins {
id "com.android.application"
id 'kotlin-android'
id 'kotlin-android-extensions'
id "com.blankj.bus"
// id "com.blankj.bus"
}
// in config.gradle
......
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=".pkg.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>
......@@ -50,7 +50,7 @@
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name=".SplashActivity"
android:name=".MainActivity"
android:screenOrientation="user"
android:windowSoftInputMode="stateHidden|adjustPan">
<intent-filter>
......@@ -61,10 +61,10 @@
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:screenOrientation="user"
android:windowSoftInputMode="stateHidden|adjustPan" />
<!--<activity-->
<!--android:name=".MainActivity"-->
<!--android:screenOrientation="user"-->
<!--android:windowSoftInputMode="stateHidden|adjustPan" />-->
</application>
</manifest>
package com.blankj.launcher.pkg;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.view.View;
import com.blankj.base.BaseDrawerActivity;
import com.blankj.pkg.R;
import com.blankj.utilcode.util.BarUtils;
import com.blankj.utilcode.util.BusUtils;
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 2016/09/29
* desc : MainActivity
* </pre>
*/
public class MainActivity extends BaseDrawerActivity {
@Override
public void initData(@Nullable Bundle bundle) {
}
@Override
public int bindLayout() {
return R.layout.activity_main;
}
@Override
public void initView(Bundle savedInstanceState, View contentView) {
Toolbar toolbar = findViewById(R.id.toolbar);
View fakeStatusBar = findViewById(R.id.fake_status_bar);
CollapsingToolbarLayout ctl = findViewById(R.id.ctl);
ctl.setExpandedTitleColor(Color.TRANSPARENT);
setSupportActionBar(toolbar);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this,
rootLayout,
toolbar,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close);
rootLayout.addDrawerListener(toggle);
toggle.syncState();
BarUtils.setStatusBarAlpha4Drawer(this, rootLayout, fakeStatusBar, 0, false);
BarUtils.addMarginTopEqualStatusBarHeight(toolbar);
}
@Override
public void doBusiness() {
}
@Override
public void onWidgetClick(View view) {
}
public void coreUtilClick(View view) {
BusUtils.post("CoreUtilActivity#start", this);
}
public void subUtilClick(View view) {
BusUtils.post("SubUtilActivity#start", this);
}
}
package com.blankj.launcher.pkg
import android.graphics.Color
import android.os.Bundle
import android.support.v7.app.ActionBarDrawerToggle
import android.view.View
import com.blankj.base.BaseDrawerActivity
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.BarUtils
import com.blankj.utilcode.util.BusUtils
import kotlinx.android.synthetic.main.activity_main.*
/**
* ```
* author: Blankj
* blog : http://blankj.com
* time : 2016/09/29
* desc : MainActivity
* ```
*/
class MainActivity : BaseDrawerActivity() {
override fun initData(bundle: Bundle?) {
}
override fun bindLayout(): Int {
return R.layout.activity_main
}
override fun initView(savedInstanceState: Bundle?, contentView: View) {
launcherMainCtl.setExpandedTitleColor(Color.TRANSPARENT)
setSupportActionBar(launcherMainToolbar)
val toggle = ActionBarDrawerToggle(this,
mDrawerRootLayout,
launcherMainToolbar,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close)
mDrawerRootLayout.addDrawerListener(toggle)
toggle.syncState()
BarUtils.setStatusBarAlpha4Drawer(this, mDrawerRootLayout, launcherMainFakeStatusBar, 0, false)
BarUtils.addMarginTopEqualStatusBarHeight(launcherMainToolbar)
}
override fun doBusiness() {
}
override fun onWidgetClick(view: View) {
}
fun coreUtilClick(view: View) {
BusUtils.post<Any>("CoreUtilActivity#start", this)
}
fun subUtilClick(view: View) {
BusUtils.post<Any>("SubUtilActivity#start", this)
}
override fun onBackPressed() {
ActivityUtils.startHomeActivity()
}
}
......@@ -5,7 +5,6 @@ import android.view.View
import com.blankj.base.BaseActivity
class SplashActivity : BaseActivity() {
override fun initData(bundle: Bundle?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
......@@ -14,7 +13,7 @@ class SplashActivity : BaseActivity() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun initView(savedInstanceState: Bundle?, contentView: View?) {
override fun initView(savedInstanceState: Bundle?, contentView: View) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
......@@ -22,7 +21,7 @@ class SplashActivity : BaseActivity() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onWidgetClick(view: View?) {
override fun onWidgetClick(view: View) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
\ No newline at end of file
......@@ -12,7 +12,7 @@
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/ctl"
android:id="@+id/launcherMainCtl"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="@color/colorPrimary"
......@@ -28,7 +28,7 @@
app:layout_collapseParallaxMultiplier="0.6" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:id="@+id/launcherMainToolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
......@@ -37,7 +37,7 @@
</android.support.design.widget.AppBarLayout>
<View
android:id="@+id/fake_status_bar"
android:id="@+id/launcherMainFakeStatusBar"
android:layout_width="match_parent"
android:layout_height="0dp" />
......
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
plugins {
id "com.android.library"
id 'kotlin-android'
id 'kotlin-android-extensions'
}
// in config.gradle
configAndroidDomain project
......
<manifest package="com.blankj.base" />
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.blankj.base">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
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.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.LayoutInflater
import android.view.View
/**
* ```
* author: blankj
* blog : http://blankj.com
* time : 2018/11/16
* desc : base about activity
* ```
*/
abstract class BaseActivity : AppCompatActivity(), IBaseView {
protected lateinit var mContentView: View
protected lateinit var mActivity: Activity
private var lastClick: Long = 0// the time of last click
private val isFastClick: Boolean
get() {
val now = System.currentTimeMillis()
if (now - lastClick >= 200) {
lastClick = now
return false
}
return true
}
override fun onCreate(savedInstanceState: Bundle?) {
mActivity = this
super.onCreate(savedInstanceState)
initData(intent.extras)
setRootLayout(bindLayout())
initView(savedInstanceState, mContentView)
doBusiness()
}
override fun setRootLayout(layoutId: Int) {
if (layoutId <= 0) return
mContentView = LayoutInflater.from(this).inflate(layoutId, null)
setContentView(mContentView)
}
override fun onClick(view: View) {
if (!isFastClick) onWidgetClick(view)
}
}
\ No newline at end of file
package com.blankj.base;
package com.blankj.base
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.support.multidex.MultiDex;
import android.support.multidex.MultiDexApplication;
import android.util.Log;
import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.CrashUtils;
import com.blankj.utilcode.util.LogUtils;
import com.squareup.leakcanary.LeakCanary;
import java.util.ArrayList;
import android.content.Context
import android.support.multidex.MultiDex
import android.support.multidex.MultiDexApplication
import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.CrashUtils
import com.blankj.utilcode.util.LogUtils
import com.squareup.leakcanary.LeakCanary
/**
* <pre>
* author: Blankj
* blog : http://blankj.com
* time : 2017/03/30
* desc : base about application
* </pre>
* ```
* author: blankj
* blog : http://blankj.com
* time : 2018/11/16
* desc : base about application
* ```
*/
public class BaseApplication extends MultiDexApplication {
private static final String TAG = "BaseApplication";
private static BaseApplication sInstance;
open class BaseApplication : MultiDexApplication() {
public static BaseApplication getInstance() {
return sInstance;
companion object {
private lateinit var instance: BaseApplication
}
protected final boolean isDebug = AppUtils.isAppDebug();
private var isDebug: Boolean? = null
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
MultiDex.install(this)
}
@Override
public void onCreate() {
super.onCreate();
sInstance = this;
initLeakCanary();
initLog();
initCrash();
override fun onCreate() {
super.onCreate()
instance = this
initLeakCanary()
initLog()
initCrash()
}
private void initLeakCanary() {
// 内存泄露检查工具
if (isDebug) {
private fun initLeakCanary() {// 内存泄露检查工具
if (isDebug()) {
if (LeakCanary.isInAnalyzerProcess(this)) {
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
return;
return
}
LeakCanary.install(this);
LeakCanary.install(this)
}
}
// init it in ur application
public void initLog() {
final LogUtils.Config config = LogUtils.getConfig()
.setLogSwitch(isDebug)// 设置 log 总开关,包括输出到控制台和文件,默认开
.setConsoleSwitch(isDebug)// 设置是否输出到控制台开关,默认开
private fun initLog() {
val config = LogUtils.getConfig()
.setLogSwitch(isDebug())// 设置 log 总开关,包括输出到控制台和文件,默认开
.setConsoleSwitch(isDebug())// 设置是否输出到控制台开关,默认开
.setGlobalTag(null)// 设置 log 全局标签,默认为空
// 当全局标签不为空时,我们输出的 log 全部为该 tag,
// 为空时,如果传入的 tag 为空那就显示类名,否则显示 tag
......@@ -82,23 +68,23 @@ public class BaseApplication extends MultiDexApplication {
.setStackOffset(0)// 设置栈偏移,比如二次封装的话就需要设置,默认为 0
.setSaveDays(3)// 设置日志可保留天数,默认为 -1 表示无限时长
// 新增 ArrayList 格式化器,默认已支持 Array, Throwable, Bundle, Intent 的格式化输出
.addFormatter(new LogUtils.IFormatter<ArrayList>() {
@Override
public String format(ArrayList list) {
return "LogUtils Formatter ArrayList { " + list.toString() + " }";
.addFormatter(object : LogUtils.IFormatter<ArrayList<*>>() {
override fun format(list: ArrayList<*>?): String {
return "LogUtils Formatter ArrayList { " + list.toString() + " }"
}
});
LogUtils.d(config.toString());
})
LogUtils.d(config.toString())
}
@SuppressLint("MissingPermission")
private void initCrash() {
CrashUtils.init(new CrashUtils.OnCrashListener() {
@Override
public void onCrash(String crashInfo, Throwable e) {
LogUtils.e(crashInfo);
AppUtils.relaunchApp();
}
});
private fun initCrash() {
CrashUtils.init { crashInfo, e ->
LogUtils.e(crashInfo)
AppUtils.relaunchApp()
}
}
protected fun isDebug(): Boolean {
if (isDebug == null) isDebug = AppUtils.isAppDebug()
return isDebug!!
}
}
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.utilcode.util.BarUtils;
import com.blankj.utilcode.util.Utils;
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(Utils.getApp(), 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.support.v4.content.ContextCompat
import android.view.LayoutInflater
import com.blankj.utilcode.util.BarUtils
import com.blankj.utilcode.util.Utils
import com.r0adkll.slidr.Slidr
import kotlinx.android.synthetic.main.activity_back.*
/**
* ```
* author: blankj
* blog : http://blankj.com
* time : 2018/11/16
* desc : base about back activity
* ```
*/
abstract class BaseBackActivity : BaseActivity() {
override fun setRootLayout(layoutId: Int) {
super.setRootLayout(R.layout.activity_back)
Slidr.attach(this)
if (layoutId > 0) {
LayoutInflater.from(this).inflate(layoutId, baseBackActivityContainer)
}
setSupportActionBar(baseBackToolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
BarUtils.setStatusBarColor(this, ContextCompat.getColor(Utils.getApp(), R.color.colorPrimary), 0)
BarUtils.addMarginTopEqualStatusBarHeight(baseBackRootLayout)
}
}
\ No newline at end of file
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.utilcode.util.ActivityUtils;
import com.blankj.utilcode.util.StringUtils;
/**
* <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) {
int i = item.getItemId();
if (i == R.id.action_git_hub) {
ActivityUtils.startActivity(
new Intent(Intent.ACTION_VIEW, Uri.parse(StringUtils.getString(R.string.github)))
);
} else if (i == R.id.action_blog) {
ActivityUtils.startActivity(
new Intent(Intent.ACTION_VIEW, Uri.parse(StringUtils.getString(R.string.blog)))
);
}
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.content.Intent
import android.net.Uri
import android.support.annotation.StringRes
import android.support.v4.widget.DrawerLayout
import android.view.LayoutInflater
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.StringUtils
import kotlinx.android.synthetic.main.activity_drawer.*
/**
* ```
* author: blankj
* blog : http://blankj.com
* time : 2018/11/16
* desc : base about drawer activity
* ```
*/
abstract class BaseDrawerActivity : BaseActivity() {
protected lateinit var mDrawerRootLayout: DrawerLayout
override fun setRootLayout(layoutId: Int) {
super.setRootLayout(R.layout.activity_drawer)
if (layoutId > 0) {
LayoutInflater.from(this).inflate(layoutId, baseBackActivityContainer)
}
navView.setNavigationItemSelectedListener l@{ item ->
when (item.itemId) {
R.id.action_git_hub -> return@l goWeb(R.string.github)
R.id.action_blog -> return@l goWeb(R.string.blog)
}
false
}
mDrawerRootLayout = drawerRootLayout;
}
private fun goWeb(@StringRes id: Int): Boolean {
return ActivityUtils.startActivity(
Intent(Intent.ACTION_VIEW, Uri.parse(StringUtils.getString(id)))
)
}
}
package com.blankj.base;
import android.annotation.SuppressLint;
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, 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.base
import android.app.Activity
import android.content.Context
import android.os.Bundle
import android.support.annotation.IdRes
import android.support.v4.app.Fragment
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
/**
* ```
* author: blankj
* blog : http://blankj.com
* time : 2018/11/16
* desc : base about v4-fragment
* ```
*/
abstract class BaseFragment : Fragment(), IBaseView {
companion object {
private const val TAG = "BaseFragment"
private const val STATE_SAVE_IS_HIDDEN = "STATE_SAVE_IS_HIDDEN"
}
protected lateinit var mActivity: Activity
protected lateinit var mInflater: LayoutInflater
protected lateinit var mContentView: View
private var lastClick: Long = 0
private val isFastClick: Boolean
get() {
val now = System.currentTimeMillis()
if (now - lastClick >= 200) {
lastClick = now
return false
}
return true
}
override fun onAttach(context: Context?) {
super.onAttach(context)
mActivity = context as Activity;
}
override fun onCreate(savedInstanceState: Bundle?) {
Log.d(TAG, "onCreate: ")
super.onCreate(savedInstanceState)
if (savedInstanceState != null) {
val isSupportHidden = savedInstanceState.getBoolean(STATE_SAVE_IS_HIDDEN)
fragmentManager?.beginTransaction()?.let {
if (isSupportHidden) {
it.hide(this).commitAllowingStateLoss()
} else {
it.show(this).commitAllowingStateLoss()
}
}
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
Log.d(TAG, "onCreateView: ")
mInflater = inflater
setRootLayout(bindLayout())
return mContentView
}
override fun setRootLayout(layoutId: Int) {
if (layoutId <= 0) return
mContentView = mInflater.inflate(layoutId, null)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
Log.d(TAG, "onViewCreated: ")
super.onViewCreated(view, savedInstanceState)
val bundle = arguments
initData(bundle)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
Log.d(TAG, "onActivityCreated: ")
super.onActivityCreated(savedInstanceState)
initView(savedInstanceState, mContentView)
doBusiness()
}
override fun onDestroyView() {
Log.d(TAG, "onDestroyView: ")
(mContentView.parent as ViewGroup).removeView(mContentView)
super.onDestroyView()
}
override fun onSaveInstanceState(outState: Bundle) {
Log.d(TAG, "onSaveInstanceState: ")
super.onSaveInstanceState(outState)
outState.putBoolean(STATE_SAVE_IS_HIDDEN, isHidden)
}
override fun onDestroy() {
Log.d(TAG, "onDestroy: ")
super.onDestroy()
}
override fun onClick(view: View) {
if (!isFastClick) onWidgetClick(view)
}
fun <T : View> findViewById(@IdRes id: Int): T {
return mContentView.findViewById(id)
}
}
package com.blankj.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.util.Log
/**
* ```
* author: blankj
* blog : http://blankj.com
* time : 2018/03/23
* desc : base about lazy fragment
* ```
*/
abstract class BaseLazyFragment : BaseFragment() {
companion object {
private const val TAG = "BaseLazyFragment"
}
private var isDataLoaded: Boolean = false
abstract fun doLazyBusiness()
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
Log.d(TAG, "setUserVisibleHint: $isVisibleToUser")
super.setUserVisibleHint(isVisibleToUser)
if (isVisibleToUser && !isDataLoaded) {
doLazyBusiness()
isDataLoaded = true
}
}
override fun doBusiness() {
if (userVisibleHint) {
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
import android.os.Bundle
import android.view.View
/**
* ```
* author: blankj
* blog : http://blankj.com
* time : 2018/11/16
* desc :
* ```
*/
interface IBaseView : View.OnClickListener {
fun initData(bundle: Bundle?)
fun bindLayout(): Int
fun setRootLayout(layoutId: Int)
fun initView(savedInstanceState: Bundle?, contentView: View)
fun doBusiness()
fun onWidgetClick(view: View)
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root_layout"
android:id="@+id/baseBackRootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
<android.support.design.widget.AppBarLayout
android:id="@+id/abl"
android:id="@+id/baseBackAppBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:id="@+id/baseBackToolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways" />
......@@ -26,7 +26,7 @@
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<FrameLayout
android:id="@+id/activity_container"
android:id="@+id/baseBackActivityContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.NestedScrollView>
......
......@@ -3,7 +3,7 @@
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:id="@+id/root_layout"
android:id="@+id/drawerRootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
......@@ -12,12 +12,12 @@
tools:openDrawer="start">
<FrameLayout
android:id="@+id/activity_container"
android:id="@+id/baseBackActivityContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:id="@+id/navView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
......
......@@ -2,8 +2,7 @@
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="192dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
android:layout_height="192dp">
<ImageView
android:layout_width="match_parent"
......@@ -13,19 +12,19 @@
android:src="@drawable/main_bg_header" />
<ImageView
android:id="@+id/iv_avatar"
android:id="@+id/avatarIv"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_above="@+id/tv_desc"
android:layout_above="@+id/descTv"
android:layout_marginLeft="@dimen/spacing_16"
android:src="@drawable/main_avatar_round" />
<TextView
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_above="@+id/tv_desc"
android:layout_above="@+id/descTv"
android:layout_marginLeft="@dimen/spacing_16"
android:layout_toRightOf="@id/iv_avatar"
android:layout_toRightOf="@id/avatarIv"
android:gravity="center_vertical"
android:text="@string/author"
android:textColor="@color/white"
......@@ -33,13 +32,13 @@
android:textStyle="bold" />
<TextView
android:id="@+id/tv_desc"
android:id="@+id/descTv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="@dimen/spacing_16"
android:layout_marginLeft="@dimen/spacing_16"
android:layout_marginTop="@dimen/spacing_8"
android:layout_marginBottom="@dimen/spacing_16"
android:text="@string/demo_of_android_util_code"
android:textColor="@color/white"
android:textSize="@dimen/font_16" />
......
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
<android.support.design.widget.AppBarLayout
android:id="@+id/abl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<FrameLayout
android:id="@+id/activity_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
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:id="@+id/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:fitsSystemWindows="true"
android:overScrollMode="never"
tools:openDrawer="start">
<FrameLayout
android:id="@+id/activity_container"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@color/white"
android:fitsSystemWindows="false"
app:headerLayout="@layout/activity_drawer_nav_header"
app:menu="@menu/main_drawer" />
</android.support.v4.widget.DrawerLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="192dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
android:scaleType="centerCrop"
android:src="@drawable/main_bg_header" />
<ImageView
android:id="@+id/iv_avatar"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_above="@+id/tv_desc"
android:layout_marginLeft="@dimen/spacing_16"
android:src="@drawable/main_avatar_round" />
<TextView
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_above="@+id/tv_desc"
android:layout_marginLeft="@dimen/spacing_16"
android:layout_toRightOf="@id/iv_avatar"
android:gravity="center_vertical"
android:text="@string/author"
android:textColor="@color/white"
android:textSize="@dimen/font_40"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="@dimen/spacing_16"
android:layout_marginLeft="@dimen/spacing_16"
android:layout_marginTop="@dimen/spacing_8"
android:text="@string/demo_of_android_util_code"
android:textColor="@color/white"
android:textSize="@dimen/font_16" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="192dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/ctl"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="@color/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/spacing_16"
android:scaleType="fitCenter"
android:src="@mipmap/ic_launcher"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.6" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<View
android:id="@+id/fake_status_bar"
android:layout_width="match_parent"
android:layout_height="0dp" />
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingLeft="@dimen/spacing_16"
android:paddingRight="@dimen/spacing_16">
<Button
style="@style/WideBtnStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="coreUtilClick"
android:text="@string/core_util" />
<Button
style="@style/WideBtnStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="subUtilClick"
android:text="@string/sub_util" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
includeModule ':app',
':buildSrc',
':bus-gradle-plugin',
':lib',
':launcher',
':lib',
':subutil',
':utilcode'
//,'libbase'
def includeModule(String... names) {
names.each {
......
......@@ -2,7 +2,7 @@
Gradle:
```groovy
implementation 'com.blankj:utilcode:1.21.2'
implementation 'com.blankj:utilcode:1.22.0'
```
......
......@@ -24,19 +24,12 @@ buildscript {
apply plugin: "com.blankj.bus"
```
给 base 模块添加 bus 依赖:
给 base 模块添加 [AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode) 依赖:
```groovy
api "com.blankj:bus:1.0"
api "com.blankj:utilcode:1.22.0"
```
或者 [AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode) 依赖:
```groovy
api "com.blankj:utilcode:1.21.0+"
```
比如 module0 中存在的 `Module0Activity.java`,我们通常都是在它内部写一个 `start` 函数来启动它,现在我们给它添加 `@BusUtils.Subscribe` 注解,并给注解的 `name` 赋唯一值,要注意,函数务必要 `public static` 哦:
```java
......
......@@ -2,7 +2,7 @@
Gradle:
```groovy
implementation 'com.blankj:utilcode:1.21.2'
implementation 'com.blankj:utilcode:1.22.0'
```
......
......@@ -282,24 +282,13 @@ public final class AppUtils {
* @return {@code true}: yes<br>{@code false}: no
*/
public static boolean isAppInstalled(@NonNull final String packageName) {
return !isSpace(packageName)
&& Utils.getApp().getPackageManager().getLaunchIntentForPackage(packageName) != null;
}
/**
* Return whether the app is installed.
*
* @param action The Intent action, such as ACTION_VIEW.
* @param category The desired category.
* @return {@code true}: yes<br>{@code false}: no
*/
public static boolean isAppInstalled(@NonNull final String action,
@NonNull final String category) {
Intent intent = new Intent(action);
intent.addCategory(category);
PackageManager pm = Utils.getApp().getPackageManager();
ResolveInfo info = pm.resolveActivity(intent, 0);
return info != null;
PackageManager packageManager = Utils.getApp().getPackageManager();
try {
return packageManager.getApplicationInfo(packageName, 0) != null;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return false;
}
}
/**
......
......@@ -892,7 +892,7 @@ public final class ThreadUtils {
ScheduledExecutorService scheduled = TASK_SCHEDULED.get(task);
if (scheduled != null) {
TASK_SCHEDULED.remove(task);
shutdownAndAwaitTermination(scheduled);
scheduled.shutdownNow();
}
}
......@@ -950,22 +950,6 @@ public final class ThreadUtils {
}
}
private static void shutdownAndAwaitTermination(final ExecutorService pool) {
pool.shutdown();
try {
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow();
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
System.err.println("Pool did not terminate");
}
}
} catch (InterruptedException e) {
pool.shutdownNow();
Thread.currentThread().interrupt();
e.printStackTrace();
}
}
public abstract static class SimpleTask<T> extends Task<T> {
@Override
......
......@@ -4,6 +4,7 @@ import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
......@@ -17,9 +18,9 @@ import android.os.Message;
import android.support.annotation.ColorInt;
import android.support.annotation.DrawableRes;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.support.v4.app.NotificationManagerCompat;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
......@@ -250,7 +251,7 @@ public final class ToastUtils {
@Override
public void run() {
cancel();
sToast = ToastFactory.makeToast(Utils.getApp(), text, duration);
sToast = ToastFactory.makeToast(Utils.getTopActivityOrApp(), text, duration);
final TextView tvMessage = sToast.getView().findViewById(android.R.id.message);
if (sMsgColor != COLOR_DEFAULT) {
tvMessage.setTextColor(sMsgColor);
......@@ -340,21 +341,14 @@ public final class ToastUtils {
if (NotificationManagerCompat.from(context).areNotificationsEnabled()) {
return new SystemToast(makeNormalToast(context, text, duration));
}
return new ToastWithoutNotification(makeNormalToast(context, text, duration));
// Log.e("ToastUtils", "Toast is GG. In fact, next step is useless.");
// return new SystemToast(makeNormalToast(context, text, duration));
}
static IToast newToast(Context context) {
if (NotificationManagerCompat.from(context).areNotificationsEnabled()) {
return new SystemToast(new Toast(context));
}
// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
return new ToastWithoutNotification(new Toast(context));
// }
// Log.e("ToastUtils", "Toast is GG. In fact, next step is useless.");
// return new SystemToast(new Toast(context));
}
private static Toast makeNormalToast(Context context, CharSequence text, int duration) {
......@@ -365,15 +359,13 @@ public final class ToastUtils {
}
}
static class SystemToast implements IToast {
Toast mToast;
static class SystemToast extends AbsToast {
private static Field sField_mTN;
private static Field sField_TN_Handler;
SystemToast(@NonNull Toast toast) {
mToast = toast;
SystemToast(Toast toast) {
super(toast);
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N_MR1) {
try {
//noinspection JavaReflectionMemberAccess
......@@ -398,36 +390,6 @@ public final class ToastUtils {
mToast.cancel();
}
@Override
public void setView(View view) {
mToast.setView(view);
}
@Override
public View getView() {
return mToast.getView();
}
@Override
public void setDuration(int duration) {
mToast.setDuration(duration);
}
@Override
public void setGravity(int gravity, int xOffset, int yOffset) {
mToast.setGravity(gravity, xOffset, yOffset);
}
@Override
public void setText(int resId) {
mToast.setText(resId);
}
@Override
public void setText(CharSequence s) {
mToast.setText(s);
}
static class SafeHandler extends Handler {
private Handler impl;
......@@ -440,7 +402,7 @@ public final class ToastUtils {
try {
impl.handleMessage(msg);
} catch (Exception e) {
LogUtils.e(e);
Log.e("ToastUtils", e.toString());
}
}
......@@ -451,9 +413,7 @@ public final class ToastUtils {
}
}
static class ToastWithoutNotification implements IToast {
private Toast mToast;
static class ToastWithoutNotification extends AbsToast {
private WindowManager mWM;
......@@ -461,20 +421,8 @@ public final class ToastUtils {
private WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
private Handler mHandler = new Handler(Looper.myLooper());
ToastWithoutNotification(@NonNull Toast toast) {
mToast = toast;
mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mParams.format = PixelFormat.TRANSLUCENT;
mParams.windowAnimations = android.R.style.Animation_Toast;
mParams.type = WindowManager.LayoutParams.TYPE_TOAST;
mParams.setTitle("ToastWithoutNotification");
mParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
ToastWithoutNotification(Toast toast) {
super(toast);
}
@Override
......@@ -484,11 +432,15 @@ public final class ToastUtils {
Context context = mToast.getView().getContext();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
mWM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
mParams.type = WindowManager.LayoutParams.TYPE_TOAST;
mParams.y = mToast.getYOffset();
} else {
Context topActivityOrApp = Utils.getTopActivityOrApp();
if (topActivityOrApp instanceof Activity) {
mWM = ((Activity) topActivityOrApp).getWindowManager();
}
mParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
mParams.y = mToast.getYOffset() + getNavBarHeight();
}
final Configuration config = context.getResources().getConfiguration();
......@@ -498,6 +450,16 @@ public final class ToastUtils {
} else {
gravity = mToast.getGravity();
}
mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mParams.format = PixelFormat.TRANSLUCENT;
mParams.windowAnimations = android.R.style.Animation_Toast;
mParams.setTitle("ToastWithoutNotification");
mParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
mParams.gravity = gravity;
if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) {
mParams.horizontalWeight = 1.0f;
......@@ -506,15 +468,13 @@ public final class ToastUtils {
mParams.verticalWeight = 1.0f;
}
mParams.x = mToast.getXOffset();
mParams.y = mToast.getYOffset();
mParams.packageName = Utils.getApp().getPackageName();
try {
mWM.addView(mView, mParams);
} catch (Exception ignored) { /**/ }
mHandler.postDelayed(new Runnable() {
HANDLER.postDelayed(new Runnable() {
@Override
public void run() {
cancel();
......@@ -525,13 +485,34 @@ public final class ToastUtils {
@Override
public void cancel() {
try {
mWM.removeView(mView);
} catch (IllegalArgumentException ignored) { /**/ }
if (mWM != null) {
mWM.removeView(mView);
}
} catch (Exception ignored) { /**/ }
mView = null;
mHandler = null;
mWM = null;
mToast = null;
}
private int getNavBarHeight() {
Resources res = Resources.getSystem();
int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId != 0) {
return res.getDimensionPixelSize(resourceId);
} else {
return 0;
}
}
}
static abstract class AbsToast implements IToast {
Toast mToast;
AbsToast(Toast toast) {
mToast = toast;
}
@Override
public void setView(View view) {
mToast.setView(view);
......
package com.blankj.utilcode.util;
import android.support.annotation.Nullable;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.concurrent.TimeUnit;
/**
* <pre>
* author: Blankj
......@@ -24,5 +28,24 @@ public class BaseTest {
@Test
public void test() {
ThreadUtils.SimpleTask<String> task = new ThreadUtils.SimpleTask<String>() {
@Nullable
@Override
public String doInBackground() throws Throwable {
boolean fl = true;
while (fl) {
System.out.println("haha");
}
return null;
}
@Override
public void onSuccess(@Nullable String result) {
}
};
ThreadUtils.executeByCpuWithDelay(task, 20, TimeUnit.SECONDS);
// task.cancel();
// ThreadUtils.cancel(task);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册