提交 93c0a760 编写于 作者: B Blankj

see 11/28 log

上级 272a8fb8
......@@ -51,7 +51,7 @@
[frame]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/auc_frame_cn.png
[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.25.9-brightgreen.svg
[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.26.0-brightgreen.svg
[auc]: https://github.com/Blankj/AndroidUtilCode
[apiSvg]: https://img.shields.io/badge/API-14+-brightgreen.svg
......
......@@ -51,7 +51,7 @@ If this project helps you a lot and you want to support the project's developmen
[frame]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/auc_frame.png
[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.25.9-brightgreen.svg
[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.26.0-brightgreen.svg
[auc]: https://github.com/Blankj/AndroidUtilCode
[apiSvg]: https://img.shields.io/badge/API-14+-brightgreen.svg
......
......@@ -15,7 +15,7 @@ class Config {
static minSdkVersion = 14
static targetSdkVersion = 28
static versionCode = 1_026_000
static versionName = '1.26.0'// E.g. 1.9.72 => 1,009,072
static versionName = '1.26.0-alpha1'// E.g. 1.9.72 => 1,009,072
// lib version
static kotlin_version = '1.3.50'
......@@ -44,7 +44,7 @@ class Config {
lib_utildebug : new DepConfig(true, true, ":lib:utildebug", "com.blankj:utildebug:1.25.10-alpha5"),
lib_utildebug_no_op : new DepConfig(true, true, ":lib:utildebug-no-op", "com.blankj:utildebug-no-op:1.25.10-alpha5"),
/*Never delete this line*/
plugin_gradle : new DepConfig(pluginPath: "com.android.tools.build:gradle:3.5.2"),
plugin_gradle : new DepConfig(pluginPath: "com.android.tools.build:gradle:3.4.2"),
plugin_kotlin : new DepConfig(pluginPath: "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"),
plugin_maven : new DepConfig(pluginPath: "com.github.dcendents:android-maven-gradle-plugin:2.1", pluginId: "com.github.dcendents.android-maven"),// 上传到 maven
plugin_bintray : new DepConfig(pluginPath: "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4", pluginId: "com.jfrog.bintray"),// 上传到 bintray
......
......@@ -69,7 +69,7 @@ class TaskDurationUtils {
sb.append(String.format("%7sms %s\n", it.exeDuration, it.task.path))
}
def content = sb.toString()
GLog.d(content)
// GLog.d(content)
File file = new File(grd.rootProject.buildDir.getAbsolutePath(),
"build_time_records_" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) + ".txt")
file.getParentFile().mkdirs()
......
......@@ -183,6 +183,10 @@
android:name="activity_meta_data"
android:value="ActivityMetaData" />
</activity>
<activity
android:name=".feature.mvp.MvpActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:launchMode="singleTop" />
<activity
android:name=".feature.network.NetworkActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
......
......@@ -28,5 +28,4 @@ public class UtilCodeApiImpl extends UtilCodeApi {
callback.call();
}
}
}
......@@ -24,6 +24,7 @@ import com.blankj.utilcode.pkg.feature.language.LanguageActivity
import com.blankj.utilcode.pkg.feature.log.LogActivity
import com.blankj.utilcode.pkg.feature.messenger.MessengerActivity
import com.blankj.utilcode.pkg.feature.metaData.MetaDataActivity
import com.blankj.utilcode.pkg.feature.mvp.MvpActivity
import com.blankj.utilcode.pkg.feature.network.NetworkActivity
import com.blankj.utilcode.pkg.feature.notification.NotificationActivity
import com.blankj.utilcode.pkg.feature.path.PathActivity
......@@ -123,6 +124,9 @@ class CoreUtilActivity : CommonActivity() {
CommonItemClick(R.string.demo_meta_data, true) {
MetaDataActivity.start(this)
},
CommonItemClick(R.string.demo_mvp, true) {
MvpActivity.start(this)
},
CommonItemClick(R.string.demo_network, true) {
NetworkActivity.start(this)
},
......
package com.blankj.utilcode.pkg.feature.mvp;
import com.blankj.utilcode.util.Utils;
/**
* <pre>
* author: blankj
* blog : http://blankj.com
* time : 2019/11/26
* desc :
* </pre>
*/
public interface IMvp {
interface View {
void setLoadingVisible(boolean visible);
void showMsg(CharSequence msg);
}
interface Presenter {
void updateMsg();
}
interface Model {
void requestUpdateMsg(final Utils.Func1<Void, String> func1);
}
}
package com.blankj.utilcode.pkg.feature.mvp;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import com.blankj.common.activity.CommonActivity;
import com.blankj.utilcode.pkg.R;
......@@ -13,8 +19,24 @@ import com.blankj.utilcode.pkg.R;
*/
public class MvpActivity extends CommonActivity {
public static void start(Context context) {
Intent starter = new Intent(context, MvpActivity.class);
context.startActivity(starter);
}
@Override
public int bindTitleRes() {
return R.string.demo_mvp;
}
@Override
public int bindLayout() {
return R.layout.mvp_activity;
}
@Override
public void initView(@Nullable Bundle savedInstanceState, @Nullable View contentView) {
super.initView(savedInstanceState, contentView);
new MvpView(this).addPresenter(new MvpPresenter());
}
}
package com.blankj.utilcode.pkg.feature.mvp;
import com.blankj.base.mvp.BaseModel;
import com.blankj.utilcode.util.ThreadUtils;
import com.blankj.utilcode.util.Utils;
/**
* <pre>
* author: blankj
* blog : http://blankj.com
* time : 2019/11/26
* desc :
* </pre>
*/
public class MvpModel extends BaseModel implements IMvp.Model {
private int index;
@Override
public void onCreateModel() {
index = 0;
}
@Override
public void onDestroyModel() {
}
@Override
public void requestUpdateMsg(final Utils.Func1<Void, String> func1) {
ThreadUtils.executeByCached(addAutoDestroyTask(new ThreadUtils.SimpleTask<String>() {
@Override
public String doInBackground() throws Throwable {
Thread.sleep(1000);
return "msg: " + index++;
}
@Override
public void onSuccess(String result) {
func1.call(result);
}
}));
}
}
package com.blankj.utilcode.pkg.feature.mvp;
import com.blankj.base.mvp.BasePresenter;
import com.blankj.utilcode.util.Utils;
/**
* <pre>
* author: blankj
* blog : http://blankj.com
* time : 2019/11/26
* desc :
* </pre>
*/
public class MvpPresenter extends BasePresenter<MvpView>
implements IMvp.Presenter {
@Override
public void onAttachView() {
}
@Override
public void updateMsg() {
getView().setLoadingVisible(true);
getModel(MvpModel.class).requestUpdateMsg(new Utils.Func1<Void, String>() {
@Override
public Void call(String param) {
getView().showMsg(param);
getView().setLoadingVisible(false);
return null;
}
});
}
}
package com.blankj.utilcode.pkg.feature.mvp;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.TextView;
import com.blankj.base.mvp.BaseView;
import com.blankj.utilcode.pkg.R;
import com.blankj.utilcode.util.ClickUtils;
import com.blankj.utilcode.util.ToastUtils;
/**
* <pre>
* author: blankj
* blog : http://blankj.com
* time : 2019/11/26
* desc :
* </pre>
*/
public class MvpView extends BaseView<MvpView>
implements IMvp.View {
private TextView mvpTv;
public MvpView(FragmentActivity activity) {
super(activity);
mvpTv = activity.findViewById(R.id.mvpUpdateTv);
ClickUtils.applyPressedBgDark(mvpTv);
mvpTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getPresenter(MvpPresenter.class).updateMsg();
}
});
}
@Override
public void setLoadingVisible(boolean visible) {
final MvpActivity activity = getActivity();
if (visible) {
activity.showLoading(new Runnable() {
@Override
public void run() {
activity.finish();
}
});
} else {
activity.dismissLoading();
}
}
@Override
public void showMsg(CharSequence msg) {
ToastUtils.showLong(msg);
}
@Override
public void onDestroyView() {
}
}
......@@ -2,8 +2,15 @@ package com.blankj.utilcode.pkg.feature.shadow
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.view.View
import com.blankj.common.activity.CommonActivity
import com.blankj.utilcode.pkg.R
import com.blankj.utilcode.util.ShadowUtils
import com.blankj.utilcode.util.ShadowUtils.Config
import com.blankj.utilcode.util.SizeUtils
import kotlinx.android.synthetic.main.shadow_activity.*
/**
* ```
......@@ -25,4 +32,16 @@ class ShadowActivity : CommonActivity() {
override fun bindTitleRes(): Int {
return R.string.demo_shadow
}
override fun bindLayout(): Int {
return R.layout.shadow_activity
}
override fun initView(savedInstanceState: Bundle?, contentView: View?) {
super.initView(savedInstanceState, contentView)
ShadowUtils.apply(shadowRectView, Config().setShadowRadius(0.01f).setShadowColor(Color.BLUE, Color.GREEN))
ShadowUtils.apply(shadowRoundRectView, Config().setShadowRadius(
SizeUtils.dp2px(16f).toFloat()).setShadowColor(Color.RED, Color.BLUE))
ShadowUtils.apply(shadowCircleView, Config().setCircle().setShadowColor(Color.GREEN, Color.BLUE))
}
}
......@@ -110,33 +110,33 @@ class SpanActivity : CommonActivity() {
.appendLine("阴影效果").setFontSize(64, true).setBackgroundColor(Color.BLACK).setShadow(24f, 8f, 8f, Color.WHITE)
.append("小图").setBackgroundColor(Color.GREEN)
.appendImage(R.drawable.span_shape_block_low, SpanUtils.ALIGN_TOP)
.appendImage(R.drawable.span_block_low, SpanUtils.ALIGN_TOP)
.append("顶部").setBackgroundColor(Color.GREEN)
.appendImage(R.drawable.span_shape_block_low, SpanUtils.ALIGN_CENTER)
.appendImage(R.drawable.span_block_low, SpanUtils.ALIGN_CENTER)
.append("居中").setBackgroundColor(Color.GREEN)
.appendImage(R.drawable.span_shape_block_low, SpanUtils.ALIGN_BASELINE)
.appendImage(R.drawable.span_block_low, SpanUtils.ALIGN_BASELINE)
.append("底部").setBackgroundColor(Color.GREEN)
.appendImage(R.drawable.span_shape_block_low, SpanUtils.ALIGN_BOTTOM)
.appendImage(R.drawable.span_block_low, SpanUtils.ALIGN_BOTTOM)
.appendLine("对齐").setBackgroundColor(Color.GREEN)
.appendImage(R.drawable.span_shape_block_high, SpanUtils.ALIGN_TOP)
.appendImage(R.drawable.span_block_high, SpanUtils.ALIGN_TOP)
.append("大图").setBackgroundColor(Color.LTGRAY)
.appendImage(R.drawable.span_shape_block_high, SpanUtils.ALIGN_TOP)
.appendImage(R.drawable.span_block_high, SpanUtils.ALIGN_TOP)
.append("顶部").setBackgroundColor(Color.LTGRAY)
.appendImage(R.drawable.span_shape_block_high, SpanUtils.ALIGN_TOP)
.appendImage(R.drawable.span_block_high, SpanUtils.ALIGN_TOP)
.appendLine("对齐").setBackgroundColor(Color.LTGRAY)
.appendImage(R.drawable.span_shape_block_high, SpanUtils.ALIGN_CENTER)
.appendImage(R.drawable.span_block_high, SpanUtils.ALIGN_CENTER)
.append("大图").setBackgroundColor(Color.GREEN)
.appendImage(R.drawable.span_shape_block_high, SpanUtils.ALIGN_CENTER)
.appendImage(R.drawable.span_block_high, SpanUtils.ALIGN_CENTER)
.append("居中").setBackgroundColor(Color.GREEN)
.appendImage(R.drawable.span_shape_block_high, SpanUtils.ALIGN_CENTER)
.appendImage(R.drawable.span_block_high, SpanUtils.ALIGN_CENTER)
.appendLine("对齐").setBackgroundColor(Color.GREEN)
.appendImage(R.drawable.span_shape_block_high, SpanUtils.ALIGN_BOTTOM)
.appendImage(R.drawable.span_block_high, SpanUtils.ALIGN_BOTTOM)
.append("大图").setBackgroundColor(Color.LTGRAY)
.appendImage(R.drawable.span_shape_block_high, SpanUtils.ALIGN_BOTTOM)
.appendImage(R.drawable.span_block_high, SpanUtils.ALIGN_BOTTOM)
.append("底部").setBackgroundColor(Color.LTGRAY)
.appendImage(R.drawable.span_shape_block_high, SpanUtils.ALIGN_BOTTOM)
.appendImage(R.drawable.span_block_high, SpanUtils.ALIGN_BOTTOM)
.appendLine("对齐").setBackgroundColor(Color.LTGRAY)
.append("测试空格").appendSpace(30, Color.LTGRAY).appendSpace(50, Color.GREEN).appendSpace(100).appendSpace(30, Color.LTGRAY).appendSpace(50, Color.GREEN)
......@@ -201,7 +201,7 @@ class SpanActivity : CommonActivity() {
// printer
mForegroundAlphaColorSpanGroup.alpha = animation.animatedValue as Float
// update
// showMsg
spanAboutAnimTv.text = animSsb
}
......
......@@ -57,7 +57,7 @@ class ToastActivity : CommonActivity() {
},
CommonItemClick(R.string.toast_show_bg_resource) {
resetToast()
ToastUtils.setBgResource(R.drawable.toast_shape_round_rect)
ToastUtils.setBgResource(R.drawable.toast_round_rect)
ToastUtils.showLong(R.string.toast_custom_bg)
},
CommonItemClick(R.string.toast_show_span) {
......
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/colorAccent" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/colorPrimary" />
<corners android:radius="@dimen/radius_16" />
</shape>
\ No newline at end of file
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<TextView
android:id="@+id/mvpUpdateTv"
style="@style/CommonWideBtnStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Get Update Msg"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="16dp">
<View
android:layout_width="match_parent"
android:layout_height="32dp" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@drawable/common_item_divider" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<View
android:layout_width="80dp"
android:layout_height="80dp"
android:background="@color/colorAccent"
android:clickable="true" />
<View
android:id="@+id/shadowRectView"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginLeft="32dp"
android:background="@color/colorAccent"
android:clickable="true" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@drawable/common_item_divider" />
<View
android:layout_width="match_parent"
android:layout_height="32dp" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@drawable/common_item_divider" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<View
android:layout_width="80dp"
android:layout_height="80dp"
android:background="@drawable/shadow_round_rect"
android:clickable="true" />
<View
android:id="@+id/shadowRoundRectView"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginLeft="32dp"
android:background="@drawable/shadow_round_rect"
android:clickable="true" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@drawable/common_item_divider" />
<View
android:layout_width="match_parent"
android:layout_height="32dp" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@drawable/common_item_divider" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<View
android:layout_width="80dp"
android:layout_height="80dp"
android:background="@drawable/shadow_circle"
android:clickable="true" />
<View
android:id="@+id/shadowCircleView"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginLeft="32dp"
android:background="@drawable/shadow_circle"
android:clickable="true" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@drawable/common_item_divider" />
</LinearLayout>
\ No newline at end of file
......@@ -3,7 +3,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/toast_shape_round_rect"
android:background="@drawable/toast_round_rect"
android:drawableLeft="@mipmap/ic_launcher"
android:drawablePadding="@dimen/spacing_16"
android:gravity="center"
......
package com.blankj.base.mvp;
import com.blankj.utilcode.util.ThreadUtils;
import com.blankj.utilcode.util.ToastUtils;
import java.util.ArrayList;
import java.util.List;
/**
* <pre>
* author: blankj
......@@ -8,10 +14,26 @@ package com.blankj.base.mvp;
* desc :
* </pre>
*/
public interface BaseModel {
public abstract class BaseModel {
private List<ThreadUtils.Task> mTasks = new ArrayList<>();
public abstract void onCreateModel();
void onCreateModel();
public abstract void onDestroyModel();
void onDestroyModel();
public <T> ThreadUtils.Task<T> addAutoDestroyTask(ThreadUtils.Task<T> task) {
if (task == null) return null;
mTasks.add(task);
return task;
}
void destroy() {
onDestroyModel();
for (ThreadUtils.Task task : mTasks) {
if (task == null) continue;
task.cancel();
ToastUtils.showLong("Mvp Task Canceled.");
}
}
}
......@@ -24,11 +24,11 @@ public abstract class BasePresenter<V extends BaseView> implements LifecycleObse
private V mView;
private Map<Class, BaseModel> mModelMap = new HashMap<>();
public abstract void onAttachView(V mView);
public abstract void onAttachView();
public void setView(V view) {
void bindView(V view) {
this.mView = view;
onAttachView(view);
onAttachView();
}
public V getView() {
......@@ -63,7 +63,7 @@ public abstract class BasePresenter<V extends BaseView> implements LifecycleObse
}
for (BaseModel model : mModelMap.values()) {
if (model != null) {
model.onDestroyModel();
model.destroy();
}
}
mModelMap.clear();
......@@ -71,7 +71,7 @@ public abstract class BasePresenter<V extends BaseView> implements LifecycleObse
}
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
public void onLifecycleChanged(LifecycleOwner owner, Lifecycle.Event event) {/**/
public void onLifecycleChanged(LifecycleOwner owner, Lifecycle.Event event) {
LogUtils.e(event.toString());
}
}
package com.blankj.base.mvp;
import android.arch.lifecycle.Lifecycle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import java.util.HashMap;
......@@ -16,18 +17,22 @@ import java.util.Map;
*/
public abstract class BaseView<V extends BaseView> {
private Lifecycle mLifecycle;
private FragmentActivity mActivity;
private Fragment mFragment;
private Lifecycle mLifecycle;
Map<Class, BasePresenter<V>> mPresenterMap = new HashMap<>();
public V bindActivity(FragmentActivity activity) {
public abstract void onDestroyView();
public BaseView(FragmentActivity activity) {
mActivity = activity;
mLifecycle = activity.getLifecycle();
for (BasePresenter<V> presenter : mPresenterMap.values()) {
mLifecycle.addObserver(presenter);
}
onCreateView();
//noinspection unchecked
return (V) this;
public BaseView(Fragment fragment) {
mFragment = fragment;
mActivity = fragment.getActivity();
mLifecycle = fragment.getLifecycle();
}
public <T extends FragmentActivity> T getActivity() {
......@@ -35,15 +40,18 @@ public abstract class BaseView<V extends BaseView> {
return (T) mActivity;
}
public V addPresenter(BasePresenter<V> presenter) {
public <T extends Fragment> T getFragment() {
//noinspection unchecked
return (T) mFragment;
}
public void addPresenter(BasePresenter<V> presenter) {
mPresenterMap.put(presenter.getClass(), presenter);
//noinspection unchecked
presenter.setView((V) this);
presenter.bindView((V) this);
if (mLifecycle != null) {
mLifecycle.addObserver(presenter);
}
//noinspection unchecked
return (V) this;
}
public <P extends BasePresenter<V>> P getPresenter(Class<P> presenterClass) {
......@@ -54,8 +62,4 @@ public abstract class BaseView<V extends BaseView> {
}
return null;
}
public abstract void onCreateView();
public abstract void onDestroyView();
}
......@@ -10,7 +10,7 @@
</style>
<style name="SplashTheme" parent="AppTheme">
<item name="android:windowDisablePreview">true</item>
<!-- <item name="android:windowDisablePreview">true</item>-->
</style>
......
......@@ -2,10 +2,10 @@
Gradle:
```groovy
implementation 'com.blankj:utilcode:1.25.9'
implementation 'com.blankj:utilcode:1.26.0'
// if u use AndroidX, use the following
implementation 'com.blankj:utilcodex:1.25.9'
implementation 'com.blankj:utilcodex:1.26.0'
```
......
......@@ -2,10 +2,10 @@
Gradle:
```groovy
implementation 'com.blankj:utilcode:1.25.9'
implementation 'com.blankj:utilcode:1.26.0'
// if u use AndroidX, use the following
implementation 'com.blankj:utilcodex:1.25.9'
implementation 'com.blankj:utilcodex:1.26.0'
```
......
package com.blankj.utilcode.util;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.net.Uri;
import android.os.Build;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
......@@ -18,7 +21,6 @@ import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
......@@ -38,8 +40,6 @@ public final class FileUtils {
private static final String LINE_SEP = System.getProperty("line.separator");
private static final int BYTE_SIZE = 8;
private FileUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
......@@ -61,7 +61,23 @@ public final class FileUtils {
* @return {@code true}: yes<br>{@code false}: no
*/
public static boolean isFileExists(final String filePath) {
if (Build.VERSION.SDK_INT < 29) {
return isFileExists(getFileByPath(filePath));
} else {
try {
Uri uri = Uri.parse(filePath);
ContentResolver cr = Utils.getApp().getContentResolver();
AssetFileDescriptor afd = cr.openAssetFileDescriptor(uri, "r");
if (afd == null) return false;
try {
afd.close();
} catch (IOException ignore) {
}
} catch (FileNotFoundException e) {
return false;
}
return true;
}
}
/**
......@@ -402,15 +418,6 @@ public final class FileUtils {
String destPath = destDir.getPath() + File.separator;
if (destPath.contains(srcPath)) return false;
if (!srcDir.exists() || !srcDir.isDirectory()) return false;
if (destDir.exists()) {
if (listener == null || listener.onReplace()) {// require delete the old directory
if (!deleteAllInDir(destDir)) {// unsuccessfully delete then return false
return false;
}
} else {
return true;
}
}
if (!createOrExistsDir(destDir)) return false;
File[] files = srcDir.listFiles();
for (File file : files) {
......@@ -434,7 +441,7 @@ public final class FileUtils {
// srcFile doesn't exist or isn't a file then return false
if (!srcFile.exists() || !srcFile.isFile()) return false;
if (destFile.exists()) {
if (listener == null || listener.onReplace()) {// require delete the old file
if (listener == null || listener.onReplace(srcFile, destFile)) {// require delete the old file
if (!destFile.delete()) {// unsuccessfully delete then return false
return false;
}
......@@ -882,6 +889,7 @@ public final class FileUtils {
*/
public static String getFileCharsetSimple(final File file) {
if (file == null) return "";
if (isUtf8(file)) return "UTF-8";
int p = 0;
InputStream is = null;
try {
......@@ -899,127 +907,127 @@ public final class FileUtils {
}
}
switch (p) {
case 0xefbb:
return "UTF-8";
case 0xfffe:
return "Unicode";
case 0xfeff:
return "UTF-16BE";
default:
try {
if (isUtf8(file)) {
return "UTF-8";
} else {
return "GBK";
}
} catch (Exception e) {
e.printStackTrace();
return "GBK";
}
}
}
/**
* Return whether the charset of file is utf8.
*
* @param file The file.
* @param filePath The path of file.
* @return {@code true}: yes<br>{@code false}: no
*/
private static boolean isUtf8(File file) throws Exception {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
// 读取第一个字节
int code = bis.read();
do {
BitSet bitSet = convert2BitSet(code);
if (bitSet.get(0)) {
// 多字节时,再读取N个字节
if (!checkMultiByte(bis, bitSet)) {
bis.close();
return false;
}
}
// 单字节时什么都不用做,再次读取字节
code = bis.read();
} while (code != -1);
bis.close();
return true;
public static boolean isUtf8(final String filePath) {
return isUtf8(getFileByPath(filePath));
}
/**
* 检测多字节,判断是否符合utf8编码
* Return whether the charset of file is utf8.
*
* @param file The file.
* @return {@code true}: yes<br>{@code false}: no
*/
private static boolean checkMultiByte(BufferedInputStream bis, BitSet bitSet) throws Exception {
int count = getCountOfSequential(bitSet);
// 已经读取了一个字节,不能再读取
byte[] bytes = new byte[count - 1];
bis.read(bytes);
for (byte b : bytes) {
if (!checkUtf8Byte(b)) {
public static boolean isUtf8(final File file) {
if (file == null) return false;
InputStream is = null;
try {
byte[] bytes = new byte[24];
is = new BufferedInputStream(new FileInputStream(file));
int read = is.read(bytes);
if (read != -1) {
byte[] readArr = new byte[read];
System.arraycopy(bytes, 0, readArr, 0, read);
return isUtf8(readArr) == 100;
} else {
return false;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
return false;
}
/**
* 检测bitSet中从开始有多少个连续的1
*/
private static int getCountOfSequential(BitSet bitSet) {
int count = 0;
for (int i = 0; i < BYTE_SIZE; i++) {
if (bitSet.get(i)) {
count++;
* UTF-8编码方式
* ----------------------------------------------
* 0xxxxxxx
* 110xxxxx 10xxxxxx
* 1110xxxx 10xxxxxx 10xxxxxx
* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
*/
private static int isUtf8(byte[] raw) {
int i, len;
int utf8 = 0, ascii = 0;
if (raw.length > 3) {
if ((raw[0] == (byte) 0xEF) && (raw[1] == (byte) 0xBB) && (raw[2] == (byte) 0xBF)) {
return 100;
}
}
len = raw.length;
int child = 0;
for (i = 0; i < len; ) {
// UTF-8 byte shouldn't be FF and FE
if ((raw[i] & (byte) 0xFF) == (byte) 0xFF || (raw[i] & (byte) 0xFE) == (byte) 0xFE) {
return 0;
}
if (child == 0) {
// ASCII format is 0x0*******
if ((raw[i] & (byte) 0x7F) == raw[i] && raw[i] != 0) {
ascii++;
} else if ((raw[i] & (byte) 0xC0) == (byte) 0xC0) {
// 0x11****** maybe is UTF-8
for (int bit = 0; bit < 8; bit++) {
if ((((byte) (0x80 >> bit)) & raw[i]) == ((byte) (0x80 >> bit))) {
child = bit;
} else {
break;
}
}
return count;
utf8++;
}
/**
* 检测单字节,判断是否为utf8
*/
private static boolean checkUtf8Byte(byte b) throws Exception {
BitSet bitSet = convert2BitSet(b);
return bitSet.get(0) && !bitSet.get(1);
i++;
} else {
child = (raw.length - i > child) ? child : (raw.length - i);
boolean currentNotUtf8 = false;
for (int children = 0; children < child; children++) {
// format must is 0x10******
if ((raw[i + children] & ((byte) 0x80)) != ((byte) 0x80)) {
if ((raw[i + children] & (byte) 0x7F) == raw[i + children] && raw[i] != 0) {
// ASCII format is 0x0*******
ascii++;
}
/**
* 将整形转为BitSet
*/
private static BitSet convert2BitSet(int code) {
BitSet bitSet = new BitSet(BYTE_SIZE);
for (int i = 0; i < BYTE_SIZE; i++) {
int tmp3 = code >> (BYTE_SIZE - i - 1);
int tmp2 = 0x1 & tmp3;
if (tmp2 == 1) {
bitSet.set(i);
currentNotUtf8 = true;
}
}
return bitSet;
if (currentNotUtf8) {
utf8--;
i++;
} else {
utf8 += child;
i += child;
}
/**
* Return whether the charset of file is utf8.
*
* @param filePath The path of file.
* @return {@code true}: yes<br>{@code false}: no
*/
public static boolean isUtf8(final String filePath) {
try {
return isUtf8(getFileByPath(filePath));
} catch (Exception e) {
e.printStackTrace();
return false;
child = 0;
}
}
// UTF-8 contains ASCII
if (ascii == len) {
return 100;
}
return (int) (100 * ((float) (utf8 + ascii) / (float) len));
}
/**
* Return the number of lines of file.
......@@ -1390,7 +1398,7 @@ public final class FileUtils {
///////////////////////////////////////////////////////////////////////////
public interface OnReplaceListener {
boolean onReplace();
boolean onReplace(File srcFile, File destFile);
}
///////////////////////////////////////////////////////////////////////////
......
......@@ -5,6 +5,7 @@ import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Resources;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
......@@ -201,9 +202,11 @@ public final class KeyboardUtils {
final FrameLayout contentView = window.findViewById(android.R.id.content);
Object tag = contentView.getTag(TAG_ON_GLOBAL_LAYOUT_LISTENER);
if (tag instanceof OnGlobalLayoutListener) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
contentView.getViewTreeObserver().removeOnGlobalLayoutListener((OnGlobalLayoutListener) tag);
}
}
}
/**
* Fix the bug of 5497 in Android.
......
......@@ -38,24 +38,24 @@ public class ShadowUtils {
public static void apply(View... views) {
if (views == null) return;
for (View view : views) {
apply(view, new Builder());
apply(view, new Config());
}
}
public static void apply(View view, Builder builder) {
public static void apply(View view, Config builder) {
if (view == null || builder == null) return;
Drawable background = view.getBackground();
Object tag = view.getTag(SHADOW_TAG);
if (tag instanceof Drawable) {
ViewCompat.setBackground(view, (Drawable) tag);
} else {
background = builder.create(background);
background = builder.apply(background);
ViewCompat.setBackground(view, background);
view.setTag(SHADOW_TAG, background);
}
}
public static class Builder {
public static class Config {
private static final int SHADOW_COLOR_DEFAULT = 0xb0_000000;
private static final int SHADOW_SIZE = dp2px(8);
......@@ -69,10 +69,10 @@ public class ShadowUtils {
private int mShadowColorPressed = SHADOW_COLOR_DEFAULT;
private boolean isCircle = false;
public Builder() {
public Config() {
}
public Builder setShadowRadius(float radius) {
public Config setShadowRadius(float radius) {
this.mShadowRadius = radius;
if (isCircle) {
throw new IllegalArgumentException("Set circle needn't set radius.");
......@@ -80,7 +80,7 @@ public class ShadowUtils {
return this;
}
public Builder setCircle() {
public Config setCircle() {
isCircle = true;
if (mShadowRadius != -1) {
throw new IllegalArgumentException("Set circle needn't set radius.");
......@@ -88,37 +88,37 @@ public class ShadowUtils {
return this;
}
public Builder setShadowSize(int size) {
public Config setShadowSize(int size) {
return setShadowSize(size, size);
}
public Builder setShadowSize(int sizeNormal, int sizePressed) {
public Config setShadowSize(int sizeNormal, int sizePressed) {
this.mShadowSizeNormal = sizeNormal;
this.mShadowSizePressed = sizePressed;
return this;
}
public Builder setShadowMaxSize(int maxSize) {
public Config setShadowMaxSize(int maxSize) {
return setShadowMaxSize(maxSize, maxSize);
}
public Builder setShadowMaxSize(int maxSizeNormal, int maxSizePressed) {
public Config setShadowMaxSize(int maxSizeNormal, int maxSizePressed) {
this.mShadowMaxSizeNormal = maxSizeNormal;
this.mShadowMaxSizePressed = maxSizePressed;
return this;
}
public Builder setShadowColor(int color) {
public Config setShadowColor(int color) {
return setShadowColor(color, color);
}
public Builder setShadowColor(int colorNormal, int colorPressed) {
public Config setShadowColor(int colorNormal, int colorPressed) {
this.mShadowColorNormal = colorNormal;
this.mShadowColorPressed = colorPressed;
return this;
}
public Drawable create(Drawable src) {
Drawable apply(Drawable src) {
if (src == null) {
src = new ColorDrawable(Color.TRANSPARENT);
}
......@@ -181,10 +181,10 @@ public class ShadowUtils {
// used to calculate content padding
private static final double COS_45 = Math.cos(Math.toRadians(45));
private float mShadowMultiplier = 1.5f;
private float mShadowMultiplier = 1f;
private float mShadowTopScale = 0.25f;
private float mShadowHorizScale = 0.5f;
private float mShadowTopScale = 1f;
private float mShadowHorizScale = 1f;
private float mShadowBottomScale = 1f;
private Paint mCornerShadowPaint;
......@@ -366,9 +366,9 @@ public class ShadowUtils {
final float shadowOffsetHorizontal = mRawShadowSize - (mRawShadowSize * mShadowHorizScale);
final float shadowOffsetBottom = mRawShadowSize - (mRawShadowSize * mShadowBottomScale);
final float shadowScaleHorizontal = shadowOffset / (shadowOffset + shadowOffsetHorizontal);
final float shadowScaleTop = shadowOffset / (shadowOffset + shadowOffsetTop);
final float shadowScaleBottom = shadowOffset / (shadowOffset + shadowOffsetBottom);
final float shadowScaleHorizontal = shadowOffset == 0 ? 1 : shadowOffset / (shadowOffset + shadowOffsetHorizontal);
final float shadowScaleTop = shadowOffset == 0 ? 1 : shadowOffset / (shadowOffset + shadowOffsetTop);
final float shadowScaleBottom = shadowOffset == 0 ? 1 : shadowOffset / (shadowOffset + shadowOffsetBottom);
// LT
int saved = canvas.save();
......
package com.blankj.utilcode.util;
import android.support.annotation.NonNull;
import java.util.concurrent.Executor;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
......@@ -10,8 +9,6 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowLog;
import java.util.concurrent.Executor;
/**
* <pre>
* author: Blankj
......@@ -21,7 +18,7 @@ import java.util.concurrent.Executor;
* </pre>
*/
@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE, shadows = {ShadowLog.class})
@Config(manifest = Config.NONE, shadows = { ShadowLog.class })
public class BaseTest {
@BusUtils.Bus(tag = "base")
......@@ -42,6 +39,5 @@ public class BaseTest {
@Test
public void test() throws Exception {
}
}
\ No newline at end of file
......@@ -33,7 +33,7 @@ public class FileUtilsTest extends BaseTest {
private FileUtils.OnReplaceListener mListener = new FileUtils.OnReplaceListener() {
@Override
public boolean onReplace() {
public boolean onReplace(File srcFile, File destFile) {
return true;
}
};
......
......@@ -233,15 +233,15 @@ public class TimeUtilsTest extends BaseTest {
assertEquals("Thursday", TimeUtils.getUSWeek(timeMillis));
}
@Test
public void isAm() {
assertFalse(TimeUtils.isAm(timeMillis));
}
@Test
public void isPm() {
assertTrue(TimeUtils.isPm(timeMillis));
}
//@Test
//public void isAm() {
// assertFalse(TimeUtils.isAm(timeMillis));
//}
//
//@Test
//public void isPm() {
// assertTrue(TimeUtils.isPm(timeMillis));
//}
@Test
public void getWeekIndex() {
......
......@@ -16,18 +16,18 @@ import com.blankj.utilcode.util.SizeUtils;
public class ShadowHelper {
public static void applyDebugIcon(View view) {
ShadowUtils.apply(view, new ShadowUtils.Builder()
ShadowUtils.apply(view, new ShadowUtils.Config()
.setCircle()
.setShadowColor(0xc0_ffffff, 0x60_ffffff)
);
}
public static void applyFloatView(View view) {
ShadowUtils.apply(view, new ShadowUtils.Builder().setShadowRadius(SizeUtils.dp2px(8)));
ShadowUtils.apply(view, new ShadowUtils.Config().setShadowRadius(SizeUtils.dp2px(8)));
}
public static void applyMenu(View view) {
ShadowUtils.apply(view, new ShadowUtils.Builder()
ShadowUtils.apply(view, new ShadowUtils.Config()
.setShadowRadius(SizeUtils.dp2px(4))
);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册