@ -1,51 +0,0 @@
|
|||||||
apply plugin: 'com.android.application'
|
|
||||||
|
|
||||||
android {
|
|
||||||
compileSdkVersion 26
|
|
||||||
defaultConfig {
|
|
||||||
applicationId "${package}"
|
|
||||||
minSdkVersion 23
|
|
||||||
targetSdkVersion 26
|
|
||||||
versionCode 1
|
|
||||||
versionName "1.0"
|
|
||||||
}
|
|
||||||
buildTypes {
|
|
||||||
release {
|
|
||||||
minifyEnabled false
|
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
android.applicationVariants.all { variant ->
|
|
||||||
variant.outputs.all {
|
|
||||||
outputFileName = rootProject.getName() + "-v" + defaultConfig.versionName + ".apk"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
|
||||||
|
|
||||||
//QMUI
|
|
||||||
implementation 'com.qmuiteam:qmui:1.1.3'
|
|
||||||
implementation "com.qmuiteam:arch:0.1.4"
|
|
||||||
//依赖注入框架
|
|
||||||
implementation 'com.jakewharton:butterknife:8.8.1'
|
|
||||||
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
|
|
||||||
//拍照,相册
|
|
||||||
implementation 'com.jph.takephoto:takephoto_library:4.0.3'
|
|
||||||
//图片查看
|
|
||||||
implementation 'com.github.chrisbanes:PhotoView:1.2.6'
|
|
||||||
//权限申请框架
|
|
||||||
implementation 'com.yanzhenjie:permission:2.0.0-rc12'
|
|
||||||
<#if qrcode>
|
|
||||||
//二维码
|
|
||||||
implementation 'com.google.zxing:core:3.3.2'
|
|
||||||
implementation'com.journeyapps:zxing-android-embedded:3.6.0'
|
|
||||||
</#if>
|
|
||||||
<#if fileselect>
|
|
||||||
//文件选择
|
|
||||||
implementation 'com.leon:lfilepickerlibrary:1.7.0'
|
|
||||||
</#if>
|
|
||||||
//Picker
|
|
||||||
implementation 'com.github.gzu-liyujiang.AndroidPicker:WheelPicker:1.5.6'
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
# Add project specific ProGuard rules here.
|
|
||||||
# You can control the set of applied configuration files using the
|
|
||||||
# proguardFiles setting in build.gradle.
|
|
||||||
#
|
|
||||||
# For more details, see
|
|
||||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
|
||||||
|
|
||||||
# If your project uses WebView with JS, uncomment the following
|
|
||||||
# and specify the fully qualified class name to the JavaScript interface
|
|
||||||
# class:
|
|
||||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
|
||||||
# public *;
|
|
||||||
#}
|
|
||||||
|
|
||||||
# Uncomment this to preserve the line number information for
|
|
||||||
# debugging stack traces.
|
|
||||||
#-keepattributes SourceFile,LineNumberTable
|
|
||||||
|
|
||||||
# If you keep the line number information, uncomment this to
|
|
||||||
# hide the original source file name.
|
|
||||||
#-renamesourcefileattribute SourceFile
|
|
@ -1,39 +0,0 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
package="${package}">
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
|
||||||
|
|
||||||
<application
|
|
||||||
android:name="${domain}.WBUIApplication"
|
|
||||||
android:allowBackup="true"
|
|
||||||
android:icon="@mipmap/ic_launcher"
|
|
||||||
android:label="@string/app_name_cn"
|
|
||||||
tools:replace="android:label"
|
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
|
||||||
android:supportsRtl="true"
|
|
||||||
android:theme="@style/AppTheme" >
|
|
||||||
<activity
|
|
||||||
android:name="${domain}.WBUIMainActivity"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:windowSoftInputMode="stateAlwaysHidden">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<#if fileselect>
|
|
||||||
<!--文件选择器-->
|
|
||||||
<activity android:name="${domain}.base.activity.FilePickerActivity" />
|
|
||||||
</#if>
|
|
||||||
<#if qrcode>
|
|
||||||
<!--二维码Activity-->
|
|
||||||
<activity android:name="${domain}.base.activity.QRcodeActivity" />
|
|
||||||
</#if>
|
|
||||||
<!--重启服务-->
|
|
||||||
<service android:name="${domain}.base.service.RestartService" />
|
|
||||||
</application>
|
|
||||||
|
|
||||||
|
|
||||||
</manifest>
|
|
@ -1,201 +0,0 @@
|
|||||||
package ${domain};
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.Application;
|
|
||||||
import android.content.pm.PackageInfo;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.location.Location;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.qmuiteam.qmui.util.QMUIDisplayHelper;
|
|
||||||
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
|
|
||||||
import com.qmuiteam.qmui.widget.dialog.QMUIDialogAction;
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import ${domain}.base.util.DataBaseUtil;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Application 入口。
|
|
||||||
*/
|
|
||||||
public class WBUIApplication extends Application implements Thread.UncaughtExceptionHandler {
|
|
||||||
|
|
||||||
private static WBUIApplication instance;
|
|
||||||
private WeakReference<Activity> currentActivity;
|
|
||||||
|
|
||||||
private DataBaseUtil db;
|
|
||||||
private Map<String, Object> map;
|
|
||||||
private Location mLocation;
|
|
||||||
|
|
||||||
private Toast toast;
|
|
||||||
protected Handler handler = new Handler();
|
|
||||||
|
|
||||||
public Location getLocation() {
|
|
||||||
return mLocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Handler getHandler() {
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static WBUIApplication getInstance() {
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Map getMap() {
|
|
||||||
return instance.map;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DataBaseUtil getDb() {
|
|
||||||
return db;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate() {
|
|
||||||
super.onCreate();
|
|
||||||
// if (LeakCanary.isInAnalyzerProcess(this)) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// LeakCanary.install(this);
|
|
||||||
instance = this;
|
|
||||||
initExceptionHandler();
|
|
||||||
initMap();
|
|
||||||
initLife();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void lozyInit() {
|
|
||||||
initDB();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initDB() {
|
|
||||||
db = new DataBaseUtil(this, new DataBaseUtil.Register() {
|
|
||||||
@Override
|
|
||||||
public List<Class> run() {
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initMap() {
|
|
||||||
map = new HashMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initLife() {
|
|
||||||
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityStarted(Activity activity) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityResumed(Activity activity) {
|
|
||||||
currentActivity = new WeakReference<Activity>(activity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityPaused(Activity activity) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityStopped(Activity activity) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityDestroyed(Activity activity) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initExceptionHandler() {
|
|
||||||
// 程序的默认处理器
|
|
||||||
Thread.setDefaultUncaughtExceptionHandler(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断是否安装插件
|
|
||||||
public boolean hasInstallPlugin(String packageName) {
|
|
||||||
try {
|
|
||||||
PackageInfo info = getPackageManager().getPackageInfo(packageName, 0);
|
|
||||||
return (info != null);
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 展示Toast消息。
|
|
||||||
*
|
|
||||||
* @param message 消息内容
|
|
||||||
*/
|
|
||||||
public synchronized void showToast(final String message) {
|
|
||||||
if (toast == null) {
|
|
||||||
toast = new Toast(this);
|
|
||||||
toast.setGravity(Gravity.CENTER, 0, 0);
|
|
||||||
TextView textView = new TextView(this);
|
|
||||||
textView.setTextColor(Color.parseColor("#ffffff"));
|
|
||||||
int padding = QMUIDisplayHelper.dp2px(this, 20);
|
|
||||||
textView.setPadding(padding, padding, padding, padding);
|
|
||||||
textView.setBackgroundColor(Color.parseColor("#aa131313"));
|
|
||||||
toast.setView(textView);
|
|
||||||
}
|
|
||||||
((TextView) toast.getView()).setText(message);
|
|
||||||
toast.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void uncaughtException(Thread thread, Throwable throwable) {
|
|
||||||
Log.e("error--->", "error : ", throwable);
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void confirm(String message, QMUIDialogAction.ActionListener actionListener) {
|
|
||||||
if (currentActivity != null) {
|
|
||||||
Activity activity = currentActivity.get();
|
|
||||||
QMUIDialog qmuiDialog = new QMUIDialog.MessageDialogBuilder(activity)
|
|
||||||
.setMessage(message)
|
|
||||||
.addAction("取消", new QMUIDialogAction.ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(QMUIDialog dialog, int index) {
|
|
||||||
dialog.dismiss();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.addAction("确定", actionListener)
|
|
||||||
.create(com.qmuiteam.qmui.R.style.QMUI_Dialog);
|
|
||||||
qmuiDialog.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void exit() {
|
|
||||||
confirm("确认退出?", new QMUIDialogAction.ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(QMUIDialog dialog, int index) {
|
|
||||||
dialog.dismiss();
|
|
||||||
android.os.Process.killProcess(android.os.Process.myPid());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
package ${domain};
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import ${package}.R;
|
|
||||||
import ${domain}.base.BaseSPAActivity;
|
|
||||||
<#if webview>
|
|
||||||
import ${domain}.fragment.WebViewFragment;
|
|
||||||
</#if>
|
|
||||||
<#if !webview>
|
|
||||||
import ${domain}.fragment.MainFragment;
|
|
||||||
</#if>
|
|
||||||
|
|
||||||
|
|
||||||
public class WBUIMainActivity extends BaseSPAActivity {
|
|
||||||
private static final String KEY_FRAGMENT = "key_fragment";
|
|
||||||
private static final int VALUE_FRAGMENT_HOME = 0;
|
|
||||||
private static final int VALUE_FRAGMENT_NOTCH_HELPER = 1;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getContextViewId() {
|
|
||||||
return R.id.main_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
<#if webview>
|
|
||||||
startFirstFragment(new WebViewFragment());
|
|
||||||
</#if>
|
|
||||||
<#if !webview>
|
|
||||||
startFirstFragment(new MainFragment());
|
|
||||||
</#if>
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
|||||||
package ${domain}.base;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Intent;
|
|
||||||
|
|
||||||
import java.util.Hashtable;
|
|
||||||
|
|
||||||
public abstract class BaseActivity extends Activity {
|
|
||||||
private Hashtable<Integer, IActivityResult> resultHashtable = new Hashtable<>();
|
|
||||||
private int mRequestCode = 1;
|
|
||||||
|
|
||||||
public void startForResult(Intent intent, IActivityResult activityResult) {
|
|
||||||
int requestCode = mRequestCode++;
|
|
||||||
resultHashtable.put(requestCode, activityResult);
|
|
||||||
startActivityForResult(intent, requestCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
if (resultHashtable.containsKey(requestCode)) {
|
|
||||||
IActivityResult i = resultHashtable.remove(requestCode);
|
|
||||||
if (i != null) {
|
|
||||||
i.onResult(resultCode, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
package ${domain}.base;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
import butterknife.Unbinder;
|
|
||||||
|
|
||||||
public abstract class BaseFragment extends Fragment {
|
|
||||||
private Unbinder unbinder;
|
|
||||||
protected Handler handler = new Handler();
|
|
||||||
|
|
||||||
protected abstract void initView();
|
|
||||||
|
|
||||||
protected abstract int getFragmnetLayout();
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
|
||||||
View inflate = LayoutInflater.from(getActivity()).inflate(getFragmnetLayout(), null);
|
|
||||||
unbinder = ButterKnife.bind(this, inflate);
|
|
||||||
initView();
|
|
||||||
return inflate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
unbinder.unbind();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,67 +0,0 @@
|
|||||||
package ${domain}.base;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
|
|
||||||
import com.qmuiteam.qmui.arch.QMUIFragmentActivity;
|
|
||||||
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
|
|
||||||
import com.qmuiteam.qmui.widget.dialog.QMUIDialogAction;
|
|
||||||
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
|
|
||||||
import java.util.Hashtable;
|
|
||||||
|
|
||||||
public abstract class BaseSPAActivity extends QMUIFragmentActivity {
|
|
||||||
|
|
||||||
protected QMUITipDialog loading;
|
|
||||||
|
|
||||||
private Hashtable<Integer, IActivityResult> resultHashtable = new Hashtable<>();
|
|
||||||
private int mRequestCode = 1;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
loading = new QMUITipDialog.Builder(this).setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING).setTipWord("加载中...").create();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showLoading() {
|
|
||||||
loading.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dismissLoading() {
|
|
||||||
loading.dismiss();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void confirmDialog(String messgae, QMUIDialogAction.ActionListener actionListener) {
|
|
||||||
new QMUIDialog.MessageDialogBuilder(this)
|
|
||||||
.setTitle("消息")
|
|
||||||
.setMessage(messgae)
|
|
||||||
.addAction("确定", actionListener)
|
|
||||||
.setCanceledOnTouchOutside(false)
|
|
||||||
.create(com.qmuiteam.qmui.R.style.QMUI_Dialog).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startForResult(Intent intent, IActivityResult activityResult) {
|
|
||||||
int requestCode = mRequestCode++;
|
|
||||||
resultHashtable.put(requestCode, activityResult);
|
|
||||||
startActivityForResult(intent, requestCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
if (resultHashtable.containsKey(requestCode)) {
|
|
||||||
IActivityResult i = resultHashtable.remove(requestCode);
|
|
||||||
if (i != null) {
|
|
||||||
i.onResult(resultCode, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void startFirstFragment(BaseSPAFragment fragment) {
|
|
||||||
getSupportFragmentManager()
|
|
||||||
.beginTransaction()
|
|
||||||
.add(getContextViewId(), fragment, fragment.getClass().getSimpleName())
|
|
||||||
.addToBackStack(fragment.getClass().getSimpleName())
|
|
||||||
.commit();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
package ${domain}.base;
|
|
||||||
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
|
|
||||||
public interface IActivityResult {
|
|
||||||
void onResult(int resultCode, Intent data);
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
package ${domain}.base.activity;
|
|
||||||
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import com.leon.lfilepickerlibrary.LFilePicker;
|
|
||||||
import com.leon.lfilepickerlibrary.utils.Constant;
|
|
||||||
import ${domain}.base.BaseSPAActivity;
|
|
||||||
|
|
||||||
public class FilePickerActivity extends BaseSPAActivity {
|
|
||||||
|
|
||||||
private static final int REQUESTCODE_FROM_ACTIVITY = 0;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getContextViewId() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
new LFilePicker()
|
|
||||||
.withActivity(this)
|
|
||||||
.withTitle("选择附件")
|
|
||||||
.withBackIcon(Constant.BACKICON_STYLETHREE)
|
|
||||||
.withRequestCode(REQUESTCODE_FROM_ACTIVITY)
|
|
||||||
.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
setResult(resultCode,data);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
package ${domain}.base.activity;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.PersistableBundle;
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
|
|
||||||
import ${package}.R;
|
|
||||||
import com.journeyapps.barcodescanner.CaptureManager;
|
|
||||||
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
|
|
||||||
|
|
||||||
public class QRcodeScanActivity extends Activity implements DecoratedBarcodeView.TorchListener {
|
|
||||||
|
|
||||||
private CaptureManager captureManager;
|
|
||||||
private DecoratedBarcodeView mDBV;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_qrcode_scan);
|
|
||||||
|
|
||||||
mDBV = (DecoratedBarcodeView) findViewById(R.id.dbv_custom);
|
|
||||||
mDBV.setTorchListener(this);
|
|
||||||
|
|
||||||
//重要代码,初始化捕获
|
|
||||||
captureManager = new CaptureManager(this, mDBV);
|
|
||||||
captureManager.initializeFromIntent(getIntent(), savedInstanceState);
|
|
||||||
captureManager.decode();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPause() {
|
|
||||||
super.onPause();
|
|
||||||
captureManager.onPause();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
captureManager.onResume();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
captureManager.onDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
|
|
||||||
super.onSaveInstanceState(outState, outPersistentState);
|
|
||||||
captureManager.onSaveInstanceState(outState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
||||||
return mDBV.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTorchOn() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTorchOff() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
package ${domain}.base.activity;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import ${domain}.base.Consant;
|
|
||||||
import ${domain}.base.util.StorageUtil;
|
|
||||||
import com.jph.takephoto.app.TakePhoto;
|
|
||||||
import com.jph.takephoto.compress.CompressConfig;
|
|
||||||
import com.jph.takephoto.model.TImage;
|
|
||||||
import com.jph.takephoto.model.TResult;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
public class TakePhotoActivity extends com.jph.takephoto.app.TakePhotoActivity {
|
|
||||||
|
|
||||||
public static final String POSITION_PARAM = "position_param";
|
|
||||||
public static final String POSITION_CAPTURE = "capture";
|
|
||||||
public static final String POSITION_GALLERY = "gallery";
|
|
||||||
public static final String POSITION_DOCUMENTS = "documents";
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
TakePhoto takePhoto = getTakePhoto();
|
|
||||||
configCompress(takePhoto);
|
|
||||||
Intent intent = getIntent();
|
|
||||||
String stringExtra = intent.getStringExtra(POSITION_PARAM);
|
|
||||||
if (POSITION_CAPTURE.equals(stringExtra)) {
|
|
||||||
takePhoto.onPickFromCapture(getImageCropUri());
|
|
||||||
} else if (POSITION_GALLERY.equals(stringExtra)) {
|
|
||||||
takePhoto.onPickFromGallery();
|
|
||||||
} else {
|
|
||||||
takePhoto.onPickFromDocuments();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//获得照片的输出保存Uri
|
|
||||||
private Uri getImageCropUri() {
|
|
||||||
File file = new File(StorageUtil.getOwnCacheDirectory(this, Consant.DIR_IMG), System.currentTimeMillis() + ".jpg");
|
|
||||||
if (!file.getParentFile().exists()) file.getParentFile().mkdirs();
|
|
||||||
return Uri.fromFile(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void configCompress(TakePhoto takePhoto) {//压缩配置
|
|
||||||
CompressConfig config = new CompressConfig.Builder().setMaxSize(512 * 1024)
|
|
||||||
.setMaxPixel(800)
|
|
||||||
.enableReserveRaw(false)//拍照压缩后是否显示原图
|
|
||||||
.create();
|
|
||||||
takePhoto.onEnableCompress(config, false);//是否显示进度条
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void takeSuccess(TResult result) {
|
|
||||||
TImage image = result.getImage();
|
|
||||||
Intent intent = new Intent();
|
|
||||||
intent.putExtra("path", image.getCompressPath() != null ? image.getCompressPath() : image.getOriginalPath());
|
|
||||||
setResult(RESULT_OK, intent);
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void takeFail(TResult result, String msg) {
|
|
||||||
super.takeFail(result, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void takeCancel() {
|
|
||||||
super.takeCancel();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
package ${domain}.base.service;
|
|
||||||
|
|
||||||
import android.app.Service;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.IBinder;
|
|
||||||
|
|
||||||
public class RestartService extends Service {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 重启整个APP
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param Delayed 延迟多少毫秒
|
|
||||||
*/
|
|
||||||
public static void restartAPP(Context context, long Delayed) {
|
|
||||||
|
|
||||||
// 开启服务,用来重启
|
|
||||||
Intent intent1 = new Intent(context, RestartService.class);
|
|
||||||
intent1.putExtra("PackageName", context.getPackageName());
|
|
||||||
intent1.putExtra("Delayed", Delayed);
|
|
||||||
context.startService(intent1);
|
|
||||||
|
|
||||||
// 杀死进程
|
|
||||||
android.os.Process.killProcess(android.os.Process.myPid());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 应用关闭重启时间
|
|
||||||
*/
|
|
||||||
private static long stopDelayed = 1000;
|
|
||||||
|
|
||||||
private Handler handler;
|
|
||||||
|
|
||||||
private String PackageName;
|
|
||||||
|
|
||||||
public RestartService() {
|
|
||||||
handler = new Handler();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int onStartCommand(final Intent intent, int flags, int startId) {
|
|
||||||
stopDelayed = intent.getLongExtra("Delayed", 1000);
|
|
||||||
PackageName = intent.getStringExtra("PackageName");
|
|
||||||
handler.postDelayed(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage(PackageName);
|
|
||||||
startActivity(LaunchIntent);
|
|
||||||
RestartService.this.stopSelf();
|
|
||||||
}
|
|
||||||
}, stopDelayed);
|
|
||||||
return super.onStartCommand(intent, flags, startId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IBinder onBind(Intent intent) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,123 +0,0 @@
|
|||||||
package ${domain}.base.ui;
|
|
||||||
|
|
||||||
import android.app.Dialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.Window;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
|
|
||||||
public class WBUICustomDialog extends Dialog {
|
|
||||||
public WBUICustomDialog(Context context) {
|
|
||||||
super(context);
|
|
||||||
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
|
||||||
this.getWindow().getDecorView().setPadding(0, 0, 0, 0);
|
|
||||||
this.getWindow().getDecorView().setBackground(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setContentView(View view, ViewGroup.LayoutParams params) {
|
|
||||||
if (params.width == ViewGroup.LayoutParams.MATCH_PARENT) {
|
|
||||||
params.width = this.getWindow().getContext().getResources().getDisplayMetrics().widthPixels;
|
|
||||||
}
|
|
||||||
if (params.height == ViewGroup.LayoutParams.MATCH_PARENT) {
|
|
||||||
params.height = this.getWindow().getContext().getResources().getDisplayMetrics().heightPixels;
|
|
||||||
}
|
|
||||||
|
|
||||||
super.setContentView(view, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContentView(View view, ViewGroup.LayoutParams params, double widthScale, double heightScale) {
|
|
||||||
if (widthScale < 0) {
|
|
||||||
widthScale = 0;
|
|
||||||
}
|
|
||||||
if (heightScale > 1) {
|
|
||||||
heightScale = 1;
|
|
||||||
}
|
|
||||||
if (params.width == ViewGroup.LayoutParams.MATCH_PARENT) {
|
|
||||||
params.width = (int) (widthScale * this.getWindow().getContext().getResources().getDisplayMetrics().widthPixels);
|
|
||||||
}
|
|
||||||
if (params.height == ViewGroup.LayoutParams.MATCH_PARENT) {
|
|
||||||
params.height = (int) (heightScale * this.getWindow().getContext().getResources().getDisplayMetrics().heightPixels);
|
|
||||||
}
|
|
||||||
super.setContentView(view, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setContentView(int layoutResID) {
|
|
||||||
LayoutInflater inflater = LayoutInflater.from(getContext());
|
|
||||||
View inflate = inflater.inflate(layoutResID, null);
|
|
||||||
if (inflater == null) {
|
|
||||||
throw new AssertionError("layout not find");
|
|
||||||
}
|
|
||||||
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
|
||||||
this.setContentView(inflate, layoutParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContentView(int layoutResID, double widthScale, double heightScale) {
|
|
||||||
LayoutInflater inflater = LayoutInflater.from(getContext());
|
|
||||||
View inflate = inflater.inflate(layoutResID, null);
|
|
||||||
if (inflater == null) {
|
|
||||||
throw new AssertionError("layout not find");
|
|
||||||
}
|
|
||||||
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
|
||||||
this.setContentView(inflate, layoutParams, widthScale, heightScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 对齐方式
|
|
||||||
*
|
|
||||||
* @param gravity
|
|
||||||
*/
|
|
||||||
public void setGravity(int gravity) {
|
|
||||||
WindowManager.LayoutParams attributes = getWindow().getAttributes();
|
|
||||||
attributes.gravity = gravity;
|
|
||||||
getWindow().setAttributes(attributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置背景屏幕透明度
|
|
||||||
*/
|
|
||||||
public void setDimAmount(float amount) {
|
|
||||||
this.getWindow().setDimAmount(amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 自定义按钮点击事件
|
|
||||||
*
|
|
||||||
* @param viewId 自定义Dialog viewId
|
|
||||||
* @param clickListener 点击事件监听器
|
|
||||||
* @param dismiss 是否消失
|
|
||||||
*/
|
|
||||||
public void addOnclickListener(int viewId, final View.OnClickListener clickListener, final boolean dismiss) {
|
|
||||||
this.findViewById(viewId).setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
clickListener.onClick(v);
|
|
||||||
if (dismiss) {
|
|
||||||
dismiss();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 自定义按钮点击事件
|
|
||||||
*
|
|
||||||
* @param view 自定义Dialog view
|
|
||||||
* @param clickListener 点击事件监听器
|
|
||||||
* @param dismiss 是否消失
|
|
||||||
*/
|
|
||||||
public void addOnclickListener(View view, final View.OnClickListener clickListener, final boolean dismiss) {
|
|
||||||
view.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
clickListener.onClick(v);
|
|
||||||
if (dismiss) {
|
|
||||||
dismiss();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
package ${domain}.base.ui;
|
|
||||||
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.LinearGradient;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.Shader;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.GridView;
|
|
||||||
|
|
||||||
import ${package}.R;
|
|
||||||
|
|
||||||
public class WBUIGridView extends GridView {
|
|
||||||
public WBUIGridView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WBUIGridView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WBUIGridView(Context context, AttributeSet attrs, int defStyle) {
|
|
||||||
super(context, attrs, defStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
super.onDraw(canvas);
|
|
||||||
int cols = getNumColumns(); //获取列数
|
|
||||||
|
|
||||||
Paint localPaint; //设置画笔
|
|
||||||
localPaint = new Paint();
|
|
||||||
localPaint.setStyle(Paint.Style.FILL); //画笔实心
|
|
||||||
|
|
||||||
for (int i = 0; i < getChildCount(); i++) {
|
|
||||||
View childAt = getChildAt(i);
|
|
||||||
localPaint.setShader(new LinearGradient(childAt.getLeft(), childAt.getBottom(), childAt.getRight(), childAt.getBottom(), new int[]{
|
|
||||||
getResources().getColor(R.color.colorGray_09), getResources().getColor(R.color.colorGray_09), getResources().getColor(R.color.colorGray_09)}, null, Shader.TileMode.REPEAT));
|
|
||||||
canvas.drawLine(childAt.getLeft(), childAt.getBottom() - 1, childAt.getRight(), childAt.getBottom() - 1, localPaint);
|
|
||||||
|
|
||||||
if ((i + 1) % cols != 0) {
|
|
||||||
localPaint.setShader(new LinearGradient(childAt.getRight(), childAt.getTop(), childAt.getRight(), childAt.getBottom(), new int[]{
|
|
||||||
getResources().getColor(R.color.colorGray_09), getResources().getColor(R.color.colorGray_09), getResources().getColor(R.color.colorGray_09)}, null, Shader.TileMode.MIRROR));
|
|
||||||
canvas.drawLine(childAt.getRight() - 1, childAt.getTop(), childAt.getRight() - 1, childAt.getBottom(), localPaint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
package ${domain}.base.ui;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
|
|
||||||
public class WBUITextView extends android.support.v7.widget.AppCompatTextView {
|
|
||||||
private int mOffsetY = 0;
|
|
||||||
public Bitmap lastBitmap;
|
|
||||||
|
|
||||||
public WBUITextView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WBUITextView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
if (lastBitmap != null) {
|
|
||||||
canvas.drawBitmap(lastBitmap, 0, mOffsetY - getHeight(), null);
|
|
||||||
canvas.translate(0, mOffsetY);
|
|
||||||
}
|
|
||||||
super.onDraw(canvas);
|
|
||||||
|
|
||||||
if (mOffsetY == 0) {
|
|
||||||
lastBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
|
|
||||||
super.onDraw(new Canvas(lastBitmap));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setText(CharSequence text, BufferType type) {
|
|
||||||
mOffsetY = getHeight();
|
|
||||||
post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (mOffsetY > 0) {
|
|
||||||
mOffsetY -= 5;
|
|
||||||
if (mOffsetY < 0) mOffsetY = 0;
|
|
||||||
postDelayed(this, 10);
|
|
||||||
} else {
|
|
||||||
mOffsetY = 0;
|
|
||||||
}
|
|
||||||
System.out.println(mOffsetY);
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
super.setText(text, type);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
package ${domain}.base.ui;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
|
|
||||||
public class WBUITipTextView extends android.support.v7.widget.AppCompatTextView {
|
|
||||||
private long time = 3000;
|
|
||||||
private String lastValue = "";
|
|
||||||
private Runnable runnable = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
time-=1000;
|
|
||||||
if (time <= 0){
|
|
||||||
WBUITipTextView.this.setText("");
|
|
||||||
}else {
|
|
||||||
postDelayed(runnable,1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public WBUITipTextView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WBUITipTextView(Context context, @Nullable AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WBUITipTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
|
||||||
super(context, attrs, defStyleAttr);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setText(CharSequence text, BufferType type) {
|
|
||||||
this.time = 3000;
|
|
||||||
postDelayed(runnable,1000);
|
|
||||||
|
|
||||||
super.setText(text, type);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,85 +0,0 @@
|
|||||||
package ${domain}.base.ui.button;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.ColorStateList;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.graphics.drawable.ShapeDrawable;
|
|
||||||
import android.graphics.drawable.StateListDrawable;
|
|
||||||
import android.graphics.drawable.shapes.RoundRectShape;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.widget.Button;
|
|
||||||
|
|
||||||
public class WbButton extends Button {
|
|
||||||
private int mColor;
|
|
||||||
private float mScale;
|
|
||||||
|
|
||||||
public WbButton(Context context) {
|
|
||||||
super(context);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public WbButton(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
mScale = getResources().getDisplayMetrics().density;
|
|
||||||
ColorStateList textColors = this.getTextColors();
|
|
||||||
mColor = textColors.getDefaultColor();
|
|
||||||
|
|
||||||
StateListDrawable stateListDrawable = new StateListDrawable();
|
|
||||||
stateListDrawable.setEnterFadeDuration(200);
|
|
||||||
stateListDrawable.setExitFadeDuration(200);
|
|
||||||
int radius = (int) (5 * mScale);
|
|
||||||
int width = (int) (1 * mScale);
|
|
||||||
|
|
||||||
//不可按时的drawable
|
|
||||||
{
|
|
||||||
RoundRectShape roundRectShape = new RoundRectShape(
|
|
||||||
new float[]{radius, radius, radius, radius, radius, radius, radius, radius},
|
|
||||||
new RectF(width, width, width, width),
|
|
||||||
new float[]{radius - width, radius - width, radius - width, radius - width, radius - width, radius - width, radius - width, radius - width}
|
|
||||||
);
|
|
||||||
ShapeDrawable shapeDrawable = new ShapeDrawable(roundRectShape);
|
|
||||||
shapeDrawable.getPaint().setColor(Color.parseColor("#aaaaaa"));
|
|
||||||
stateListDrawable.addState(new int[]{-android.R.attr.state_enabled}, shapeDrawable);
|
|
||||||
}
|
|
||||||
//正常的drawable
|
|
||||||
{
|
|
||||||
RoundRectShape roundRectShape = new RoundRectShape(
|
|
||||||
new float[]{radius, radius, radius, radius, radius, radius, radius, radius},
|
|
||||||
new RectF(width, width, width, width),
|
|
||||||
new float[]{radius - width, radius - width, radius - width, radius - width, radius - width, radius - width, radius - width, radius - width}
|
|
||||||
);
|
|
||||||
ShapeDrawable shapeDrawable = new ShapeDrawable(roundRectShape);
|
|
||||||
shapeDrawable.getPaint().setColor(mColor);
|
|
||||||
|
|
||||||
stateListDrawable.addState(new int[]{-android.R.attr.state_pressed}, shapeDrawable);
|
|
||||||
}
|
|
||||||
//按下去的drawable
|
|
||||||
{
|
|
||||||
RoundRectShape roundRectShape = new RoundRectShape(
|
|
||||||
new float[]{radius, radius, radius, radius, radius, radius, radius, radius},
|
|
||||||
null,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
ShapeDrawable shapeDrawable = new ShapeDrawable(roundRectShape);
|
|
||||||
shapeDrawable.getPaint().setColor(mColor);
|
|
||||||
stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, shapeDrawable);
|
|
||||||
}
|
|
||||||
this.setBackground(stateListDrawable);
|
|
||||||
|
|
||||||
//各状态对应的字体颜色
|
|
||||||
int[][] satate = {
|
|
||||||
{-android.R.attr.state_enabled},
|
|
||||||
{-android.R.attr.state_pressed},
|
|
||||||
{android.R.attr.state_pressed}
|
|
||||||
};
|
|
||||||
int[] colors = {Color.parseColor("#aaaaaa"), mColor, Color.WHITE,};
|
|
||||||
|
|
||||||
ColorStateList colorStateList = new ColorStateList(satate, colors);
|
|
||||||
this.setTextColor(colorStateList);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package ${domain}.base.ui.button;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.widget.ImageButton;
|
|
||||||
|
|
||||||
public class WbImageButton extends ImageButton {
|
|
||||||
private int mSrcWitdh;
|
|
||||||
private int mSrcHeight;
|
|
||||||
private int mExactlyWidth;
|
|
||||||
private int mEactlyHeight;
|
|
||||||
|
|
||||||
public WbImageButton(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WbImageButton(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
|
||||||
|
|
||||||
Drawable drawable = getDrawable();
|
|
||||||
Rect bounds = drawable.getBounds();
|
|
||||||
mSrcWitdh = bounds.width();
|
|
||||||
mSrcHeight = bounds.height();
|
|
||||||
|
|
||||||
System.out.println(mSrcWitdh);
|
|
||||||
System.out.println(mSrcHeight);
|
|
||||||
if (mSrcWitdh != 0 && mSrcHeight != 0) {
|
|
||||||
if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY && MeasureSpec.getMode(heightMeasureSpec) != MeasureSpec.EXACTLY) {
|
|
||||||
//宽度确定,高度自适应
|
|
||||||
mExactlyWidth = MeasureSpec.getSize(widthMeasureSpec);
|
|
||||||
mEactlyHeight = mExactlyWidth * mSrcHeight / mSrcWitdh;
|
|
||||||
setMeasuredDimension(mExactlyWidth, mEactlyHeight);
|
|
||||||
} else if (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY && MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) {
|
|
||||||
//高度确定,宽度自适应
|
|
||||||
mEactlyHeight = MeasureSpec.getSize(heightMeasureSpec);
|
|
||||||
mExactlyWidth = mEactlyHeight * mSrcWitdh / mSrcHeight;
|
|
||||||
setMeasuredDimension(mExactlyWidth, mEactlyHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,114 +0,0 @@
|
|||||||
package ${domain}.base.ui.button;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.ColorStateList;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.ShapeDrawable;
|
|
||||||
import android.graphics.drawable.StateListDrawable;
|
|
||||||
import android.graphics.drawable.shapes.RoundRectShape;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class WbMultiToggleButton extends LinearLayout implements View.OnClickListener {
|
|
||||||
private Button b1;
|
|
||||||
private Button b2;
|
|
||||||
|
|
||||||
|
|
||||||
public WbMultiToggleButton(Context context) {
|
|
||||||
super(context);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public WbMultiToggleButton(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
this.setOrientation(HORIZONTAL);
|
|
||||||
float density = this.getResources().getDisplayMetrics().density;
|
|
||||||
LayoutParams layoutParams = new LayoutParams(0, LayoutParams.MATCH_PARENT);
|
|
||||||
layoutParams.weight = 1;
|
|
||||||
|
|
||||||
{
|
|
||||||
// 边框
|
|
||||||
ShapeDrawable shapeDrawable = new ShapeDrawable(new RoundRectShape(new float[]{density * 5, density * 5, density * 5, density * 5, density * 5, density * 5, density * 5, density * 5}, null, null));
|
|
||||||
shapeDrawable.getPaint().setColor(Color.parseColor("#aaaaaa"));
|
|
||||||
this.setPadding((int) (density * 1), (int) (density * 1), (int) (density * 1), (int) (density * 1));
|
|
||||||
this.setBackground(shapeDrawable);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
b1 = new Button(getContext());
|
|
||||||
b1.setText("aa");
|
|
||||||
b1.setTag("b1");
|
|
||||||
b1.setOnClickListener(this);
|
|
||||||
int[][] satate = {
|
|
||||||
{-android.R.attr.state_selected},
|
|
||||||
{android.R.attr.state_selected}
|
|
||||||
};
|
|
||||||
int[] colors = {Color.BLACK, Color.WHITE};
|
|
||||||
ColorStateList colorStateList = new ColorStateList(satate, colors);
|
|
||||||
b1.setTextColor(colorStateList);
|
|
||||||
|
|
||||||
ShapeDrawable unselected = new ShapeDrawable(new RoundRectShape(new float[]{density * 4, density * 4, 0, 0, 0, 0, density * 4, density * 4}, null, null));
|
|
||||||
unselected.getPaint().setColor(Color.WHITE);
|
|
||||||
ShapeDrawable selected = new ShapeDrawable(new RoundRectShape(new float[]{density * 4, density * 4, 0, 0, 0, 0, density * 4, density * 4}, null, null));
|
|
||||||
selected.getPaint().setColor(Color.parseColor("#66b3ff"));
|
|
||||||
StateListDrawable listDrawable = new StateListDrawable();
|
|
||||||
listDrawable.addState(new int[]{-android.R.attr.state_selected}, unselected);
|
|
||||||
listDrawable.addState(new int[]{android.R.attr.state_selected}, selected);
|
|
||||||
b1.setBackground(listDrawable);
|
|
||||||
this.addView(b1, layoutParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
b2 = new Button(getContext());
|
|
||||||
b2.setText("bb");
|
|
||||||
b2.setTag("b2");
|
|
||||||
b2.setOnClickListener(this);
|
|
||||||
int[][] satate = {
|
|
||||||
{-android.R.attr.state_selected},
|
|
||||||
{android.R.attr.state_selected}
|
|
||||||
};
|
|
||||||
int[] colors = {Color.BLACK, Color.WHITE};
|
|
||||||
ColorStateList colorStateList = new ColorStateList(satate, colors);
|
|
||||||
b2.setTextColor(colorStateList);
|
|
||||||
ShapeDrawable unselected = new ShapeDrawable(new RoundRectShape(new float[]{0, 0, density * 4, density * 4, density * 4, density * 4, 0, 0}, null, null));
|
|
||||||
unselected.getPaint().setColor(Color.WHITE);
|
|
||||||
ShapeDrawable selected = new ShapeDrawable(new RoundRectShape(new float[]{0, 0, density * 4, density * 4, density * 4, density * 4, 0, 0}, null, null));
|
|
||||||
selected.getPaint().setColor(Color.parseColor("#66b3ff"));
|
|
||||||
StateListDrawable listDrawable = new StateListDrawable();
|
|
||||||
listDrawable.addState(new int[]{-android.R.attr.state_selected}, unselected);
|
|
||||||
listDrawable.addState(new int[]{android.R.attr.state_selected}, selected);
|
|
||||||
b2.setBackground(listDrawable);
|
|
||||||
this.addView(b2, layoutParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
b1.setSelected(true);
|
|
||||||
b2.setSelected(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
Object tag = v.getTag();
|
|
||||||
if (tag instanceof String) {
|
|
||||||
String t = (String) tag;
|
|
||||||
switch (t) {
|
|
||||||
case "b1":
|
|
||||||
b1.setSelected(true);
|
|
||||||
b2.setSelected(false);
|
|
||||||
break;
|
|
||||||
case "b2":
|
|
||||||
b1.setSelected(false);
|
|
||||||
b2.setSelected(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
package ${domain}.base.ui.button;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
|
||||||
import android.graphics.drawable.StateListDrawable;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.widget.RadioButton;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by bingwang on 2016/7/17.
|
|
||||||
*/
|
|
||||||
public class WbRadioButton extends RadioButton {
|
|
||||||
|
|
||||||
public WbRadioButton(Context context) {
|
|
||||||
super(context);
|
|
||||||
initial();
|
|
||||||
}
|
|
||||||
|
|
||||||
public WbRadioButton(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
initial();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造自定义radio
|
|
||||||
*/
|
|
||||||
public void initial() {
|
|
||||||
float density = getResources().getDisplayMetrics().density;
|
|
||||||
StateListDrawable stateListDrawable = new StateListDrawable();
|
|
||||||
|
|
||||||
Bitmap unchecked = Bitmap.createBitmap((int) (30 * density), (int) (30 * density), Bitmap.Config.ARGB_8888);
|
|
||||||
Bitmap checked = Bitmap.createBitmap((int) (30 * density), (int) (30 * density), Bitmap.Config.ARGB_8888);
|
|
||||||
|
|
||||||
{//未选中状态
|
|
||||||
Canvas canvas = new Canvas(unchecked);
|
|
||||||
Paint paint = new Paint();
|
|
||||||
paint.setColor(Color.DKGRAY);
|
|
||||||
paint.setStyle(Paint.Style.STROKE);
|
|
||||||
paint.setStrokeWidth(5 * density);
|
|
||||||
canvas.drawRect(4.5f * density, 4.5f * density, 25.5f * density, 25.5f * density, paint);
|
|
||||||
}
|
|
||||||
|
|
||||||
{//选中状态
|
|
||||||
Canvas canvas = new Canvas(checked);
|
|
||||||
Paint paint = new Paint();
|
|
||||||
paint.setColor(Color.DKGRAY);
|
|
||||||
paint.setStyle(Paint.Style.STROKE);
|
|
||||||
paint.setStrokeWidth(5 * density);
|
|
||||||
canvas.drawRect(4.5f * density, 4.5f * density, 25.5f * density, 25.5f * density, paint);
|
|
||||||
paint.setColor(Color.argb(255, 00, 94, 00));
|
|
||||||
paint.setStyle(Paint.Style.FILL);
|
|
||||||
canvas.drawRect(9 * density, 9 * density, 21 * density, 21 * density, paint);
|
|
||||||
}
|
|
||||||
|
|
||||||
stateListDrawable.addState(new int[]{-android.R.attr.state_checked}, new BitmapDrawable(getResources(), unchecked));
|
|
||||||
stateListDrawable.addState(new int[]{android.R.attr.state_checked}, new BitmapDrawable(getResources(), checked));
|
|
||||||
this.setButtonDrawable(stateListDrawable);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,114 +0,0 @@
|
|||||||
package ${domain}.base.ui.button;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.ColorStateList;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.ShapeDrawable;
|
|
||||||
import android.graphics.drawable.StateListDrawable;
|
|
||||||
import android.graphics.drawable.shapes.RoundRectShape;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class WbToggleButton extends LinearLayout implements View.OnClickListener {
|
|
||||||
private Button b1;
|
|
||||||
private Button b2;
|
|
||||||
|
|
||||||
|
|
||||||
public WbToggleButton(Context context) {
|
|
||||||
super(context);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public WbToggleButton(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
this.setOrientation(HORIZONTAL);
|
|
||||||
float density = this.getResources().getDisplayMetrics().density;
|
|
||||||
LayoutParams layoutParams = new LayoutParams(0, LayoutParams.MATCH_PARENT);
|
|
||||||
layoutParams.weight = 1;
|
|
||||||
|
|
||||||
{
|
|
||||||
// 边框
|
|
||||||
ShapeDrawable shapeDrawable = new ShapeDrawable(new RoundRectShape(new float[]{density * 5, density * 5, density * 5, density * 5, density * 5, density * 5, density * 5, density * 5}, null, null));
|
|
||||||
shapeDrawable.getPaint().setColor(Color.parseColor("#aaaaaa"));
|
|
||||||
this.setPadding((int) (density * 1), (int) (density * 1), (int) (density * 1), (int) (density * 1));
|
|
||||||
this.setBackground(shapeDrawable);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
b1 = new Button(getContext());
|
|
||||||
b1.setText("aa");
|
|
||||||
b1.setTag("b1");
|
|
||||||
b1.setOnClickListener(this);
|
|
||||||
int[][] satate = {
|
|
||||||
{-android.R.attr.state_selected},
|
|
||||||
{android.R.attr.state_selected}
|
|
||||||
};
|
|
||||||
int[] colors = {Color.BLACK, Color.WHITE};
|
|
||||||
ColorStateList colorStateList = new ColorStateList(satate, colors);
|
|
||||||
b1.setTextColor(colorStateList);
|
|
||||||
|
|
||||||
ShapeDrawable unselected = new ShapeDrawable(new RoundRectShape(new float[]{density * 4, density * 4, 0, 0, 0, 0, density * 4, density * 4}, null, null));
|
|
||||||
unselected.getPaint().setColor(Color.WHITE);
|
|
||||||
ShapeDrawable selected = new ShapeDrawable(new RoundRectShape(new float[]{density * 4, density * 4, 0, 0, 0, 0, density * 4, density * 4}, null, null));
|
|
||||||
selected.getPaint().setColor(Color.parseColor("#66b3ff"));
|
|
||||||
StateListDrawable listDrawable = new StateListDrawable();
|
|
||||||
listDrawable.addState(new int[]{-android.R.attr.state_selected}, unselected);
|
|
||||||
listDrawable.addState(new int[]{android.R.attr.state_selected}, selected);
|
|
||||||
b1.setBackground(listDrawable);
|
|
||||||
this.addView(b1, layoutParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
b2 = new Button(getContext());
|
|
||||||
b2.setText("bb");
|
|
||||||
b2.setTag("b2");
|
|
||||||
b2.setOnClickListener(this);
|
|
||||||
int[][] satate = {
|
|
||||||
{-android.R.attr.state_selected},
|
|
||||||
{android.R.attr.state_selected}
|
|
||||||
};
|
|
||||||
int[] colors = {Color.BLACK, Color.WHITE};
|
|
||||||
ColorStateList colorStateList = new ColorStateList(satate, colors);
|
|
||||||
b2.setTextColor(colorStateList);
|
|
||||||
ShapeDrawable unselected = new ShapeDrawable(new RoundRectShape(new float[]{0, 0, density * 4, density * 4, density * 4, density * 4, 0, 0}, null, null));
|
|
||||||
unselected.getPaint().setColor(Color.WHITE);
|
|
||||||
ShapeDrawable selected = new ShapeDrawable(new RoundRectShape(new float[]{0, 0, density * 4, density * 4, density * 4, density * 4, 0, 0}, null, null));
|
|
||||||
selected.getPaint().setColor(Color.parseColor("#66b3ff"));
|
|
||||||
StateListDrawable listDrawable = new StateListDrawable();
|
|
||||||
listDrawable.addState(new int[]{-android.R.attr.state_selected}, unselected);
|
|
||||||
listDrawable.addState(new int[]{android.R.attr.state_selected}, selected);
|
|
||||||
b2.setBackground(listDrawable);
|
|
||||||
this.addView(b2, layoutParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
b1.setSelected(true);
|
|
||||||
b2.setSelected(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
Object tag = v.getTag();
|
|
||||||
if (tag instanceof String) {
|
|
||||||
String t = (String) tag;
|
|
||||||
switch (t) {
|
|
||||||
case "b1":
|
|
||||||
b1.setSelected(true);
|
|
||||||
b2.setSelected(false);
|
|
||||||
break;
|
|
||||||
case "b2":
|
|
||||||
b1.setSelected(false);
|
|
||||||
b2.setSelected(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
package ${domain}.base.ui.dialog;
|
|
||||||
|
|
||||||
import android.app.Dialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.ColorDrawable;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.Window;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
public class ConfirmDialog extends Dialog {
|
|
||||||
private LinearLayout mLinearLayout;
|
|
||||||
|
|
||||||
public ConfirmDialog(@NonNull Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfirmDialog(@NonNull Context context, int themeResId) {
|
|
||||||
super(context, themeResId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConfirmDialog(Context context, String message) {
|
|
||||||
super(context);
|
|
||||||
//px与dp比例
|
|
||||||
float mScale = getContext().getResources().getDisplayMetrics().density;
|
|
||||||
|
|
||||||
//设置基本参数
|
|
||||||
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
|
||||||
// this.getWindow().setBackgroundDrawable(new ColorDrawable(Color.argb(0, 0, 0, 0)));
|
|
||||||
// this.getWindow().setDimAmount(0);
|
|
||||||
this.setCanceledOnTouchOutside(false);
|
|
||||||
|
|
||||||
//父容器
|
|
||||||
{
|
|
||||||
mLinearLayout = new LinearLayout(getContext());
|
|
||||||
mLinearLayout.setGravity(Gravity.CENTER);
|
|
||||||
mLinearLayout.setOrientation(LinearLayout.VERTICAL);
|
|
||||||
mLinearLayout.setPadding(10, 10, 10, 10);
|
|
||||||
mLinearLayout.setBackground(new ColorDrawable(Color.WHITE));
|
|
||||||
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, (int) (mScale * 50));
|
|
||||||
this.setContentView(mLinearLayout, layoutParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//消息显示框
|
|
||||||
TextView mTextView = new TextView(context);
|
|
||||||
mTextView.setText(message);
|
|
||||||
mTextView.setGravity(Gravity.CENTER);
|
|
||||||
mTextView.setTextColor(Color.BLACK);
|
|
||||||
mTextView.setMinWidth((int) (mScale * 150));
|
|
||||||
mLinearLayout.addView(mTextView);
|
|
||||||
|
|
||||||
{
|
|
||||||
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, (int) (mScale * 50));
|
|
||||||
|
|
||||||
Button button = new Button(getContext());
|
|
||||||
button.setText("确认");
|
|
||||||
button.setTextColor(Color.parseColor("#7AECC4"));
|
|
||||||
button.setBackground(null);
|
|
||||||
button.setGravity(Gravity.RIGHT);
|
|
||||||
mLinearLayout.addView(button, layoutParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,123 +0,0 @@
|
|||||||
package ${domain}.base.ui.dialog;
|
|
||||||
|
|
||||||
import android.app.Dialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.Window;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
|
|
||||||
public class CustomDialog extends Dialog {
|
|
||||||
public CustomDialog(Context context) {
|
|
||||||
super(context);
|
|
||||||
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
|
||||||
this.getWindow().getDecorView().setPadding(0, 0, 0, 0);
|
|
||||||
// this.getWindow().setBackgroundDrawable(new ColorDrawable(Color.argb(0, 0, 0, 0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setContentView(View view, ViewGroup.LayoutParams params) {
|
|
||||||
if (params.width == ViewGroup.LayoutParams.MATCH_PARENT) {
|
|
||||||
params.width = this.getWindow().getContext().getResources().getDisplayMetrics().widthPixels;
|
|
||||||
}
|
|
||||||
if (params.height == ViewGroup.LayoutParams.MATCH_PARENT) {
|
|
||||||
params.height = this.getWindow().getContext().getResources().getDisplayMetrics().heightPixels;
|
|
||||||
}
|
|
||||||
|
|
||||||
super.setContentView(view, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContentView(View view, ViewGroup.LayoutParams params, double widthScale, double heightScale) {
|
|
||||||
if (widthScale < 0) {
|
|
||||||
widthScale = 0;
|
|
||||||
}
|
|
||||||
if (heightScale > 1) {
|
|
||||||
heightScale = 1;
|
|
||||||
}
|
|
||||||
if (params.width == ViewGroup.LayoutParams.MATCH_PARENT) {
|
|
||||||
params.width = (int) (widthScale * this.getWindow().getContext().getResources().getDisplayMetrics().widthPixels);
|
|
||||||
}
|
|
||||||
if (params.height == ViewGroup.LayoutParams.MATCH_PARENT) {
|
|
||||||
params.height = (int) (heightScale * this.getWindow().getContext().getResources().getDisplayMetrics().heightPixels);
|
|
||||||
}
|
|
||||||
super.setContentView(view, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setContentView(int layoutResID) {
|
|
||||||
LayoutInflater inflater = LayoutInflater.from(getContext());
|
|
||||||
View inflate = inflater.inflate(layoutResID, null);
|
|
||||||
if (inflater == null) {
|
|
||||||
throw new AssertionError("layout not find");
|
|
||||||
}
|
|
||||||
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
|
||||||
this.setContentView(inflate, layoutParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setContentView(int layoutResID, double widthScale, double heightScale) {
|
|
||||||
LayoutInflater inflater = LayoutInflater.from(getContext());
|
|
||||||
View inflate = inflater.inflate(layoutResID, null);
|
|
||||||
if (inflater == null) {
|
|
||||||
throw new AssertionError("layout not find");
|
|
||||||
}
|
|
||||||
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
|
||||||
this.setContentView(inflate, layoutParams, widthScale, heightScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 对齐方式
|
|
||||||
*
|
|
||||||
* @param gravity
|
|
||||||
*/
|
|
||||||
public void setGravity(int gravity) {
|
|
||||||
WindowManager.LayoutParams attributes = getWindow().getAttributes();
|
|
||||||
attributes.gravity = gravity;
|
|
||||||
getWindow().setAttributes(attributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置背景屏幕透明度
|
|
||||||
*/
|
|
||||||
public void setDimAmount(float amount) {
|
|
||||||
this.getWindow().setDimAmount(amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 自定义按钮点击事件
|
|
||||||
*
|
|
||||||
* @param viewId 自定义Dialog viewId
|
|
||||||
* @param clickListener 点击事件监听器
|
|
||||||
* @param dismiss 是否消失
|
|
||||||
*/
|
|
||||||
public void addOnclickListener(int viewId, final View.OnClickListener clickListener, final boolean dismiss) {
|
|
||||||
this.findViewById(viewId).setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
clickListener.onClick(v);
|
|
||||||
if (dismiss) {
|
|
||||||
dismiss();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 自定义按钮点击事件
|
|
||||||
*
|
|
||||||
* @param view 自定义Dialog view
|
|
||||||
* @param clickListener 点击事件监听器
|
|
||||||
* @param dismiss 是否消失
|
|
||||||
*/
|
|
||||||
public void addOnclickListener(View view, final View.OnClickListener clickListener, final boolean dismiss) {
|
|
||||||
view.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
clickListener.onClick(v);
|
|
||||||
if (dismiss) {
|
|
||||||
dismiss();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
package ${domain}.base.ui.dialog;
|
|
||||||
|
|
||||||
import android.app.Dialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.widget.FrameLayout;
|
|
||||||
|
|
||||||
public class WBUIDialog extends Dialog {
|
|
||||||
public WBUIDialog(@NonNull Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void show() {
|
|
||||||
super.show();
|
|
||||||
// FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) mContentView
|
|
||||||
// .getLayoutParams();
|
|
||||||
// layoutParams.width = display.getWidth();
|
|
||||||
// layoutParams.height = display.getHeight();
|
|
||||||
// mContentView.setLayoutParams(layoutParams);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,155 +0,0 @@
|
|||||||
package ${domain}.base.ui.dialog;
|
|
||||||
|
|
||||||
import android.app.Dialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.ColorDrawable;
|
|
||||||
import android.graphics.drawable.ShapeDrawable;
|
|
||||||
import android.graphics.drawable.StateListDrawable;
|
|
||||||
import android.graphics.drawable.shapes.RoundRectShape;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.Window;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.view.animation.Animation;
|
|
||||||
import android.view.animation.TranslateAnimation;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by bingwang on 2016/5/17.
|
|
||||||
*/
|
|
||||||
public class WbConfirmDialog extends Dialog {
|
|
||||||
LinearLayout mLinearLayout;
|
|
||||||
private float demsity = 1;
|
|
||||||
private Button mPositiveButton;
|
|
||||||
private Button mNegativeButton;
|
|
||||||
private OnPostiveListener mOnPostiveListener = null;
|
|
||||||
private OnNegativeListener mOnNegativeListener = null;
|
|
||||||
|
|
||||||
public WbConfirmDialog(Context context) {
|
|
||||||
super(context);
|
|
||||||
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
|
||||||
this.getWindow().setGravity(Gravity.FILL_HORIZONTAL | Gravity.BOTTOM);
|
|
||||||
this.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
|
||||||
this.getWindow().setDimAmount(0.2f);
|
|
||||||
this.getWindow().setWindowAnimations(-1);
|
|
||||||
this.demsity = context.getResources().getDisplayMetrics().density;
|
|
||||||
|
|
||||||
mLinearLayout = new LinearLayout(context);
|
|
||||||
mLinearLayout.setOrientation(LinearLayout.VERTICAL);
|
|
||||||
mLinearLayout.setPadding((int) (5 * demsity), 0, (int) (5 * demsity), (int) (5 * demsity));
|
|
||||||
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);
|
|
||||||
lp.width = context.getResources().getDisplayMetrics().widthPixels;
|
|
||||||
this.setContentView(mLinearLayout, lp);
|
|
||||||
|
|
||||||
{
|
|
||||||
mNegativeButton = new Button(context);
|
|
||||||
mNegativeButton.setText("取消");
|
|
||||||
mNegativeButton.setGravity(Gravity.CENTER);
|
|
||||||
mNegativeButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
onNegative();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
float[] out = {5 * demsity, 5 * demsity, 5 * demsity, 5 * demsity, 5 * demsity, 5 * demsity, 5 * demsity, 5 * demsity};
|
|
||||||
RoundRectShape roundRectShape = new RoundRectShape(out, null, null);
|
|
||||||
ShapeDrawable shapeDrawable = new ShapeDrawable(roundRectShape);
|
|
||||||
shapeDrawable.getPaint().setColor(Color.argb(255, 255, 255, 255));
|
|
||||||
|
|
||||||
StateListDrawable stateListDrawable = new StateListDrawable();
|
|
||||||
stateListDrawable.addState(new int[]{-android.R.attr.state_pressed}, shapeDrawable);
|
|
||||||
|
|
||||||
ShapeDrawable shapeDrawable1 = new ShapeDrawable(roundRectShape);
|
|
||||||
shapeDrawable1.getPaint().setColor(Color.argb(255, 240, 240, 240));
|
|
||||||
stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, shapeDrawable1);
|
|
||||||
|
|
||||||
mNegativeButton.setBackground(stateListDrawable);
|
|
||||||
|
|
||||||
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, (int) (45 * demsity));
|
|
||||||
layoutParams.setMargins(0, (int) (5 * demsity), 0, 0);
|
|
||||||
mLinearLayout.addView(mNegativeButton, layoutParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
mPositiveButton = new Button(context);
|
|
||||||
mPositiveButton.setText("确认");
|
|
||||||
mPositiveButton.setGravity(Gravity.CENTER);
|
|
||||||
float[] out = {5 * demsity, 5 * demsity, 5 * demsity, 5 * demsity, 5 * demsity, 5 * demsity, 5 * demsity, 5 * demsity};
|
|
||||||
RoundRectShape roundRectShape = new RoundRectShape(out, null, null);
|
|
||||||
ShapeDrawable shapeDrawable = new ShapeDrawable(roundRectShape);
|
|
||||||
shapeDrawable.getPaint().setColor(Color.argb(255, 255, 255, 255));
|
|
||||||
|
|
||||||
StateListDrawable stateListDrawable = new StateListDrawable();
|
|
||||||
stateListDrawable.addState(new int[]{-android.R.attr.state_pressed}, shapeDrawable);
|
|
||||||
|
|
||||||
ShapeDrawable shapeDrawable1 = new ShapeDrawable(roundRectShape);
|
|
||||||
shapeDrawable1.getPaint().setColor(Color.argb(255, 240, 240, 240));
|
|
||||||
stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, shapeDrawable1);
|
|
||||||
mPositiveButton.setBackground(stateListDrawable);
|
|
||||||
|
|
||||||
mPositiveButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
onPositive();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, (int) (45 * demsity));
|
|
||||||
mLinearLayout.addView(mPositiveButton, 0, layoutParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void show() {
|
|
||||||
super.show();
|
|
||||||
TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0,
|
|
||||||
Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 0);
|
|
||||||
translateAnimation.setDuration(200);
|
|
||||||
|
|
||||||
mLinearLayout.startAnimation(translateAnimation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onPositive() {
|
|
||||||
dismiss();
|
|
||||||
if (mOnPostiveListener != null) {
|
|
||||||
mOnPostiveListener.onPostive();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onNegative() {
|
|
||||||
dismiss();
|
|
||||||
if (mOnNegativeListener != null) {
|
|
||||||
mOnNegativeListener.onNegative();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public OnNegativeListener getOnNegativeListener() {
|
|
||||||
return mOnNegativeListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnNegativeListener(OnNegativeListener mOnNegativeListener) {
|
|
||||||
this.mOnNegativeListener = mOnNegativeListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OnPostiveListener getOnPostiveListener() {
|
|
||||||
return mOnPostiveListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnPostiveListener(OnPostiveListener mOnPostiveListener) {
|
|
||||||
this.mOnPostiveListener = mOnPostiveListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface OnPostiveListener {
|
|
||||||
void onPostive();
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface OnNegativeListener {
|
|
||||||
void onNegative();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,168 +0,0 @@
|
|||||||
package ${domain}.base.ui.image;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.LinearGradient;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.Path;
|
|
||||||
import android.graphics.RadialGradient;
|
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.graphics.Shader;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.util.TypedValue;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
|
||||||
import android.view.animation.AccelerateInterpolator;
|
|
||||||
import android.view.animation.Animation;
|
|
||||||
import android.view.animation.CycleInterpolator;
|
|
||||||
import android.view.animation.DecelerateInterpolator;
|
|
||||||
import android.view.animation.Interpolator;
|
|
||||||
import android.view.animation.RotateAnimation;
|
|
||||||
|
|
||||||
|
|
||||||
public class AnimationView extends View {
|
|
||||||
|
|
||||||
private int fullDegrees = 300;
|
|
||||||
|
|
||||||
private float progress = 0;
|
|
||||||
|
|
||||||
private int offset = 0;
|
|
||||||
private int indicatorRadius;
|
|
||||||
private int indicatorWidth;
|
|
||||||
|
|
||||||
private int arrowWidth;
|
|
||||||
|
|
||||||
private int shadowRadius;
|
|
||||||
|
|
||||||
private int shadowWidth;
|
|
||||||
|
|
||||||
private Animation rotateAnimation;
|
|
||||||
|
|
||||||
public AnimationView(Context context) {
|
|
||||||
super(context);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public AnimationView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
indicatorWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, getContext().getResources().getDisplayMetrics());
|
|
||||||
shadowWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, getContext().getResources().getDisplayMetrics());
|
|
||||||
rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
|
|
||||||
rotateAnimation.setDuration(1000);
|
|
||||||
rotateAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
|
|
||||||
rotateAnimation.setRepeatCount(Animation.INFINITE);
|
|
||||||
arrowWidth = indicatorWidth * 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getOffset() {
|
|
||||||
int o = 0;
|
|
||||||
if (getPaddingTop() > o) {
|
|
||||||
o = getPaddingTop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getPaddingRight() > o) {
|
|
||||||
o = getPaddingRight();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getPaddingBottom() > o) {
|
|
||||||
o = getPaddingBottom();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getPaddingLeft() > o) {
|
|
||||||
o = getPaddingLeft();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getPaddingStart() > o) {
|
|
||||||
o = getPaddingStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getPaddingEnd() > o) {
|
|
||||||
o = getPaddingEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o == 0) {
|
|
||||||
o = shadowWidth + 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
super.onDraw(canvas);
|
|
||||||
int width = getWidth();
|
|
||||||
int height = getHeight();
|
|
||||||
|
|
||||||
{//阴影部分
|
|
||||||
shadowRadius = Math.min(width, height) / 2;
|
|
||||||
Paint paint = new Paint();
|
|
||||||
paint.setColor(Color.RED);
|
|
||||||
paint.setStyle(Paint.Style.STROKE);
|
|
||||||
paint.setStrokeWidth(shadowWidth);
|
|
||||||
RadialGradient radialGradient = new RadialGradient(
|
|
||||||
width / 2,
|
|
||||||
height / 2,
|
|
||||||
shadowRadius,
|
|
||||||
Color.parseColor("#888888"),
|
|
||||||
Color.TRANSPARENT,
|
|
||||||
Shader.TileMode.REPEAT);
|
|
||||||
paint.setShader(radialGradient);
|
|
||||||
canvas.drawCircle(getWidth() / 2, getHeight() / 2, shadowRadius - shadowWidth / 2 - 1, paint);
|
|
||||||
}
|
|
||||||
|
|
||||||
{//指示器部分
|
|
||||||
offset = getOffset();
|
|
||||||
indicatorRadius = shadowRadius - offset - shadowWidth;
|
|
||||||
int currentDegress = (int) (fullDegrees * progress);
|
|
||||||
int currentArrowWidth = (int) (arrowWidth * progress);
|
|
||||||
|
|
||||||
Path path = new Path();
|
|
||||||
path.moveTo(width / 2, height / 2 - indicatorRadius);
|
|
||||||
RectF outer = new RectF(
|
|
||||||
width / 2 - indicatorRadius,
|
|
||||||
height / 2 - indicatorRadius,
|
|
||||||
width / 2 + indicatorRadius,
|
|
||||||
height / 2 + indicatorRadius
|
|
||||||
);
|
|
||||||
path.addArc(outer, -90, currentDegress);
|
|
||||||
Paint paint1 = new Paint();
|
|
||||||
paint1.setStyle(Paint.Style.STROKE);
|
|
||||||
paint1.setStrokeWidth(indicatorWidth);
|
|
||||||
paint1.setAntiAlias(true);
|
|
||||||
canvas.drawPath(path, paint1);
|
|
||||||
|
|
||||||
Path arrowPath = new Path();
|
|
||||||
arrowPath.moveTo(width / 2, height / 2 - indicatorRadius - currentArrowWidth / 2);
|
|
||||||
arrowPath.lineTo(width / 2, height / 2 - indicatorRadius + currentArrowWidth / 2);
|
|
||||||
arrowPath.lineTo(width / 2 + currentArrowWidth, height / 2 - indicatorRadius);
|
|
||||||
arrowPath.close();
|
|
||||||
paint1.setStyle(Paint.Style.FILL);
|
|
||||||
canvas.rotate(currentDegress, width / 2, height / 2);
|
|
||||||
canvas.drawPath(arrowPath, paint1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startAnimation() {
|
|
||||||
progress = 1;
|
|
||||||
this.startAnimation(rotateAnimation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stopAnimation() {
|
|
||||||
this.clearAnimation();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public float getProgress() {
|
|
||||||
return progress;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProgress(float progress) {
|
|
||||||
this.progress = progress;
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
package ${domain}.base.ui.image;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
|
|
||||||
import ${domain}.base.util.FastBlur;
|
|
||||||
|
|
||||||
|
|
||||||
public class BlurImage extends android.support.v7.widget.AppCompatImageView {
|
|
||||||
public BlurImage(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlurImage(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
//获取当前显示的位图
|
|
||||||
Bitmap bitMap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
|
|
||||||
super.onDraw(new Canvas(bitMap));
|
|
||||||
//模糊处理
|
|
||||||
FastBlur.doBlur(bitMap, 10, true);
|
|
||||||
//绘图
|
|
||||||
canvas.drawBitmap(bitMap, 0, 0, new Paint());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,158 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package ${domain}.base.ui.image;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.RadialGradient;
|
|
||||||
import android.graphics.Shader;
|
|
||||||
import android.graphics.drawable.ShapeDrawable;
|
|
||||||
import android.graphics.drawable.shapes.OvalShape;
|
|
||||||
import android.support.v4.content.ContextCompat;
|
|
||||||
import android.support.v4.view.ViewCompat;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.animation.Animation;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private class created to work around issues with AnimationListeners being
|
|
||||||
* called before the animation is actually complete and support shadows on older
|
|
||||||
* platforms.
|
|
||||||
*/
|
|
||||||
public class CircleImageView extends ImageView {
|
|
||||||
|
|
||||||
private static final int KEY_SHADOW_COLOR = 0x1E000000;
|
|
||||||
private static final int FILL_SHADOW_COLOR = 0x3D000000;
|
|
||||||
// PX
|
|
||||||
private static final float X_OFFSET = 0f;
|
|
||||||
private static final float Y_OFFSET = 1.75f;
|
|
||||||
private static final float SHADOW_RADIUS = 3.5f;
|
|
||||||
private static final int SHADOW_ELEVATION = 4;
|
|
||||||
|
|
||||||
private Animation.AnimationListener mListener;
|
|
||||||
int mShadowRadius;
|
|
||||||
|
|
||||||
public CircleImageView(Context context, int color) {
|
|
||||||
super(context);
|
|
||||||
final float density = getContext().getResources().getDisplayMetrics().density;
|
|
||||||
final int shadowYOffset = (int) (density * Y_OFFSET);
|
|
||||||
final int shadowXOffset = (int) (density * X_OFFSET);
|
|
||||||
|
|
||||||
mShadowRadius = (int) (density * SHADOW_RADIUS);
|
|
||||||
|
|
||||||
ShapeDrawable circle;
|
|
||||||
if (elevationSupported()) {
|
|
||||||
circle = new ShapeDrawable(new OvalShape());
|
|
||||||
ViewCompat.setElevation(this, SHADOW_ELEVATION * density);
|
|
||||||
} else {
|
|
||||||
OvalShape oval = new OvalShadow(mShadowRadius);
|
|
||||||
circle = new ShapeDrawable(oval);
|
|
||||||
setLayerType(View.LAYER_TYPE_SOFTWARE, circle.getPaint());
|
|
||||||
circle.getPaint().setShadowLayer(mShadowRadius, shadowXOffset, shadowYOffset,
|
|
||||||
KEY_SHADOW_COLOR);
|
|
||||||
final int padding = mShadowRadius;
|
|
||||||
// set padding so the inner image sits correctly within the shadow.
|
|
||||||
setPadding(padding, padding, padding, padding);
|
|
||||||
}
|
|
||||||
circle.getPaint().setColor(color);
|
|
||||||
ViewCompat.setBackground(this, circle);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean elevationSupported() {
|
|
||||||
return android.os.Build.VERSION.SDK_INT >= 21;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
|
||||||
if (!elevationSupported()) {
|
|
||||||
setMeasuredDimension(getMeasuredWidth() + mShadowRadius * 2, getMeasuredHeight()
|
|
||||||
+ mShadowRadius * 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAnimationListener(Animation.AnimationListener listener) {
|
|
||||||
mListener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAnimationStart() {
|
|
||||||
super.onAnimationStart();
|
|
||||||
if (mListener != null) {
|
|
||||||
mListener.onAnimationStart(getAnimation());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAnimationEnd() {
|
|
||||||
super.onAnimationEnd();
|
|
||||||
if (mListener != null) {
|
|
||||||
mListener.onAnimationEnd(getAnimation());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the background color of the circle image view.
|
|
||||||
*
|
|
||||||
* @param colorRes Id of a color resource.
|
|
||||||
*/
|
|
||||||
public void setBackgroundColorRes(int colorRes) {
|
|
||||||
setBackgroundColor(ContextCompat.getColor(getContext(), colorRes));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBackgroundColor(int color) {
|
|
||||||
if (getBackground() instanceof ShapeDrawable) {
|
|
||||||
((ShapeDrawable) getBackground()).getPaint().setColor(color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class OvalShadow extends OvalShape {
|
|
||||||
private RadialGradient mRadialGradient;
|
|
||||||
private Paint mShadowPaint;
|
|
||||||
|
|
||||||
OvalShadow(int shadowRadius) {
|
|
||||||
super();
|
|
||||||
mShadowPaint = new Paint();
|
|
||||||
mShadowRadius = shadowRadius;
|
|
||||||
updateRadialGradient((int) rect().width());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResize(float width, float height) {
|
|
||||||
super.onResize(width, height);
|
|
||||||
updateRadialGradient((int) width);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(Canvas canvas, Paint paint) {
|
|
||||||
final int viewWidth = CircleImageView.this.getWidth();
|
|
||||||
final int viewHeight = CircleImageView.this.getHeight();
|
|
||||||
canvas.drawCircle(viewWidth / 2, viewHeight / 2, viewWidth / 2, mShadowPaint);
|
|
||||||
canvas.drawCircle(viewWidth / 2, viewHeight / 2, viewWidth / 2 - mShadowRadius, paint);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateRadialGradient(int diameter) {
|
|
||||||
mRadialGradient = new RadialGradient(diameter / 2, diameter / 2,
|
|
||||||
mShadowRadius, new int[] { FILL_SHADOW_COLOR, Color.TRANSPARENT },
|
|
||||||
null, Shader.TileMode.CLAMP);
|
|
||||||
mShadowPaint.setShader(mRadialGradient);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
package ${domain}.base.ui.image;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.PorterDuff;
|
|
||||||
import android.graphics.PorterDuffXfermode;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
|
|
||||||
public class RoundImageView extends ImageView {
|
|
||||||
public RoundImageView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RoundImageView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
|
|
||||||
//获取原图
|
|
||||||
int width = getWidth();
|
|
||||||
int height = getHeight();
|
|
||||||
Bitmap srcBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
||||||
super.onDraw(new Canvas(srcBitmap));
|
|
||||||
|
|
||||||
//绘制原图
|
|
||||||
{
|
|
||||||
Bitmap shapeBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
||||||
Canvas shapeCanvas = new Canvas(shapeBitmap);
|
|
||||||
shapeCanvas.drawCircle(width / 2, height / 2, Math.min(width, height) / 2 - 4, new Paint());
|
|
||||||
|
|
||||||
Paint paint = new Paint();
|
|
||||||
paint.setAntiAlias(true);
|
|
||||||
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
|
|
||||||
shapeCanvas.drawBitmap(srcBitmap, 0, 0, paint);
|
|
||||||
|
|
||||||
canvas.drawBitmap(shapeBitmap, 0, 0, new Paint());
|
|
||||||
}
|
|
||||||
|
|
||||||
//绘制边框
|
|
||||||
{
|
|
||||||
Paint paint = new Paint();
|
|
||||||
paint.setStyle(Paint.Style.STROKE);
|
|
||||||
paint.setColor(Color.GREEN);
|
|
||||||
paint.setStrokeWidth(4);
|
|
||||||
paint.setAntiAlias(true);
|
|
||||||
canvas.drawCircle(width / 2, height / 2, Math.min(width, height) / 2 - 4, paint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
package ${domain}.base.ui.image;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.TypedArray;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
|
|
||||||
import ${package}.R;
|
|
||||||
|
|
||||||
public class WBUISquareImageView extends android.support.v7.widget.AppCompatImageView {
|
|
||||||
|
|
||||||
private int weight_width = 1;
|
|
||||||
private int weight_height = 1;
|
|
||||||
|
|
||||||
public WBUISquareImageView(Context context, AttributeSet attrs, int defStyle) {
|
|
||||||
super(context, attrs, defStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WBUISquareImageView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
|
|
||||||
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.uiSquare);
|
|
||||||
weight_width = typedArray.getInt(R.styleable.uiSquare_weight_width,1);
|
|
||||||
weight_height = typedArray.getInt(R.styleable.uiSquare_weight_height,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WBUISquareImageView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
setMeasuredDimension(getDefaultSize(0, widthMeasureSpec), getDefaultSize(0, heightMeasureSpec));
|
|
||||||
int width = getMeasuredWidth();
|
|
||||||
int height = getMeasuredHeight();
|
|
||||||
|
|
||||||
int expectWidth = height * weight_width / weight_height;
|
|
||||||
int expectHeght = width * weight_height / weight_width;
|
|
||||||
|
|
||||||
if (expectWidth == 0){
|
|
||||||
expectWidth = expectHeght;
|
|
||||||
}else if (expectHeght == 0){
|
|
||||||
expectHeght = expectWidth;
|
|
||||||
}else {
|
|
||||||
if ((double) expectWidth / width <= (double) expectHeght / height) {
|
|
||||||
expectHeght = expectWidth * weight_height / weight_width;
|
|
||||||
} else {
|
|
||||||
expectWidth = expectHeght * weight_width / weight_height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
widthMeasureSpec = MeasureSpec.makeMeasureSpec(expectWidth, MeasureSpec.EXACTLY);
|
|
||||||
heightMeasureSpec = MeasureSpec.makeMeasureSpec(expectHeght, MeasureSpec.EXACTLY);
|
|
||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package ${domain}.base.ui.image;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.PorterDuff;
|
|
||||||
import android.graphics.PorterDuffXfermode;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
|
|
||||||
import ${domain}.base.util.FastBlur;
|
|
||||||
|
|
||||||
|
|
||||||
public class WbRoundImageView extends android.support.v7.widget.AppCompatImageView {
|
|
||||||
public WbRoundImageView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WbRoundImageView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
|
|
||||||
//获取原图
|
|
||||||
int width = getWidth();
|
|
||||||
int height = getHeight();
|
|
||||||
Bitmap srcBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
||||||
super.onDraw(new Canvas(srcBitmap));
|
|
||||||
|
|
||||||
canvas.drawBitmap(FastBlur.doBlur(srcBitmap, 20, false), 0, 0, new Paint());
|
|
||||||
|
|
||||||
//绘制原图
|
|
||||||
{
|
|
||||||
Bitmap shapeBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
||||||
Canvas shapeCanvas = new Canvas(shapeBitmap);
|
|
||||||
shapeCanvas.drawCircle(width / 2, height / 2, Math.min(width, height) / 2 - 4, new Paint());
|
|
||||||
|
|
||||||
Paint paint = new Paint();
|
|
||||||
paint.setAntiAlias(true);
|
|
||||||
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
|
|
||||||
shapeCanvas.drawBitmap(srcBitmap, 0, 0, paint);
|
|
||||||
|
|
||||||
canvas.drawBitmap(shapeBitmap, 0, 0, new Paint());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
package ${domain}.base.ui.layout;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.TypedArray;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
|
|
||||||
import ${package}.R;
|
|
||||||
|
|
||||||
public class WBUISquareLayout extends RelativeLayout {
|
|
||||||
|
|
||||||
private int weight_width = 1;
|
|
||||||
private int weight_height = 1;
|
|
||||||
private int mWidth;
|
|
||||||
private int mHeight;
|
|
||||||
|
|
||||||
private View targetView;
|
|
||||||
|
|
||||||
public WBUISquareLayout(Context context, AttributeSet attrs, int defStyle) {
|
|
||||||
super(context, attrs, defStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WBUISquareLayout(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
setWillNotDraw(false);
|
|
||||||
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.uiSquare);
|
|
||||||
weight_width = typedArray.getInt(R.styleable.uiSquare_weight_width, weight_width);
|
|
||||||
weight_height = typedArray.getInt(R.styleable.uiSquare_weight_height, weight_height);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WBUISquareLayout(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ensureView() {
|
|
||||||
int childCount = getChildCount();
|
|
||||||
if (childCount > 1) {
|
|
||||||
throw new IllegalStateException("WBUISquareLayout can host only one child");
|
|
||||||
} else if (childCount == 1) {
|
|
||||||
targetView = getChildAt(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
|
|
||||||
int wMode = MeasureSpec.getMode(widthMeasureSpec);
|
|
||||||
int wSize = MeasureSpec.getSize(widthMeasureSpec);
|
|
||||||
int hMode = MeasureSpec.getMode(heightMeasureSpec);
|
|
||||||
int hSize = MeasureSpec.getSize(heightMeasureSpec);
|
|
||||||
|
|
||||||
if (wMode == MeasureSpec.EXACTLY && hMode == MeasureSpec.EXACTLY) {
|
|
||||||
mWidth = wSize;
|
|
||||||
mHeight = hSize;
|
|
||||||
} else if (wMode == MeasureSpec.EXACTLY && hMode != MeasureSpec.EXACTLY) {
|
|
||||||
mWidth = wSize;
|
|
||||||
mHeight = wSize * weight_height / weight_width;
|
|
||||||
} else if (wMode != MeasureSpec.EXACTLY && hMode == MeasureSpec.EXACTLY) {
|
|
||||||
mWidth = hSize * weight_width / weight_height;
|
|
||||||
mHeight = hSize;
|
|
||||||
} else if (wMode != MeasureSpec.EXACTLY && hMode != MeasureSpec.EXACTLY) {
|
|
||||||
measureChildren(widthMeasureSpec, heightMeasureSpec);
|
|
||||||
ensureView();
|
|
||||||
if (targetView != null) {
|
|
||||||
int measuredWidth = targetView.getMeasuredWidth();
|
|
||||||
int measuredHeight = targetView.getMeasuredHeight();
|
|
||||||
mWidth = mHeight = Math.max(measuredWidth, measuredHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
measureChildren(MeasureSpec.makeMeasureSpec(mWidth,MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(mHeight,MeasureSpec.AT_MOST));
|
|
||||||
setMeasuredDimension(mWidth, mHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
|
||||||
ensureView();
|
|
||||||
if (targetView != null) {
|
|
||||||
int measuredWidth = targetView.getMeasuredWidth();
|
|
||||||
int measuredHeight = targetView.getMeasuredHeight();
|
|
||||||
if (measuredWidth > measuredHeight) {
|
|
||||||
int dy = measuredWidth - measuredHeight;
|
|
||||||
targetView.layout(0, dy / 2, measuredWidth, measuredHeight + dy / 2);
|
|
||||||
} else {
|
|
||||||
int dx = measuredHeight - measuredWidth;
|
|
||||||
targetView.layout(dx / 2, 0, measuredWidth + dx / 2, measuredHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,104 +0,0 @@
|
|||||||
package ${domain}.base.ui.layout;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.support.v4.view.PagerAdapter;
|
|
||||||
import android.support.v4.view.ViewPager;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by bingwang on 2016/5/16.
|
|
||||||
*/
|
|
||||||
public class WbViewPager extends RelativeLayout {
|
|
||||||
|
|
||||||
private LinearLayout mIndexView;
|
|
||||||
private ViewPager mViewPager;
|
|
||||||
|
|
||||||
public WbViewPager(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WbViewPager(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
|
|
||||||
mViewPager = new ViewPager(context);
|
|
||||||
this.addView(mViewPager, new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
|
||||||
|
|
||||||
mIndexView = new LinearLayout(context);
|
|
||||||
mIndexView.setGravity(Gravity.CENTER);
|
|
||||||
mIndexView.setOrientation(LinearLayout.HORIZONTAL);
|
|
||||||
LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 50);
|
|
||||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
|
|
||||||
layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
|
|
||||||
layoutParams.setMargins(0, 0, 0, 10);
|
|
||||||
this.addView(mIndexView, layoutParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAdapter(PagerAdapter adapter) {
|
|
||||||
mViewPager.setAdapter(adapter);
|
|
||||||
|
|
||||||
for (int i = 0; i < adapter.getCount(); i++) {
|
|
||||||
Circle circle = new Circle(getContext());
|
|
||||||
if (i == 0) {
|
|
||||||
circle.setColor(Color.argb(255, 100, 100, 100));
|
|
||||||
}
|
|
||||||
mIndexView.addView(circle, new ViewGroup.LayoutParams(40, 20));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
|
||||||
@Override
|
|
||||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPageSelected(int position) {
|
|
||||||
for (int i = 0; i < mIndexView.getChildCount(); i++) {
|
|
||||||
Circle circle = (Circle) mIndexView.getChildAt(i);
|
|
||||||
circle.setColor(Color.argb(255, 200, 200, 200));
|
|
||||||
circle.invalidate();
|
|
||||||
}
|
|
||||||
Circle circle = (Circle) mIndexView.getChildAt(position);
|
|
||||||
circle.setColor(Color.argb(255, 100, 100, 100));
|
|
||||||
circle.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPageScrollStateChanged(int state) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Circle extends View {
|
|
||||||
private int mColor = Color.argb(255, 200, 200, 200);
|
|
||||||
private Paint mPaint = new Paint();
|
|
||||||
|
|
||||||
public Circle(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
mPaint.setColor(mColor);
|
|
||||||
canvas.drawCircle(getWidth() / 2, getHeight() / 2, Math.min(getWidth() / 2, getHeight() / 2), mPaint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getColor() {
|
|
||||||
return mColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setColor(int mColor) {
|
|
||||||
this.mColor = mColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,144 +0,0 @@
|
|||||||
package ${domain}.base.ui.list;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.widget.ListView;
|
|
||||||
|
|
||||||
public class BoundListView extends ListView {
|
|
||||||
public static int OVERSCROLL_STATE_NORMAL = 0;//正常
|
|
||||||
public static int OVERSCROLL_STATE_PULL = -1;//拉
|
|
||||||
public static int OVERSCROLL_STATE_PUSH = 1;//推
|
|
||||||
|
|
||||||
private int mOverScrollState = OVERSCROLL_STATE_NORMAL;
|
|
||||||
private float lastY = -1;//最近一次Y轴位置
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 小于0-->pull,大于0-->push
|
|
||||||
*/
|
|
||||||
private int mOverY = 0;
|
|
||||||
|
|
||||||
public BoundListView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BoundListView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setOverScrollMode(int mode) {
|
|
||||||
//去掉边缘发光效果
|
|
||||||
super.setOverScrollMode(OVER_SCROLL_NEVER);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onTouchEvent(MotionEvent ev) {
|
|
||||||
switch (ev.getAction()) {
|
|
||||||
case MotionEvent.ACTION_DOWN:
|
|
||||||
if (mOverY < 0) {
|
|
||||||
mOverScrollState = OVERSCROLL_STATE_PULL;
|
|
||||||
} else if (mOverY > 0) {
|
|
||||||
mOverScrollState = OVERSCROLL_STATE_PUSH;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (mOverScrollState != OVERSCROLL_STATE_NORMAL) {
|
|
||||||
switch (ev.getAction()) {
|
|
||||||
case MotionEvent.ACTION_UP:
|
|
||||||
mOverScrollState = OVERSCROLL_STATE_NORMAL;
|
|
||||||
onBound();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastY < 0) {
|
|
||||||
lastY = ev.getY();
|
|
||||||
} else {
|
|
||||||
if (Math.abs(ev.getY() - lastY) > 30) {
|
|
||||||
lastY = ev.getY();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (ev.getY() - lastY != 0) {
|
|
||||||
if (mOverScrollState == OVERSCROLL_STATE_PULL) {
|
|
||||||
mOverY -= (ev.getY() - lastY);
|
|
||||||
if (mOverY > 0) {
|
|
||||||
mOverY = 0;
|
|
||||||
mOverScrollState = OVERSCROLL_STATE_NORMAL;
|
|
||||||
ev.setAction(MotionEvent.ACTION_DOWN);
|
|
||||||
super.onTouchEvent(ev);
|
|
||||||
}
|
|
||||||
} else if (mOverScrollState == OVERSCROLL_STATE_PUSH) {
|
|
||||||
mOverY -= (ev.getY() - lastY);
|
|
||||||
if (mOverY < 0) {
|
|
||||||
mOverY = 0;
|
|
||||||
mOverScrollState = OVERSCROLL_STATE_NORMAL;
|
|
||||||
ev.setAction(MotionEvent.ACTION_DOWN);
|
|
||||||
super.onTouchEvent(ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastY = ev.getY();
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return super.onTouchEvent(ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
|
|
||||||
// if (isTouchEvent) {
|
|
||||||
// if (deltaY < 0) {
|
|
||||||
// mOverScrollState = OVERSCROLL_STATE_PULL;
|
|
||||||
// } else {
|
|
||||||
// mOverScrollState = OVERSCROLL_STATE_PUSH;
|
|
||||||
// }
|
|
||||||
// mOverY += deltaY;
|
|
||||||
// invalidate();
|
|
||||||
// }
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(Canvas canvas) {
|
|
||||||
canvas.translate(0, -mOverY / 2);
|
|
||||||
super.draw(canvas);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 回弹归位
|
|
||||||
*/
|
|
||||||
private void onBound() {
|
|
||||||
final int during = 1000;
|
|
||||||
final int d = 10;
|
|
||||||
if (mOverY != 0) {
|
|
||||||
new Thread() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
int flag = 1;
|
|
||||||
if (mOverY < 0) {
|
|
||||||
flag = -1;
|
|
||||||
mOverY = -mOverY;
|
|
||||||
}
|
|
||||||
int temp = mOverY;
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
while (i < during && Math.abs(temp) >= 5 && mOverScrollState == OVERSCROLL_STATE_NORMAL) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(d);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
i += d;
|
|
||||||
temp = (int) (Math.pow((double) i / during - 1, 2) * temp);
|
|
||||||
mOverY = flag * temp;
|
|
||||||
postInvalidate();
|
|
||||||
}
|
|
||||||
mOverY = 0;
|
|
||||||
postInvalidate();
|
|
||||||
}
|
|
||||||
}.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package ${domain}.base.ui.list;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.widget.ListView;
|
|
||||||
|
|
||||||
public class NoScrollListView extends ListView {
|
|
||||||
|
|
||||||
public NoScrollListView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NoScrollListView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public NoScrollListView(Context context, AttributeSet attrs, int defStyle) {
|
|
||||||
super(context, attrs, defStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置listView不可滑动
|
|
||||||
*
|
|
||||||
* @param widthMeasureSpec
|
|
||||||
* @param heightMeasureSpec
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
|
|
||||||
MeasureSpec.AT_MOST);
|
|
||||||
super.onMeasure(widthMeasureSpec, expandSpec);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,178 +0,0 @@
|
|||||||
package ${domain}.base.ui.list;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Message;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.ScrollView;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
public class OverScrollView extends ScrollView {
|
|
||||||
LinearLayout mLinearLayout;
|
|
||||||
LinearLayout mHeader;
|
|
||||||
LinearLayout mFooter;
|
|
||||||
private int mLastScrollY = -1;
|
|
||||||
private int mOverY = 0;
|
|
||||||
private int mLastMotionY = 0;
|
|
||||||
|
|
||||||
public static int OVERSCROLL_STATE_NORMAL = 0;//正常
|
|
||||||
public static int OVERSCROLL_STATE_PULL = 1;//拉
|
|
||||||
public static int OVERSCROLL_STATE_PUSH = -1;//推
|
|
||||||
|
|
||||||
private int mOverScrollState = OVERSCROLL_STATE_NORMAL;
|
|
||||||
|
|
||||||
public OverScrollView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public OverScrollView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setOverScrollMode(int mode) {
|
|
||||||
//去掉边缘发光效果
|
|
||||||
super.setOverScrollMode(OVER_SCROLL_NEVER);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addView(View child, int index, ViewGroup.LayoutParams params) {
|
|
||||||
Log.i("--->", "addView");
|
|
||||||
|
|
||||||
mLinearLayout = new LinearLayout(getContext());
|
|
||||||
mLinearLayout.setOrientation(LinearLayout.VERTICAL);
|
|
||||||
|
|
||||||
mHeader = new LinearLayout(getContext());
|
|
||||||
mFooter = new LinearLayout(getContext());
|
|
||||||
mLinearLayout.addView(mHeader, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
|
||||||
mLinearLayout.addView(child, params);
|
|
||||||
mLinearLayout.addView(mFooter, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
|
||||||
|
|
||||||
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
|
||||||
super.addView(mLinearLayout, index, layoutParams);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onTouchEvent(MotionEvent ev) {
|
|
||||||
switch (ev.getAction()) {
|
|
||||||
case MotionEvent.ACTION_UP:
|
|
||||||
mOverScrollState = OVERSCROLL_STATE_NORMAL;
|
|
||||||
onBound();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mOverScrollState == OVERSCROLL_STATE_PULL) {
|
|
||||||
if (ev.getY() > mLastMotionY) {
|
|
||||||
mOverY = (int) (ev.getY() - mLastMotionY);
|
|
||||||
this.fullScroll(ScrollView.FOCUS_UP);
|
|
||||||
mHeader.setMinimumHeight(mOverY);
|
|
||||||
Log.i("-->", "mOverY=" + mOverY);
|
|
||||||
} else {
|
|
||||||
mOverScrollState = OVERSCROLL_STATE_NORMAL;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} else if (mOverScrollState == OVERSCROLL_STATE_PUSH) {
|
|
||||||
if (mLastMotionY > ev.getY()) {
|
|
||||||
mOverY = (int) (ev.getY() - mLastMotionY);
|
|
||||||
mFooter.setMinimumHeight(-mOverY);
|
|
||||||
this.fullScroll(ScrollView.FOCUS_DOWN);
|
|
||||||
Log.i("-->", "mOverY=" + mOverY);
|
|
||||||
} else {
|
|
||||||
mOverScrollState = OVERSCROLL_STATE_NORMAL;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return super.onTouchEvent(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 回弹归位
|
|
||||||
*/
|
|
||||||
private void onBound() {
|
|
||||||
final Handler handler = new Handler() {
|
|
||||||
@Override
|
|
||||||
public void handleMessage(Message msg) {
|
|
||||||
if (mOverY > 0) {
|
|
||||||
OverScrollView.this.fullScroll(ScrollView.FOCUS_UP);
|
|
||||||
mHeader.setMinimumHeight(mOverY);
|
|
||||||
} else if (mOverY < 0) {
|
|
||||||
OverScrollView.this.fullScroll(ScrollView.FOCUS_DOWN);
|
|
||||||
mFooter.setMinimumHeight(-mOverY);
|
|
||||||
} else {
|
|
||||||
mHeader.setMinimumHeight(0);
|
|
||||||
mFooter.setMinimumHeight(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
new Thread() {
|
|
||||||
int during = 1000;
|
|
||||||
int d = 10;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
int flag = 1;
|
|
||||||
if (mOverY < 0) {
|
|
||||||
flag = -1;
|
|
||||||
mOverY = -mOverY;
|
|
||||||
}
|
|
||||||
int temp = mOverY;
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
while (i < during && Math.abs(temp) >= 5 && mOverScrollState == OVERSCROLL_STATE_NORMAL) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(d);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
i += d;
|
|
||||||
temp = (int) (Math.pow((double) i / during - 1, 2) * temp);
|
|
||||||
mOverY = flag * temp;
|
|
||||||
handler.sendEmptyMessage(1);
|
|
||||||
}
|
|
||||||
mOverY = 0;
|
|
||||||
}
|
|
||||||
}.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
|
|
||||||
|
|
||||||
//只捕捉边界值
|
|
||||||
if (mOverScrollState == OVERSCROLL_STATE_NORMAL && (scrollY == 0 || scrollY == scrollRangeY)) {
|
|
||||||
if (scrollY == 0) {
|
|
||||||
mOverScrollState = OVERSCROLL_STATE_PULL;
|
|
||||||
} else {
|
|
||||||
mOverScrollState = OVERSCROLL_STATE_PUSH;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Class aClass = this.getClass().getSuperclass();
|
|
||||||
Field mLastMotionYField = aClass.getDeclaredField("mLastMotionY");
|
|
||||||
mLastMotionYField.setAccessible(true);
|
|
||||||
mLastMotionY = (int) mLastMotionYField.get(this);
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// switch (mOverScrollState){
|
|
||||||
// case -1:
|
|
||||||
// Log.i("-->","PUSH");
|
|
||||||
// break;
|
|
||||||
// case 1:
|
|
||||||
// Log.i("-->","PULL");
|
|
||||||
// break;
|
|
||||||
// case 0:
|
|
||||||
// Log.i("-->","NORMAL");
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Log.i("-->-->","deltaY-->"+getScaleY()+"/"+scrollY+"---"+scrollRangeY);
|
|
||||||
return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,92 +0,0 @@
|
|||||||
package ${domain}.base.ui.list;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by wangbing on 2016/4/17.
|
|
||||||
*/
|
|
||||||
public class OverView extends LinearLayout {
|
|
||||||
private int mOverY = 0;
|
|
||||||
private int mLastY = -1;
|
|
||||||
|
|
||||||
public OverView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public OverView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
|
||||||
Log.i("-->", "Y" + event.getY());
|
|
||||||
Log.i("-->", "mLastY" + mLastY);
|
|
||||||
if (mLastY == -1) {
|
|
||||||
mLastY = (int) event.getY();
|
|
||||||
} else {
|
|
||||||
mOverY = (int) (event.getY() - mLastY);
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
switch (event.getAction()) {
|
|
||||||
case MotionEvent.ACTION_UP:
|
|
||||||
mLastY = -1;
|
|
||||||
onBound();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onBound() {
|
|
||||||
final int during = 1000;
|
|
||||||
final int d = 10;
|
|
||||||
if (mOverY != 0) {
|
|
||||||
new Thread() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
int flag = 1;
|
|
||||||
if (mOverY < 0) {
|
|
||||||
flag = -1;
|
|
||||||
mOverY = -mOverY;
|
|
||||||
}
|
|
||||||
int temp = mOverY;
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
while (i < during && Math.abs(temp) >= 5) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(d);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
i += d;
|
|
||||||
temp = (int) (Math.pow((double) i / during - 1, 2) * temp);
|
|
||||||
mOverY = flag * temp;
|
|
||||||
postInvalidate();
|
|
||||||
}
|
|
||||||
mOverY = 0;
|
|
||||||
postInvalidate();
|
|
||||||
}
|
|
||||||
}.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void draw(Canvas canvas) {
|
|
||||||
canvas.translate(0, mOverY / 2);
|
|
||||||
super.draw(canvas);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
|
||||||
if (ev.getAction() == MotionEvent.ACTION_MOVE) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,142 +0,0 @@
|
|||||||
package ${domain}.base.ui.other;
|
|
||||||
|
|
||||||
|
|
||||||
import android.animation.Animator;
|
|
||||||
import android.animation.ValueAnimator;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.RadialGradient;
|
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.graphics.Shader;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.animation.LinearInterpolator;
|
|
||||||
|
|
||||||
import ${domain}.base.util.DensityUtil;
|
|
||||||
|
|
||||||
public class LoadingProgressBar extends View {
|
|
||||||
private ValueAnimator mAnimator;
|
|
||||||
|
|
||||||
private Paint mShadowPaint = new Paint();
|
|
||||||
private Paint mPaint = new Paint();
|
|
||||||
private int shadowWidth = DensityUtil.dp2px(getContext(), 4);
|
|
||||||
private int backgroundWidth = DensityUtil.dp2px(getContext(), 4);
|
|
||||||
private int indicatorWidth = DensityUtil.dp2px(getContext(), 3);
|
|
||||||
|
|
||||||
private int startAngle = -90;
|
|
||||||
private int sweepAngle = 100;
|
|
||||||
private int mDuration = 1000;
|
|
||||||
|
|
||||||
private int defaultSize = DensityUtil.dp2px(getContext(), 50);
|
|
||||||
|
|
||||||
private boolean isAnimating = false;
|
|
||||||
|
|
||||||
public LoadingProgressBar(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LoadingProgressBar(Context context, @Nullable AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
int wMode = MeasureSpec.getMode(widthMeasureSpec);
|
|
||||||
int hMode = MeasureSpec.getMode(heightMeasureSpec);
|
|
||||||
|
|
||||||
if (wMode == MeasureSpec.AT_MOST) {
|
|
||||||
setMeasuredDimension(defaultSize, MeasureSpec.getSize(heightMeasureSpec));
|
|
||||||
return;
|
|
||||||
} else if (hMode == MeasureSpec.AT_MOST) {
|
|
||||||
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), defaultSize);
|
|
||||||
return;
|
|
||||||
} else if (wMode == MeasureSpec.AT_MOST && hMode == MeasureSpec.AT_MOST) {
|
|
||||||
setMeasuredDimension(defaultSize, defaultSize);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
int width = getWidth();
|
|
||||||
int height = getHeight();
|
|
||||||
int radius = Math.min(width, height) / 2;
|
|
||||||
if (radius >= shadowWidth + backgroundWidth) {
|
|
||||||
RadialGradient radialGradient = new RadialGradient(width / 2, height / 2, radius, new int[]{Color.GRAY, Color.TRANSPARENT}, null, Shader.TileMode.CLAMP);
|
|
||||||
mShadowPaint.setShader(radialGradient);
|
|
||||||
canvas.drawCircle(width / 2, height / 2, radius, mShadowPaint);
|
|
||||||
|
|
||||||
mPaint.setColor(Color.WHITE);
|
|
||||||
mPaint.setStyle(Paint.Style.FILL);
|
|
||||||
mPaint.setAntiAlias(true);
|
|
||||||
canvas.drawCircle(width / 2, height / 2, radius - shadowWidth, mPaint);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (radius >= shadowWidth + backgroundWidth + indicatorWidth) {
|
|
||||||
mPaint.setColor(Color.RED);
|
|
||||||
mPaint.setStyle(Paint.Style.STROKE);
|
|
||||||
mPaint.setStrokeWidth(indicatorWidth);
|
|
||||||
|
|
||||||
RectF rectF = new RectF(
|
|
||||||
width / 2 - radius + shadowWidth + backgroundWidth + indicatorWidth / 2,
|
|
||||||
height / 2 - radius + shadowWidth + backgroundWidth + indicatorWidth / 2,
|
|
||||||
width / 2 + radius - shadowWidth - backgroundWidth - indicatorWidth / 2,
|
|
||||||
height / 2 + radius - shadowWidth - backgroundWidth - indicatorWidth / 2);
|
|
||||||
canvas.drawArc(rectF, startAngle, sweepAngle, false, mPaint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProgress(float process) {
|
|
||||||
startAngle = (int) (process * 360 - 90);
|
|
||||||
sweepAngle = (int) (Math.abs(startAngle + 90 - 180) * 1.0f / 180 * 120 + 45);
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startAnimation() {
|
|
||||||
mAnimator = ValueAnimator.ofInt(-90, 270);
|
|
||||||
mAnimator.setDuration(mDuration);
|
|
||||||
mAnimator.setRepeatCount(ValueAnimator.INFINITE);
|
|
||||||
mAnimator.setRepeatMode(ValueAnimator.RESTART);
|
|
||||||
mAnimator.setInterpolator(new LinearInterpolator());
|
|
||||||
mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
|
||||||
public void onAnimationUpdate(ValueAnimator animation) {
|
|
||||||
startAngle = (int) animation.getAnimatedValue();
|
|
||||||
sweepAngle = (int) (Math.abs(startAngle + 90 - 180) * 1.0f / 180 * 120 + 45);
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mAnimator.addListener(new Animator.AnimatorListener() {
|
|
||||||
@Override
|
|
||||||
public void onAnimationStart(Animator animation) {
|
|
||||||
isAnimating = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAnimationEnd(Animator animation) {
|
|
||||||
isAnimating = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAnimationCancel(Animator animation) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAnimationRepeat(Animator animation) {
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mAnimator.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stopAnimation() {
|
|
||||||
if (isAnimating) {
|
|
||||||
mAnimator.cancel();
|
|
||||||
startAngle = -90;
|
|
||||||
sweepAngle = 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,114 +0,0 @@
|
|||||||
package ${domain}.base.ui.other;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.SweepGradient;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.util.DisplayMetrics;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by bingwang on 2016/5/14.
|
|
||||||
*/
|
|
||||||
public class LoadingView extends View {
|
|
||||||
/**
|
|
||||||
* 周期
|
|
||||||
*/
|
|
||||||
private int mDuring = 1000;
|
|
||||||
/**
|
|
||||||
* 旋转步长
|
|
||||||
*/
|
|
||||||
private int mStep = 10;
|
|
||||||
/**
|
|
||||||
* 当前旋转角度
|
|
||||||
*/
|
|
||||||
private int mSweep = 0;
|
|
||||||
/**
|
|
||||||
* 前景色
|
|
||||||
*/
|
|
||||||
private int mColor = Color.BLACK;
|
|
||||||
|
|
||||||
public LoadingView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LoadingView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
int width = 0;
|
|
||||||
int height = 0;
|
|
||||||
|
|
||||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
|
||||||
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
|
|
||||||
wm.getDefaultDisplay().getMetrics(displayMetrics);
|
|
||||||
|
|
||||||
int widhtMode = MeasureSpec.getMode(widthMeasureSpec);
|
|
||||||
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
|
|
||||||
if (widhtMode == MeasureSpec.EXACTLY) {
|
|
||||||
width = widthSize;
|
|
||||||
} else {
|
|
||||||
width = (int) (50 * displayMetrics.density);
|
|
||||||
}
|
|
||||||
|
|
||||||
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
|
||||||
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
|
|
||||||
if (heightMode == MeasureSpec.EXACTLY) {
|
|
||||||
height = heightSize;
|
|
||||||
} else {
|
|
||||||
height = (int) (50 * displayMetrics.density);
|
|
||||||
}
|
|
||||||
setMeasuredDimension(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDraw(Canvas canvas) {
|
|
||||||
int scale = 0;
|
|
||||||
int width = getWidth();
|
|
||||||
int height = getHeight();
|
|
||||||
if (width > height) {
|
|
||||||
scale = height;
|
|
||||||
} else {
|
|
||||||
scale = width;
|
|
||||||
}
|
|
||||||
//画圈
|
|
||||||
Paint paint = new Paint();
|
|
||||||
//设置画笔
|
|
||||||
paint.setColor(Color.BLUE);
|
|
||||||
paint.setAntiAlias(true);
|
|
||||||
//设置角度渐变
|
|
||||||
SweepGradient radialGradient = new SweepGradient(width / 2, height / 2, mColor, Color.argb(0, 0, 0, 255));
|
|
||||||
paint.setShader(radialGradient);
|
|
||||||
paint.setStyle(Paint.Style.STROKE);
|
|
||||||
paint.setStrokeWidth(10);
|
|
||||||
|
|
||||||
canvas.rotate(mSweep, width / 2, height / 2);
|
|
||||||
canvas.drawCircle(width / 2, height / 2, scale / 2 - 10, paint);
|
|
||||||
mSweep += mStep;
|
|
||||||
if (mSweep >= 360) {
|
|
||||||
mSweep = 0;
|
|
||||||
}
|
|
||||||
postInvalidateDelayed(360 / mStep);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDuring() {
|
|
||||||
return mDuring;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDuring(int mDuring) {
|
|
||||||
this.mDuring = mDuring;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getColor() {
|
|
||||||
return mColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setColor(int mColor) {
|
|
||||||
this.mColor = mColor;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,113 +0,0 @@
|
|||||||
package ${domain}.base.ui.other;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.util.DisplayMetrics;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by bingwang on 2016/5/14.
|
|
||||||
*/
|
|
||||||
public class LoadingView1 extends View {
|
|
||||||
/**
|
|
||||||
* 周期
|
|
||||||
*/
|
|
||||||
private int mDuring = 1000;
|
|
||||||
|
|
||||||
private int firstFlag;
|
|
||||||
/**
|
|
||||||
* 前景色
|
|
||||||
*/
|
|
||||||
private int mColor = Color.BLACK;
|
|
||||||
|
|
||||||
public LoadingView1(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LoadingView1(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
int width = 0;
|
|
||||||
int height = 0;
|
|
||||||
|
|
||||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
|
||||||
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
|
|
||||||
wm.getDefaultDisplay().getMetrics(displayMetrics);
|
|
||||||
|
|
||||||
int widhtMode = MeasureSpec.getMode(widthMeasureSpec);
|
|
||||||
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
|
|
||||||
if (widhtMode == MeasureSpec.EXACTLY) {
|
|
||||||
width = widthSize;
|
|
||||||
} else {
|
|
||||||
width = (int) (50 * displayMetrics.density);
|
|
||||||
}
|
|
||||||
|
|
||||||
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
|
||||||
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
|
|
||||||
if (heightMode == MeasureSpec.EXACTLY) {
|
|
||||||
height = heightSize;
|
|
||||||
} else {
|
|
||||||
height = (int) (50 * displayMetrics.density);
|
|
||||||
}
|
|
||||||
setMeasuredDimension(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
super.onDraw(canvas);
|
|
||||||
int scale = 0;
|
|
||||||
int width = getWidth();
|
|
||||||
int height = getHeight();
|
|
||||||
if (width > height) {
|
|
||||||
scale = height;
|
|
||||||
} else {
|
|
||||||
scale = width;
|
|
||||||
}
|
|
||||||
|
|
||||||
Paint p = new Paint();
|
|
||||||
p.setAntiAlias(true);
|
|
||||||
p.setColor(mColor);
|
|
||||||
|
|
||||||
int centerX = getWidth() / 2;
|
|
||||||
int centerY = getHeight() / 2;
|
|
||||||
int blockWidth = scale / 20;
|
|
||||||
int blockHeight = scale / 4;
|
|
||||||
int radiou = blockWidth / 2;
|
|
||||||
RectF rect = new RectF(centerX - blockWidth / 2, centerY - 3 * blockHeight / 2, centerX + blockWidth / 2, centerY - blockHeight / 2);
|
|
||||||
canvas.rotate(firstFlag, centerX, centerY);
|
|
||||||
firstFlag += 30;
|
|
||||||
if (firstFlag == 360) firstFlag = 0;
|
|
||||||
canvas.drawRoundRect(rect, radiou, radiou, p);
|
|
||||||
|
|
||||||
for (int i = 0; i < 11; i++) {
|
|
||||||
canvas.rotate(30, centerX, centerY);
|
|
||||||
p.setAlpha(i * (255 / 12));
|
|
||||||
canvas.drawRoundRect(rect, radiou, radiou, p);
|
|
||||||
}
|
|
||||||
postInvalidateDelayed(mDuring / 12);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getDuring() {
|
|
||||||
return mDuring;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDuring(int mDuring) {
|
|
||||||
this.mDuring = mDuring;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getColor() {
|
|
||||||
return mColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setColor(int mColor) {
|
|
||||||
this.mColor = mColor;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
package ${domain}.base.ui.other;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by bingwang on 2016/5/14.
|
|
||||||
*/
|
|
||||||
public class LoadingView2 extends View {
|
|
||||||
/**
|
|
||||||
* 周期
|
|
||||||
*/
|
|
||||||
private int mDuring = 600;
|
|
||||||
private int timeStamp = 0;
|
|
||||||
private int currentAngle = 0;
|
|
||||||
|
|
||||||
public LoadingView2(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LoadingView2(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
int width = getWidth();
|
|
||||||
int height = getHeight();
|
|
||||||
|
|
||||||
AccelerateDecelerateInterpolator interpolator = new AccelerateDecelerateInterpolator();
|
|
||||||
currentAngle = (int) (360 * interpolator.getInterpolation(((float) (timeStamp % mDuring) / (mDuring + 1))));
|
|
||||||
canvas.rotate(currentAngle, width / 2, height / 2);
|
|
||||||
|
|
||||||
Paint paint = new Paint();
|
|
||||||
paint.setAntiAlias(true);
|
|
||||||
canvas.drawCircle(width / 2, height / 2, 3, paint);
|
|
||||||
|
|
||||||
int abs = Math.abs((currentAngle % 360) % 180 - 180 * ((currentAngle % 360) / 180));
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
canvas.rotate(-abs * 30 / 180, width / 2, height / 2);
|
|
||||||
paint.setAlpha(255 - 255 * i / 5);
|
|
||||||
canvas.drawCircle(width / 2, height / 2 - 50, 10, paint);
|
|
||||||
}
|
|
||||||
|
|
||||||
// for (int i = 0; i < 200; i++) {
|
|
||||||
// float interpolation = interpolator.getInterpolation(i / 100f);
|
|
||||||
//
|
|
||||||
// StringBuffer stringBuffer = new StringBuffer();
|
|
||||||
// stringBuffer.append(i/100f);
|
|
||||||
// for (int j = 0; j < interpolation*100; j++) {
|
|
||||||
// stringBuffer.append(".");
|
|
||||||
// }
|
|
||||||
// System.out.println(stringBuffer.toString());
|
|
||||||
// }
|
|
||||||
|
|
||||||
timeStamp += 10;
|
|
||||||
postInvalidateDelayed(30);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,101 +0,0 @@
|
|||||||
package ${domain}.base.witget.other;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.inputmethodservice.Keyboard.Key;
|
|
||||||
import android.inputmethodservice.KeyboardView;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import ${package}.R;
|
|
||||||
|
|
||||||
public class WBUIKeyboardView extends KeyboardView {
|
|
||||||
|
|
||||||
private Drawable mKeybgDrawable;
|
|
||||||
private Resources res;
|
|
||||||
|
|
||||||
public WBUIKeyboardView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
initResources(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WBUIKeyboardView(Context context, AttributeSet attrs, int defStyleAttr) {
|
|
||||||
super(context, attrs, defStyleAttr);
|
|
||||||
initResources(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initResources(Context context) {
|
|
||||||
res = context.getResources();
|
|
||||||
mKeybgDrawable = res.getDrawable(R.drawable.ui_keyboard_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDraw(Canvas canvas) {
|
|
||||||
List<Key> keys = getKeyboard().getKeys();
|
|
||||||
for (Key key : keys) {
|
|
||||||
canvas.save();
|
|
||||||
|
|
||||||
int offsety = 0;
|
|
||||||
if (key.y == 0) {
|
|
||||||
offsety = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int initdrawy = key.y + offsety;
|
|
||||||
|
|
||||||
Rect rect = new Rect(key.x, initdrawy, key.x + key.width, key.y
|
|
||||||
+ key.height);
|
|
||||||
|
|
||||||
canvas.clipRect(rect);
|
|
||||||
|
|
||||||
int primaryCode = -1;
|
|
||||||
if (null != key.codes && key.codes.length != 0) {
|
|
||||||
primaryCode = key.codes[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
Drawable dr = mKeybgDrawable;
|
|
||||||
|
|
||||||
if (null != dr) {
|
|
||||||
int[] state = key.getCurrentDrawableState();
|
|
||||||
|
|
||||||
dr.setState(state);
|
|
||||||
dr.setBounds(rect);
|
|
||||||
dr.draw(canvas);
|
|
||||||
}
|
|
||||||
|
|
||||||
Paint paint = new Paint();
|
|
||||||
paint.setAntiAlias(true);
|
|
||||||
paint.setTextAlign(Paint.Align.CENTER);
|
|
||||||
paint.setTextSize(50);
|
|
||||||
paint.setColor(Color.BLACK);
|
|
||||||
|
|
||||||
if (key.label != null) {
|
|
||||||
canvas.drawText(
|
|
||||||
key.label.toString(),
|
|
||||||
key.x + (key.width / 2),
|
|
||||||
initdrawy + (key.height + paint.getTextSize() - paint.descent()) / 2,
|
|
||||||
paint);
|
|
||||||
} else if (key.icon != null) {
|
|
||||||
int intriWidth = key.icon.getIntrinsicWidth();
|
|
||||||
int intriHeight = key.icon.getIntrinsicHeight();
|
|
||||||
|
|
||||||
final int drawableX = key.x + (key.width - intriWidth) / 2;
|
|
||||||
final int drawableY = initdrawy + (key.height - intriHeight) / 2;
|
|
||||||
|
|
||||||
key.icon.setBounds(
|
|
||||||
drawableX, drawableY, drawableX + intriWidth,
|
|
||||||
drawableY + intriHeight);
|
|
||||||
|
|
||||||
key.icon.draw(canvas);
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas.restore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,97 +0,0 @@
|
|||||||
package ${domain}.base.ui.spinner;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.graphics.drawable.ColorDrawable;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.graphics.drawable.LayerDrawable;
|
|
||||||
import android.graphics.drawable.ShapeDrawable;
|
|
||||||
import android.graphics.drawable.shapes.RoundRectShape;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.PopupWindow;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
public class WbSpinner extends TextView {
|
|
||||||
private String[] arrs = {
|
|
||||||
"AAAAAAAAAAAA", "BBBBBBBBBBB", "CCCCCCCCCCC", "DDDDDDDDDDD"
|
|
||||||
};
|
|
||||||
private float scale;
|
|
||||||
private ListView optionList;
|
|
||||||
private Context context;
|
|
||||||
private int width;
|
|
||||||
private boolean isShow = false;
|
|
||||||
private PopupWindow popupWindow;
|
|
||||||
private TextView itemTxtView;
|
|
||||||
|
|
||||||
public WbSpinner(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WbSpinner(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
|
||||||
width = getWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
context = getContext();
|
|
||||||
scale = getResources().getDisplayMetrics().density;
|
|
||||||
this.setTextColor(Color.BLACK);
|
|
||||||
|
|
||||||
this.setOnClickListener(new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (isShow) {
|
|
||||||
popupWindow.dismiss();
|
|
||||||
isShow = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
isShow = true;
|
|
||||||
optionList = new ListView(context);
|
|
||||||
optionList.setDivider(new ColorDrawable(Color.parseColor("#efefef")));
|
|
||||||
optionList.setDividerHeight(1);
|
|
||||||
optionList.setFadingEdgeLength(0);
|
|
||||||
|
|
||||||
ShapeDrawable shapeDrawable = new ShapeDrawable(new RoundRectShape(new float[]{0, 0, 0, 0, 5, 5, 5, 5}, new RectF((int) (1 * scale), (int) (1 * scale), (int) (1 * scale), (int) (1 * scale)), new float[]{0, 0, 0, 0, 5, 5, 5, 5}));
|
|
||||||
shapeDrawable.getPaint().setColor(Color.parseColor("#efefef"));
|
|
||||||
shapeDrawable.setPadding((int) (1 * scale), 0, (int) (1 * scale), (int) (1 * scale));
|
|
||||||
|
|
||||||
ColorDrawable colorDrawable = new ColorDrawable(Color.WHITE);
|
|
||||||
LayerDrawable layerDrawable = new LayerDrawable(new Drawable[]{colorDrawable, shapeDrawable});
|
|
||||||
optionList.setBackground(layerDrawable);
|
|
||||||
|
|
||||||
itemTxtView = new TextView(getContext());
|
|
||||||
itemTxtView.setBackgroundColor(Color.BLUE);
|
|
||||||
int id = (int) (new Date().getTime());
|
|
||||||
itemTxtView.setId(id);
|
|
||||||
|
|
||||||
optionList.setAdapter(new ArrayAdapter<String>(context, id, arrs));
|
|
||||||
optionList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
|
||||||
WbSpinner.this.setText(arrs[position]);
|
|
||||||
popupWindow.dismiss();
|
|
||||||
isShow = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
popupWindow = new PopupWindow(width, ViewGroup.LayoutParams.WRAP_CONTENT);
|
|
||||||
popupWindow.setContentView(optionList);
|
|
||||||
popupWindow.showAsDropDown(WbSpinner.this, 0, 0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
package ${domain}.base.ui.textview;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.text.TextPaint;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
|
|
||||||
public class AverageTextView extends android.support.v7.widget.AppCompatTextView {
|
|
||||||
|
|
||||||
public AverageTextView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AverageTextView(Context context, @Nullable AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
TextPaint paint = getPaint();
|
|
||||||
paint.setTextAlign(Paint.Align.CENTER);
|
|
||||||
paint.setColor(getCurrentTextColor());
|
|
||||||
|
|
||||||
String mText = getText().toString();
|
|
||||||
int width = getWidth() - getPaddingLeft() - getPaddingRight();
|
|
||||||
int height = getHeight() - getPaddingTop() - getPaddingBottom();
|
|
||||||
int x_offset = getPaddingLeft();
|
|
||||||
int y_offset = getPaddingTop();
|
|
||||||
|
|
||||||
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
|
|
||||||
float offset = (Math.abs(fontMetrics.top) - fontMetrics.bottom) / 2;
|
|
||||||
|
|
||||||
if (mText.length() >= 2) {
|
|
||||||
String firstF = String.valueOf(mText.charAt(0));
|
|
||||||
String lastF = String.valueOf(mText.charAt(mText.length() - 1));
|
|
||||||
|
|
||||||
float firstF_W = paint.measureText(firstF);
|
|
||||||
float lastF_W = paint.measureText(lastF);
|
|
||||||
|
|
||||||
{// 绘制首位字符
|
|
||||||
canvas.drawText(firstF, firstF_W / 2 + x_offset, height / 2 + offset + y_offset, paint);
|
|
||||||
canvas.drawText(lastF, width - lastF_W / 2 + x_offset, height / 2 + offset + y_offset, paint);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果大于2个才均分
|
|
||||||
if (mText.length() > 2) {
|
|
||||||
float remainingWidth = width - firstF_W / 2 - lastF_W / 2;//剩余宽度
|
|
||||||
float averageW = remainingWidth / (mText.length() - 2 + 1);//等分距离
|
|
||||||
|
|
||||||
for (int i = 1; i < mText.length() - 1; i++) {//循环绘文字
|
|
||||||
String f = String.valueOf(mText.charAt(i));
|
|
||||||
canvas.drawText(f, firstF_W/2 + i * averageW + x_offset, height / 2 + offset + y_offset, paint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
package ${domain}.base.ui.textview;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by wangbing on 2018/4/7.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class TipTextView extends TextView {
|
|
||||||
private long time = 3000;
|
|
||||||
private String lastValue = "";
|
|
||||||
private Runnable runnable = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
time -= 1000;
|
|
||||||
if (time <= 0) {
|
|
||||||
TipTextView.this.setText("");
|
|
||||||
} else {
|
|
||||||
postDelayed(runnable, 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public TipTextView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TipTextView(Context context, @Nullable AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TipTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
|
||||||
super(context, attrs, defStyleAttr);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setText(CharSequence text, BufferType type) {
|
|
||||||
this.time = 3000;
|
|
||||||
postDelayed(runnable, 1000);
|
|
||||||
|
|
||||||
super.setText(text, type);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
package ${domain}.base.ui.textview;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
|
||||||
import android.graphics.drawable.StateListDrawable;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.widget.EditText;
|
|
||||||
|
|
||||||
public class WbEditText extends EditText {
|
|
||||||
private float density;
|
|
||||||
private Paint paint;
|
|
||||||
|
|
||||||
public WbEditText(Context context) {
|
|
||||||
super(context);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public WbEditText(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
density = getResources().getDisplayMetrics().density;
|
|
||||||
|
|
||||||
StateListDrawable stateListDrawable = new StateListDrawable();
|
|
||||||
|
|
||||||
{
|
|
||||||
Bitmap bitmap = Bitmap.createBitmap((int) (density * 20), (int) (density * 20), Bitmap.Config.ARGB_4444);
|
|
||||||
Canvas canvas = new Canvas(bitmap);
|
|
||||||
paint = new Paint();
|
|
||||||
canvas.drawCircle(density * 20 / 2, density * 20 / 2, density * 20 / 2, paint);
|
|
||||||
|
|
||||||
BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), bitmap);
|
|
||||||
bitmapDrawable.setBounds((int) (density * 20), (int) (density * 20), (int) (density * 20), (int) (density * 20));
|
|
||||||
bitmapDrawable.setGravity(Gravity.RIGHT);
|
|
||||||
|
|
||||||
stateListDrawable.addState(new int[]{android.R.attr.state_focused}, bitmapDrawable);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
this.setBackground(stateListDrawable);
|
|
||||||
this.setPadding(20, 20, 50, 20);
|
|
||||||
this.setMinimumWidth(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
|
||||||
float x = event.getX();
|
|
||||||
float y = event.getY();
|
|
||||||
|
|
||||||
int width = getWidth();
|
|
||||||
int height = getHeight();
|
|
||||||
|
|
||||||
if (x > (width - density * 20) && y > height / 2 - density * 10 && y < (height / 2 + density * 10)) {
|
|
||||||
paint.setColor(Color.BLUE);
|
|
||||||
invalidate();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return super.onTouchEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
package ${domain}.base.ui.textview;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by wangbing on 16/6/2.
|
|
||||||
*/
|
|
||||||
public class WbTextView extends TextView {
|
|
||||||
private int mOffsetY = 0;
|
|
||||||
public Bitmap lastBitmap;
|
|
||||||
|
|
||||||
public WbTextView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WbTextView(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
if (lastBitmap != null) {
|
|
||||||
canvas.drawBitmap(lastBitmap, 0, mOffsetY - getHeight(), null);
|
|
||||||
canvas.translate(0, mOffsetY);
|
|
||||||
}
|
|
||||||
super.onDraw(canvas);
|
|
||||||
|
|
||||||
if (mOffsetY == 0) {
|
|
||||||
lastBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
|
|
||||||
super.onDraw(new Canvas(lastBitmap));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setText(CharSequence text, BufferType type) {
|
|
||||||
mOffsetY = getHeight();
|
|
||||||
post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (mOffsetY > 0) {
|
|
||||||
mOffsetY -= 5;
|
|
||||||
if (mOffsetY < 0) mOffsetY = 0;
|
|
||||||
postDelayed(this, 10);
|
|
||||||
} else {
|
|
||||||
mOffsetY = 0;
|
|
||||||
}
|
|
||||||
System.out.println(mOffsetY);
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
super.setText(text, type);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
package ${domain}.base.ui.textview;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by bingwang on 2016/6/4.
|
|
||||||
*/
|
|
||||||
public class WbTextView1 extends TextView {
|
|
||||||
private int r = 250;
|
|
||||||
|
|
||||||
public void setR(int r) {
|
|
||||||
this.r = r;
|
|
||||||
}
|
|
||||||
|
|
||||||
public WbTextView1(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public WbTextView1(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDraw(Canvas canvas) {
|
|
||||||
int width = getWidth();
|
|
||||||
int height = getHeight();
|
|
||||||
int meshWidth = 5;
|
|
||||||
int meshHeight = 5;
|
|
||||||
|
|
||||||
//获得原始位图
|
|
||||||
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
|
||||||
super.onDraw(new Canvas(bitmap));
|
|
||||||
|
|
||||||
//初始化网格坐标
|
|
||||||
float[] vers = new float[(meshWidth + 1) * (meshHeight + 1) * 2];
|
|
||||||
for (int y = 0; y <= meshHeight; y++) {
|
|
||||||
for (int x = 0; x <= meshWidth; x++) {
|
|
||||||
vers[2 * x + y * (2 * (meshWidth + 1))] = (float) width * x / meshWidth;
|
|
||||||
vers[2 * x + y * (2 * (meshWidth + 1)) + 1] = (float) height * y / meshWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//扭曲坐标
|
|
||||||
for (int i = 0; i < vers.length; i += 2) {
|
|
||||||
if (vers[i] != width / 2) {
|
|
||||||
//获取周长
|
|
||||||
float l = Math.abs(vers[i] - width / 2);
|
|
||||||
//获取角度
|
|
||||||
double v = Math.toRadians((l / (2 * Math.PI * r)) * 360);
|
|
||||||
//转换后的长度
|
|
||||||
double v1 = Math.sin(v) * r;
|
|
||||||
//转成实际坐标
|
|
||||||
vers[i] = (float) ((Math.abs(vers[i] - width / 2) / (vers[i] - width / 2)) * v1 + width / 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas.drawBitmapMesh(bitmap, meshWidth, meshHeight, vers, 0, null, 0, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
package ${domain}.base.ui.textview;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.Path;
|
|
||||||
import android.graphics.RectF;
|
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TextView 自带右箭头
|
|
||||||
*/
|
|
||||||
public class WbTextView2 extends TextView {
|
|
||||||
public WbTextView2(Context context) {
|
|
||||||
super(context);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
public WbTextView2(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() {
|
|
||||||
int drawableWidth = 20;
|
|
||||||
int drawableColor = Color.parseColor("#aaaaaa");
|
|
||||||
|
|
||||||
float density = getResources().getDisplayMetrics().density;
|
|
||||||
Bitmap bitmap = Bitmap.createBitmap((int) (1 * drawableWidth * density), (int) (1 * drawableWidth * density), Bitmap.Config.ARGB_4444);
|
|
||||||
|
|
||||||
Canvas canvas = new Canvas(bitmap);
|
|
||||||
Path path = new Path();
|
|
||||||
path.moveTo(0.775f * drawableWidth * density, 0.5f * drawableWidth * density);
|
|
||||||
path.lineTo(0.4f * drawableWidth * density, 0.875f * drawableWidth * density);
|
|
||||||
path.arcTo(new RectF(0.35f * drawableWidth * density, 0.725f * drawableWidth * density, 0.45f * drawableWidth * density, 0.875f * drawableWidth * density), 90, 90, false);
|
|
||||||
path.lineTo(0.65f * drawableWidth * density, 0.5f * drawableWidth * density);
|
|
||||||
path.lineTo(0.35f * drawableWidth * density, 0.2f * drawableWidth * density);
|
|
||||||
path.arcTo(new RectF(0.35f * drawableWidth * density, 0.125f * drawableWidth * density, 0.45f * drawableWidth * density, 0.275f * drawableWidth * density), 180, 90, false);
|
|
||||||
path.lineTo(0.775f * drawableWidth * density, 0.5f * drawableWidth * density);
|
|
||||||
|
|
||||||
Paint paint = new Paint();
|
|
||||||
paint.setColor(drawableColor);
|
|
||||||
canvas.drawPath(path, paint);
|
|
||||||
|
|
||||||
BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), bitmap);
|
|
||||||
bitmapDrawable.setGravity(Gravity.RIGHT);
|
|
||||||
this.setPadding(this.getPaddingLeft(), this.getPaddingTop(), (int) (drawableWidth * density + this.getPaddingRight()), this.getPaddingBottom());
|
|
||||||
this.setBackground(bitmapDrawable);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
package ${domain}.base.ui.toast;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.util.DisplayMetrics;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.view.animation.TranslateAnimation;
|
|
||||||
import android.widget.FrameLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
public class MessageToast extends Toast {
|
|
||||||
private Context mContext;
|
|
||||||
private FrameLayout mRootView;
|
|
||||||
private String message;
|
|
||||||
|
|
||||||
private MessageToast(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MessageToast(Context context, String message) {
|
|
||||||
super(context);
|
|
||||||
this.mContext = context;
|
|
||||||
this.message = message;
|
|
||||||
this.mRootView = new FrameLayout(context);
|
|
||||||
this.setView(mRootView);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void show() {
|
|
||||||
//加入控件
|
|
||||||
TextView tvMessage = new TextView(mContext);
|
|
||||||
tvMessage.setText(message);
|
|
||||||
tvMessage.setGravity(Gravity.CENTER);
|
|
||||||
tvMessage.setBackgroundColor(Color.argb(100, 100, 100, 100));
|
|
||||||
mRootView.addView(tvMessage);
|
|
||||||
|
|
||||||
//高度
|
|
||||||
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
|
|
||||||
DisplayMetrics metrics = new DisplayMetrics();
|
|
||||||
wm.getDefaultDisplay().getMetrics(metrics);
|
|
||||||
tvMessage.setHeight((int) (45 * metrics.density));
|
|
||||||
|
|
||||||
//动画
|
|
||||||
TranslateAnimation translateAnimation = new TranslateAnimation(0f, 0f, 45 * metrics.density, 0.0f);
|
|
||||||
translateAnimation.setDuration(400);
|
|
||||||
tvMessage.startAnimation(translateAnimation);
|
|
||||||
|
|
||||||
//位置
|
|
||||||
this.setGravity(Gravity.BOTTOM | Gravity.FILL_HORIZONTAL, 0, 0);
|
|
||||||
|
|
||||||
super.show();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,134 +0,0 @@
|
|||||||
package ${domain}.base.util;
|
|
||||||
|
|
||||||
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.animation.Animation;
|
|
||||||
import android.view.animation.CycleInterpolator;
|
|
||||||
import android.view.animation.TranslateAnimation;
|
|
||||||
|
|
||||||
public class AnimationUtil {
|
|
||||||
|
|
||||||
public static void shake(View view, int counts, Animation.AnimationListener listener) {
|
|
||||||
Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);
|
|
||||||
translateAnimation.setInterpolator(new CycleInterpolator(counts));
|
|
||||||
translateAnimation.setDuration(500);
|
|
||||||
translateAnimation.setAnimationListener(listener);
|
|
||||||
view.startAnimation(translateAnimation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void shake(View view, int counts) {
|
|
||||||
shake(view, counts, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void toBottom(final View view, long duration, Animation.AnimationListener listener) {
|
|
||||||
TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
|
|
||||||
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
|
|
||||||
0.0f, Animation.RELATIVE_TO_SELF, 1.0f);
|
|
||||||
animation.setDuration(duration);
|
|
||||||
animation.setAnimationListener(listener);
|
|
||||||
view.clearAnimation();
|
|
||||||
view.startAnimation(animation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void toBottom(View view, long duration) {
|
|
||||||
toBottom(view, duration, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void toTop(View view, long duration, Animation.AnimationListener listener) {
|
|
||||||
TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
|
|
||||||
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
|
|
||||||
0.0f, Animation.RELATIVE_TO_SELF, -1.0f);
|
|
||||||
animation.setDuration(duration);
|
|
||||||
animation.setAnimationListener(listener);
|
|
||||||
view.clearAnimation();
|
|
||||||
view.startAnimation(animation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void toTop(View view, long duration) {
|
|
||||||
toTop(view, duration, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void toLeft(View view, long duration, Animation.AnimationListener listener) {
|
|
||||||
TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
|
|
||||||
Animation.RELATIVE_TO_SELF, -1.0f, Animation.RELATIVE_TO_SELF,
|
|
||||||
0.0f, Animation.RELATIVE_TO_SELF, 0.0f);
|
|
||||||
animation.setDuration(duration);
|
|
||||||
animation.setAnimationListener(listener);
|
|
||||||
view.clearAnimation();
|
|
||||||
view.startAnimation(animation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void toLeft(View view, long duration) {
|
|
||||||
toLeft(view, duration, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void toRight(final View view, long duration, Animation.AnimationListener listener) {
|
|
||||||
TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
|
|
||||||
Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF,
|
|
||||||
0.0f, Animation.RELATIVE_TO_SELF, 0.0f);
|
|
||||||
animation.setDuration(duration);
|
|
||||||
animation.setAnimationListener(listener);
|
|
||||||
view.clearAnimation();
|
|
||||||
view.startAnimation(animation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void toRight(final View view, long duration) {
|
|
||||||
toRight(view, duration, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void fromBottom(View view, long duration, Animation.AnimationListener listener) {
|
|
||||||
TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
|
|
||||||
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
|
|
||||||
1.0f, Animation.RELATIVE_TO_SELF, 0.0f);
|
|
||||||
animation.setDuration(duration);
|
|
||||||
animation.setAnimationListener(listener);
|
|
||||||
view.clearAnimation();
|
|
||||||
view.startAnimation(animation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void fromBottom(View view, long duration) {
|
|
||||||
fromBottom(view, duration, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void fromTop(View view, long duration, Animation.AnimationListener listener) {
|
|
||||||
TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f,
|
|
||||||
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
|
|
||||||
-1.0f, Animation.RELATIVE_TO_SELF, 0.0f);
|
|
||||||
animation.setDuration(duration);
|
|
||||||
animation.setAnimationListener(listener);
|
|
||||||
view.clearAnimation();
|
|
||||||
view.startAnimation(animation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void fromTop(View view, long duration) {
|
|
||||||
fromTop(view, duration, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void fromLeft(View view, long duration, Animation.AnimationListener listener) {
|
|
||||||
TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, -1.0f,
|
|
||||||
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
|
|
||||||
0.0f, Animation.RELATIVE_TO_SELF, 0.0f);
|
|
||||||
animation.setDuration(duration);
|
|
||||||
animation.setAnimationListener(listener);
|
|
||||||
view.clearAnimation();
|
|
||||||
view.startAnimation(animation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void fromLeft(View view, long duration) {
|
|
||||||
fromLeft(view, duration, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void fromRight(View view, long duration, Animation.AnimationListener listener) {
|
|
||||||
TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 1.0f,
|
|
||||||
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,
|
|
||||||
0.0f, Animation.RELATIVE_TO_SELF, 0.0f);
|
|
||||||
animation.setDuration(duration);
|
|
||||||
animation.setAnimationListener(listener);
|
|
||||||
view.clearAnimation();
|
|
||||||
view.startAnimation(animation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void fromRight(View view, long duration) {
|
|
||||||
fromRight(view, duration, null);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,507 +0,0 @@
|
|||||||
package ${domain}.base.util;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base64Util
|
|
||||||
*
|
|
||||||
* @author wangbing
|
|
||||||
* @version 0.0.1
|
|
||||||
* @since 2017-01-01
|
|
||||||
*/
|
|
||||||
public class Base64Util {
|
|
||||||
private static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
|
|
||||||
private static final int[] IA = new int[256];
|
|
||||||
|
|
||||||
static {
|
|
||||||
Arrays.fill(IA, -1);
|
|
||||||
for(int i = 0, iS = CA.length; i < iS; i++)
|
|
||||||
IA[CA[i]] = i;
|
|
||||||
IA['='] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final static char[] encodeToChar(byte[] sArr, boolean lineSep) {
|
|
||||||
// Check special case
|
|
||||||
int sLen = sArr != null ? sArr.length : 0;
|
|
||||||
if(sLen == 0)
|
|
||||||
return new char[0];
|
|
||||||
|
|
||||||
int eLen = (sLen / 3) * 3; // Length of even 24-bits.
|
|
||||||
int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count
|
|
||||||
int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array
|
|
||||||
char[] dArr = new char[dLen];
|
|
||||||
|
|
||||||
// Encode even 24-bits
|
|
||||||
for(int s = 0, d = 0, cc = 0; s < eLen; ) {
|
|
||||||
// Copy next three bytes into lower 24 bits of int, paying attension to sign.
|
|
||||||
int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff);
|
|
||||||
|
|
||||||
// Encode the int into four chars
|
|
||||||
dArr[d++] = CA[(i >>> 18) & 0x3f];
|
|
||||||
dArr[d++] = CA[(i >>> 12) & 0x3f];
|
|
||||||
dArr[d++] = CA[(i >>> 6) & 0x3f];
|
|
||||||
dArr[d++] = CA[i & 0x3f];
|
|
||||||
|
|
||||||
// Add optional line separator
|
|
||||||
if(lineSep && ++cc == 19 && d < dLen - 2) {
|
|
||||||
dArr[d++] = '\r';
|
|
||||||
dArr[d++] = '\n';
|
|
||||||
cc = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pad and encode last bits if source isn't even 24 bits.
|
|
||||||
int left = sLen - eLen; // 0 - 2.
|
|
||||||
if(left > 0) {
|
|
||||||
// Prepare the int
|
|
||||||
int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);
|
|
||||||
|
|
||||||
// Set last four chars
|
|
||||||
dArr[dLen - 4] = CA[i >> 12];
|
|
||||||
dArr[dLen - 3] = CA[(i >>> 6) & 0x3f];
|
|
||||||
dArr[dLen - 2] = left == 2 ? CA[i & 0x3f] : '=';
|
|
||||||
dArr[dLen - 1] = '=';
|
|
||||||
}
|
|
||||||
return dArr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final static byte[] decode(char[] sArr) {
|
|
||||||
// Check special case
|
|
||||||
int sLen = sArr != null ? sArr.length : 0;
|
|
||||||
if(sLen == 0)
|
|
||||||
return new byte[0];
|
|
||||||
|
|
||||||
// Count illegal characters (including '\r', '\n') to know what size the returned array will be,
|
|
||||||
// so we don't have to reallocate & copy it later.
|
|
||||||
int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
|
|
||||||
for(int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out.
|
|
||||||
if(IA[sArr[i]] < 0)
|
|
||||||
sepCnt++;
|
|
||||||
|
|
||||||
// Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045.
|
|
||||||
if((sLen - sepCnt) % 4 != 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
int pad = 0;
|
|
||||||
for(int i = sLen; i > 1 && IA[sArr[--i]] <= 0; )
|
|
||||||
if(sArr[i] == '=')
|
|
||||||
pad++;
|
|
||||||
|
|
||||||
int len = ((sLen - sepCnt) * 6 >> 3) - pad;
|
|
||||||
|
|
||||||
byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
|
|
||||||
|
|
||||||
for(int s = 0, d = 0; d < len; ) {
|
|
||||||
// Assemble three bytes into an int from four "valid" characters.
|
|
||||||
int i = 0;
|
|
||||||
for(int j = 0; j < 4; j++) { // j only increased if a valid char was found.
|
|
||||||
int c = IA[sArr[s++]];
|
|
||||||
if(c >= 0)
|
|
||||||
i |= c << (18 - j * 6);
|
|
||||||
else
|
|
||||||
j--;
|
|
||||||
}
|
|
||||||
// Add the bytes
|
|
||||||
dArr[d++] = (byte) (i >> 16);
|
|
||||||
if(d < len) {
|
|
||||||
dArr[d++] = (byte) (i >> 8);
|
|
||||||
if(d < len)
|
|
||||||
dArr[d++] = (byte) i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dArr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decodes a BASE64 encoded char array that is known to be resonably well formatted. The method is about twice as
|
|
||||||
* fast as {@link =#=decode(char[])}. The preconditions are:<br>
|
|
||||||
* + The array must have a line length of 76 chars OR no line separators at all (one line).<br>
|
|
||||||
* + Line separator must be "\r\n", as specified in RFC 2045
|
|
||||||
* + The array must not contain illegal characters within the encoded string<br>
|
|
||||||
* + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br>
|
|
||||||
*
|
|
||||||
* @param sArr The source array. Length 0 will return an empty array. <code>null</code> will throw an exception.
|
|
||||||
* @return The decoded array of bytes. May be of length 0.
|
|
||||||
*/
|
|
||||||
public final static byte[] decodeFast(char[] sArr) {
|
|
||||||
// Check special case
|
|
||||||
int sLen = sArr.length;
|
|
||||||
if(sLen == 0)
|
|
||||||
return new byte[0];
|
|
||||||
|
|
||||||
int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
|
|
||||||
|
|
||||||
// Trim illegal chars from start
|
|
||||||
while(sIx < eIx && IA[sArr[sIx]] < 0)
|
|
||||||
sIx++;
|
|
||||||
|
|
||||||
// Trim illegal chars from end
|
|
||||||
while(eIx > 0 && IA[sArr[eIx]] < 0)
|
|
||||||
eIx--;
|
|
||||||
|
|
||||||
// get the padding count (=) (0, 1 or 2)
|
|
||||||
int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end.
|
|
||||||
int cCnt = eIx - sIx + 1; // Content count including possible separators
|
|
||||||
int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0;
|
|
||||||
|
|
||||||
int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
|
|
||||||
byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
|
|
||||||
|
|
||||||
// Decode all but the last 0 - 2 bytes.
|
|
||||||
int d = 0;
|
|
||||||
for(int cc = 0, eLen = (len / 3) * 3; d < eLen; ) {
|
|
||||||
// Assemble three bytes into an int from four "valid" characters.
|
|
||||||
int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]];
|
|
||||||
|
|
||||||
// Add the bytes
|
|
||||||
dArr[d++] = (byte) (i >> 16);
|
|
||||||
dArr[d++] = (byte) (i >> 8);
|
|
||||||
dArr[d++] = (byte) i;
|
|
||||||
|
|
||||||
// If line separator, jump over it.
|
|
||||||
if(sepCnt > 0 && ++cc == 19) {
|
|
||||||
sIx += 2;
|
|
||||||
cc = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(d < len) {
|
|
||||||
// Decode last 1-3 bytes (incl '=') into 1-3 bytes
|
|
||||||
int i = 0;
|
|
||||||
for(int j = 0; sIx <= eIx - pad; j++)
|
|
||||||
i |= IA[sArr[sIx++]] << (18 - j * 6);
|
|
||||||
|
|
||||||
for(int r = 16; d < len; r -= 8)
|
|
||||||
dArr[d++] = (byte) (i >> r);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dArr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encodes a raw byte array into a BASE64 <code>byte[]</code> representation i accordance with RFC 2045.
|
|
||||||
*
|
|
||||||
* @param sArr The bytes to convert. If <code>null</code> or length 0 an empty array will be returned.
|
|
||||||
* @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br>
|
|
||||||
* No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a
|
|
||||||
* little faster.
|
|
||||||
* @return A BASE64 encoded array. Never <code>null</code>.
|
|
||||||
*/
|
|
||||||
public final static byte[] encodeToByte(byte[] sArr, boolean lineSep) {
|
|
||||||
// Check special case
|
|
||||||
int sLen = sArr != null ? sArr.length : 0;
|
|
||||||
if(sLen == 0)
|
|
||||||
return new byte[0];
|
|
||||||
|
|
||||||
int eLen = (sLen / 3) * 3; // Length of even 24-bits.
|
|
||||||
int cCnt = ((sLen - 1) / 3 + 1) << 2; // Returned character count
|
|
||||||
int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length of returned array
|
|
||||||
byte[] dArr = new byte[dLen];
|
|
||||||
|
|
||||||
// Encode even 24-bits
|
|
||||||
for(int s = 0, d = 0, cc = 0; s < eLen; ) {
|
|
||||||
// Copy next three bytes into lower 24 bits of int, paying attension to sign.
|
|
||||||
int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8 | (sArr[s++] & 0xff);
|
|
||||||
|
|
||||||
// Encode the int into four chars
|
|
||||||
dArr[d++] = (byte) CA[(i >>> 18) & 0x3f];
|
|
||||||
dArr[d++] = (byte) CA[(i >>> 12) & 0x3f];
|
|
||||||
dArr[d++] = (byte) CA[(i >>> 6) & 0x3f];
|
|
||||||
dArr[d++] = (byte) CA[i & 0x3f];
|
|
||||||
|
|
||||||
// Add optional line separator
|
|
||||||
if(lineSep && ++cc == 19 && d < dLen - 2) {
|
|
||||||
dArr[d++] = '\r';
|
|
||||||
dArr[d++] = '\n';
|
|
||||||
cc = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pad and encode last bits if source isn't an even 24 bits.
|
|
||||||
int left = sLen - eLen; // 0 - 2.
|
|
||||||
if(left > 0) {
|
|
||||||
// Prepare the int
|
|
||||||
int i = ((sArr[eLen] & 0xff) << 10) | (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);
|
|
||||||
|
|
||||||
// Set last four chars
|
|
||||||
dArr[dLen - 4] = (byte) CA[i >> 12];
|
|
||||||
dArr[dLen - 3] = (byte) CA[(i >>> 6) & 0x3f];
|
|
||||||
dArr[dLen - 2] = left == 2 ? (byte) CA[i & 0x3f] : (byte) '=';
|
|
||||||
dArr[dLen - 1] = '=';
|
|
||||||
}
|
|
||||||
return dArr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decodes a BASE64 encoded byte array. All illegal characters will be ignored and can handle both arrays with
|
|
||||||
* and without line separators.
|
|
||||||
*
|
|
||||||
* @param sArr The source array. Length 0 will return an empty array. <code>null</code> will throw an exception.
|
|
||||||
* @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters
|
|
||||||
* (including '=') isn't divideable by 4. (I.e. definitely corrupted).
|
|
||||||
*/
|
|
||||||
public final static byte[] decode(byte[] sArr) {
|
|
||||||
// Check special case
|
|
||||||
int sLen = sArr.length;
|
|
||||||
|
|
||||||
// Count illegal characters (including '\r', '\n') to know what size the returned array will be,
|
|
||||||
// so we don't have to reallocate & copy it later.
|
|
||||||
int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
|
|
||||||
for(int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out.
|
|
||||||
if(IA[sArr[i] & 0xff] < 0)
|
|
||||||
sepCnt++;
|
|
||||||
|
|
||||||
// Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045.
|
|
||||||
if((sLen - sepCnt) % 4 != 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
int pad = 0;
|
|
||||||
for(int i = sLen; i > 1 && IA[sArr[--i] & 0xff] <= 0; )
|
|
||||||
if(sArr[i] == '=')
|
|
||||||
pad++;
|
|
||||||
|
|
||||||
int len = ((sLen - sepCnt) * 6 >> 3) - pad;
|
|
||||||
|
|
||||||
byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
|
|
||||||
|
|
||||||
for(int s = 0, d = 0; d < len; ) {
|
|
||||||
// Assemble three bytes into an int from four "valid" characters.
|
|
||||||
int i = 0;
|
|
||||||
for(int j = 0; j < 4; j++) { // j only increased if a valid char was found.
|
|
||||||
int c = IA[sArr[s++] & 0xff];
|
|
||||||
if(c >= 0)
|
|
||||||
i |= c << (18 - j * 6);
|
|
||||||
else
|
|
||||||
j--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the bytes
|
|
||||||
dArr[d++] = (byte) (i >> 16);
|
|
||||||
if(d < len) {
|
|
||||||
dArr[d++] = (byte) (i >> 8);
|
|
||||||
if(d < len)
|
|
||||||
dArr[d++] = (byte) i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dArr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decodes a BASE64 encoded byte array that is known to be resonably well formatted. The method is about twice as
|
|
||||||
* fast as {@link =#=decode(byte[])}. The preconditions are:<br>
|
|
||||||
* + The array must have a line length of 76 chars OR no line separators at all (one line).<br>
|
|
||||||
* + Line separator must be "\r\n", as specified in RFC 2045
|
|
||||||
* + The array must not contain illegal characters within the encoded string<br>
|
|
||||||
* + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br>
|
|
||||||
*
|
|
||||||
* @param sArr The source array. Length 0 will return an empty array. <code>null</code> will throw an exception.
|
|
||||||
* @return The decoded array of bytes. May be of length 0.
|
|
||||||
*/
|
|
||||||
public final static byte[] decodeFast(byte[] sArr) {
|
|
||||||
// Check special case
|
|
||||||
int sLen = sArr.length;
|
|
||||||
if(sLen == 0)
|
|
||||||
return new byte[0];
|
|
||||||
|
|
||||||
int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
|
|
||||||
|
|
||||||
// Trim illegal chars from start
|
|
||||||
while(sIx < eIx && IA[sArr[sIx] & 0xff] < 0)
|
|
||||||
sIx++;
|
|
||||||
|
|
||||||
// Trim illegal chars from end
|
|
||||||
while(eIx > 0 && IA[sArr[eIx] & 0xff] < 0)
|
|
||||||
eIx--;
|
|
||||||
|
|
||||||
// get the padding count (=) (0, 1 or 2)
|
|
||||||
int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0; // Count '=' at end.
|
|
||||||
int cCnt = eIx - sIx + 1; // Content count including possible separators
|
|
||||||
int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0;
|
|
||||||
|
|
||||||
int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
|
|
||||||
byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
|
|
||||||
|
|
||||||
// Decode all but the last 0 - 2 bytes.
|
|
||||||
int d = 0;
|
|
||||||
for(int cc = 0, eLen = (len / 3) * 3; d < eLen; ) {
|
|
||||||
// Assemble three bytes into an int from four "valid" characters.
|
|
||||||
int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12 | IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]];
|
|
||||||
|
|
||||||
// Add the bytes
|
|
||||||
dArr[d++] = (byte) (i >> 16);
|
|
||||||
dArr[d++] = (byte) (i >> 8);
|
|
||||||
dArr[d++] = (byte) i;
|
|
||||||
|
|
||||||
// If line separator, jump over it.
|
|
||||||
if(sepCnt > 0 && ++cc == 19) {
|
|
||||||
sIx += 2;
|
|
||||||
cc = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(d < len) {
|
|
||||||
// Decode last 1-3 bytes (incl '=') into 1-3 bytes
|
|
||||||
int i = 0;
|
|
||||||
for(int j = 0; sIx <= eIx - pad; j++)
|
|
||||||
i |= IA[sArr[sIx++]] << (18 - j * 6);
|
|
||||||
|
|
||||||
for(int r = 16; d < len; r -= 8)
|
|
||||||
dArr[d++] = (byte) (i >> r);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dArr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ****************************************************************************************
|
|
||||||
// * String version
|
|
||||||
// ****************************************************************************************
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Encodes a raw byte array into a BASE64 <code>String</code> representation i accordance with RFC 2045.
|
|
||||||
*
|
|
||||||
* @param sArr The bytes to convert. If <code>null</code> or length 0 an empty array will be returned.
|
|
||||||
* @param lineSep Optional "\r\n" after 76 characters, unless end of file.<br>
|
|
||||||
* No line separator will be in breach of RFC 2045 which specifies max 76 per line but will be a
|
|
||||||
* little faster.
|
|
||||||
* @return A BASE64 encoded array. Never <code>null</code>.
|
|
||||||
*/
|
|
||||||
public final static String encodeToString(byte[] sArr, boolean lineSep) {
|
|
||||||
// Reuse char[] since we can't create a String incrementally anyway and StringBuffer/Builder would be slower.
|
|
||||||
return new String(encodeToChar(sArr, lineSep));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decodes a BASE64 encoded <code>String</code>. All illegal characters will be ignored and can handle both strings with
|
|
||||||
* and without line separators.<br>
|
|
||||||
* <b>Note!</b> It can be up to about 2x the speed to call <code>decode(str.toCharArray())</code> instead. That
|
|
||||||
* will create a temporary array though. This version will use <code>str.charAt(i)</code> to iterate the string.
|
|
||||||
*
|
|
||||||
* @param str The source string. <code>null</code> or length 0 will return an empty array.
|
|
||||||
* @return The decoded array of bytes. May be of length 0. Will be <code>null</code> if the legal characters
|
|
||||||
* (including '=') isn't divideable by 4. (I.e. definitely corrupted).
|
|
||||||
*/
|
|
||||||
public final static byte[] decode(String str) {
|
|
||||||
// Check special case
|
|
||||||
int sLen = str != null ? str.length() : 0;
|
|
||||||
if(sLen == 0)
|
|
||||||
return new byte[0];
|
|
||||||
|
|
||||||
// Count illegal characters (including '\r', '\n') to know what size the returned array will be,
|
|
||||||
// so we don't have to reallocate & copy it later.
|
|
||||||
int sepCnt = 0; // Number of separator characters. (Actually illegal characters, but that's a bonus...)
|
|
||||||
for(int i = 0; i < sLen; i++) // If input is "pure" (I.e. no line separators or illegal chars) base64 this loop can be commented out.
|
|
||||||
if(IA[str.charAt(i)] < 0)
|
|
||||||
sepCnt++;
|
|
||||||
|
|
||||||
// Check so that legal chars (including '=') are evenly divideable by 4 as specified in RFC 2045.
|
|
||||||
if((sLen - sepCnt) % 4 != 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// Count '=' at end
|
|
||||||
int pad = 0;
|
|
||||||
for(int i = sLen; i > 1 && IA[str.charAt(--i)] <= 0; )
|
|
||||||
if(str.charAt(i) == '=')
|
|
||||||
pad++;
|
|
||||||
|
|
||||||
int len = ((sLen - sepCnt) * 6 >> 3) - pad;
|
|
||||||
|
|
||||||
byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
|
|
||||||
|
|
||||||
for(int s = 0, d = 0; d < len; ) {
|
|
||||||
// Assemble three bytes into an int from four "valid" characters.
|
|
||||||
int i = 0;
|
|
||||||
for(int j = 0; j < 4; j++) { // j only increased if a valid char was found.
|
|
||||||
int c = IA[str.charAt(s++)];
|
|
||||||
if(c >= 0)
|
|
||||||
i |= c << (18 - j * 6);
|
|
||||||
else
|
|
||||||
j--;
|
|
||||||
}
|
|
||||||
// Add the bytes
|
|
||||||
dArr[d++] = (byte) (i >> 16);
|
|
||||||
if(d < len) {
|
|
||||||
dArr[d++] = (byte) (i >> 8);
|
|
||||||
if(d < len)
|
|
||||||
dArr[d++] = (byte) i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dArr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decodes a BASE64 encoded string that is known to be resonably well formatted. The method is about twice as
|
|
||||||
* fast as {@link =#=decode(String)}. The preconditions are:<br>
|
|
||||||
* + The array must have a line length of 76 chars OR no line separators at all (one line).<br>
|
|
||||||
* + Line separator must be "\r\n", as specified in RFC 2045
|
|
||||||
* + The array must not contain illegal characters within the encoded string<br>
|
|
||||||
* + The array CAN have illegal characters at the beginning and end, those will be dealt with appropriately.<br>
|
|
||||||
*
|
|
||||||
* @param s The source string. Length 0 will return an empty array. <code>null</code> will throw an exception.
|
|
||||||
* @return The decoded array of bytes. May be of length 0.
|
|
||||||
*/
|
|
||||||
public final static byte[] decodeFast(String s) {
|
|
||||||
// Check special case
|
|
||||||
int sLen = s.length();
|
|
||||||
if(sLen == 0)
|
|
||||||
return new byte[0];
|
|
||||||
|
|
||||||
int sIx = 0, eIx = sLen - 1; // Start and end index after trimming.
|
|
||||||
|
|
||||||
// Trim illegal chars from start
|
|
||||||
while(sIx < eIx && IA[s.charAt(sIx) & 0xff] < 0)
|
|
||||||
sIx++;
|
|
||||||
|
|
||||||
// Trim illegal chars from end
|
|
||||||
while(eIx > 0 && IA[s.charAt(eIx) & 0xff] < 0)
|
|
||||||
eIx--;
|
|
||||||
|
|
||||||
// get the padding count (=) (0, 1 or 2)
|
|
||||||
int pad = s.charAt(eIx) == '=' ? (s.charAt(eIx - 1) == '=' ? 2 : 1) : 0; // Count '=' at end.
|
|
||||||
int cCnt = eIx - sIx + 1; // Content count including possible separators
|
|
||||||
int sepCnt = sLen > 76 ? (s.charAt(76) == '\r' ? cCnt / 78 : 0) << 1 : 0;
|
|
||||||
|
|
||||||
int len = ((cCnt - sepCnt) * 6 >> 3) - pad; // The number of decoded bytes
|
|
||||||
byte[] dArr = new byte[len]; // Preallocate byte[] of exact length
|
|
||||||
|
|
||||||
// Decode all but the last 0 - 2 bytes.
|
|
||||||
int d = 0;
|
|
||||||
for(int cc = 0, eLen = (len / 3) * 3; d < eLen; ) {
|
|
||||||
// Assemble three bytes into an int from four "valid" characters.
|
|
||||||
int i = IA[s.charAt(sIx++)] << 18 | IA[s.charAt(sIx++)] << 12 | IA[s.charAt(sIx++)] << 6 | IA[s.charAt(sIx++)];
|
|
||||||
|
|
||||||
// Add the bytes
|
|
||||||
dArr[d++] = (byte) (i >> 16);
|
|
||||||
dArr[d++] = (byte) (i >> 8);
|
|
||||||
dArr[d++] = (byte) i;
|
|
||||||
|
|
||||||
// If line separator, jump over it.
|
|
||||||
if(sepCnt > 0 && ++cc == 19) {
|
|
||||||
sIx += 2;
|
|
||||||
cc = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(d < len) {
|
|
||||||
// Decode last 1-3 bytes (incl '=') into 1-3 bytes
|
|
||||||
int i = 0;
|
|
||||||
for(int j = 0; sIx <= eIx - pad; j++)
|
|
||||||
i |= IA[s.charAt(sIx++)] << (18 - j * 6);
|
|
||||||
|
|
||||||
for(int r = 16; d < len; r -= 8)
|
|
||||||
dArr[d++] = (byte) (i >> r);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dArr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
String s = Base64Util.encodeToString("我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1我搜搜1".getBytes(), false);
|
|
||||||
System.out.println(s);
|
|
||||||
|
|
||||||
byte[] decode = Base64Util.decode(s);
|
|
||||||
System.out.println(new String(decode));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,135 +0,0 @@
|
|||||||
|
|
||||||
package ${domain}.base.util;
|
|
||||||
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.BitmapFactory;
|
|
||||||
import android.graphics.BitmapFactory.Options;
|
|
||||||
import android.graphics.Matrix;
|
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.util.DisplayMetrics;
|
|
||||||
import android.util.TypedValue;
|
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
public final class BitmapUtil {
|
|
||||||
|
|
||||||
|
|
||||||
public static Bitmap scaleBitmap(Bitmap src, int destWidth, int destHeigth) {
|
|
||||||
if (src == null) return null;
|
|
||||||
|
|
||||||
int width = src.getWidth();
|
|
||||||
int height = src.getHeight();
|
|
||||||
|
|
||||||
float scaleWidth = ((float) destWidth) / width;
|
|
||||||
float scaleHeight = ((float) destHeigth) / height;
|
|
||||||
|
|
||||||
Matrix matrix = new Matrix();
|
|
||||||
matrix.postScale(scaleWidth, scaleHeight);
|
|
||||||
return Bitmap.createBitmap(src, 0, 0, width, height, matrix, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Bitmap scaleBitmap(Bitmap src, float scale) {
|
|
||||||
if (src == null) return null;
|
|
||||||
|
|
||||||
int width = src.getWidth();
|
|
||||||
int height = src.getHeight();
|
|
||||||
|
|
||||||
Matrix matrix = new Matrix();
|
|
||||||
matrix.postScale(scale, scale);
|
|
||||||
return Bitmap.createBitmap(src, 0, 0, width, height, matrix, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Drawable getDrawableFromAssetFile(Resources res, String fileName) {
|
|
||||||
InputStream is = null;
|
|
||||||
Drawable icon = null;
|
|
||||||
try {
|
|
||||||
is = res.getAssets().open(fileName);
|
|
||||||
TypedValue typedValue = new TypedValue();
|
|
||||||
typedValue.density = TypedValue.DENSITY_DEFAULT;
|
|
||||||
icon = Drawable.createFromResourceStream(res, typedValue, is, null);
|
|
||||||
} catch (Exception e) {
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (is != null) {
|
|
||||||
is.close();
|
|
||||||
is = null;
|
|
||||||
}
|
|
||||||
} catch (final IOException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Bitmap getBitmapFromAssetFile(Resources res, String fileName) {
|
|
||||||
InputStream is = null;
|
|
||||||
Bitmap bmp = null;
|
|
||||||
try {
|
|
||||||
is = res.getAssets().open(fileName);
|
|
||||||
|
|
||||||
DisplayMetrics metrics = res.getDisplayMetrics();
|
|
||||||
Options opts = new Options();
|
|
||||||
opts.inDensity = (int) (metrics.densityDpi / metrics.scaledDensity);
|
|
||||||
bmp = BitmapFactory.decodeStream(is, null, opts);
|
|
||||||
is.close();
|
|
||||||
is = null;
|
|
||||||
} catch (Exception e) {
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (is != null) is.close();
|
|
||||||
} catch (final IOException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Drawable getDrawableFromFile(Resources res, String fileName) {
|
|
||||||
FileInputStream fis = null;
|
|
||||||
Drawable icon = null;
|
|
||||||
try {
|
|
||||||
fis = new FileInputStream(fileName);
|
|
||||||
DisplayMetrics metrics = res.getDisplayMetrics();
|
|
||||||
Options opts = new Options();
|
|
||||||
opts.inDensity = (int) (metrics.densityDpi / metrics.scaledDensity);
|
|
||||||
Bitmap bmp = BitmapFactory.decodeStream(fis, null, opts);
|
|
||||||
|
|
||||||
fis.close();
|
|
||||||
fis = null;
|
|
||||||
if (bmp != null) {
|
|
||||||
icon = new BitmapDrawable(bmp);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (fis != null) fis.close();
|
|
||||||
} catch (final IOException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Bitmap getBitmapFromFile(Resources res, String fileName) {
|
|
||||||
FileInputStream fis = null;
|
|
||||||
Bitmap bmp = null;
|
|
||||||
try {
|
|
||||||
fis = new FileInputStream(fileName);
|
|
||||||
|
|
||||||
DisplayMetrics metrics = res.getDisplayMetrics();
|
|
||||||
Options opts = new Options();
|
|
||||||
opts.inDensity = (int) (metrics.densityDpi / metrics.scaledDensity);
|
|
||||||
bmp = BitmapFactory.decodeStream(fis, null, opts);
|
|
||||||
fis.close();
|
|
||||||
fis = null;
|
|
||||||
} catch (Exception e) {
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (fis != null) fis.close();
|
|
||||||
} catch (final IOException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bmp;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
package ${domain}.base;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 内容辅助类
|
|
||||||
*/
|
|
||||||
public class Consant {
|
|
||||||
|
|
||||||
//是否记住密码
|
|
||||||
public static String REMEMBER_PASSWORD = "remember_password";
|
|
||||||
|
|
||||||
//是否自动登录
|
|
||||||
public static String AUTO_LOGIN = "auto_login";
|
|
||||||
|
|
||||||
//文件存储目录
|
|
||||||
public static String DIR = "WBUI";
|
|
||||||
|
|
||||||
//图片存储目录
|
|
||||||
public static String DIR_IMG = "WBUI/temp";
|
|
||||||
|
|
||||||
public static int REQUESTCODE_FROM_FRAGMENT = 1;
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
package ${domain}.base.util;
|
|
||||||
|
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.Key;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
|
|
||||||
import javax.crypto.BadPaddingException;
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.crypto.IllegalBlockSizeException;
|
|
||||||
import javax.crypto.KeyGenerator;
|
|
||||||
import javax.crypto.NoSuchPaddingException;
|
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
|
||||||
|
|
||||||
public class DESUtil {
|
|
||||||
|
|
||||||
public static final String ALGORITHM_DES = "DES";
|
|
||||||
|
|
||||||
public static Key generateKey(String algorithm) throws NoSuchAlgorithmException {
|
|
||||||
KeyGenerator generator = KeyGenerator.getInstance(algorithm);
|
|
||||||
return generator.generateKey();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Key getKey(byte[] key, String algorithm) throws NoSuchAlgorithmException {
|
|
||||||
return new SecretKeySpec(key, algorithm);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] encrypt(String transformation, Key key, String content)
|
|
||||||
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
|
|
||||||
IllegalBlockSizeException, BadPaddingException {
|
|
||||||
Cipher cipher = Cipher.getInstance(transformation);
|
|
||||||
// 加密模式
|
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
|
||||||
return cipher.doFinal(content.getBytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] decrypt(String transformation, Key key, byte[] content)
|
|
||||||
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
|
|
||||||
IllegalBlockSizeException, BadPaddingException {
|
|
||||||
Cipher cipher = Cipher.getInstance(transformation);
|
|
||||||
// 解密模式
|
|
||||||
cipher.init(Cipher.DECRYPT_MODE, key);
|
|
||||||
return cipher.doFinal(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,433 +0,0 @@
|
|||||||
package ${domain}.base.util;
|
|
||||||
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.ContextWrapper;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.database.DatabaseErrorHandler;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.database.sqlite.SQLiteException;
|
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import ${domain}.base.Consant;
|
|
||||||
|
|
||||||
public class DataBaseUtil {
|
|
||||||
private String defaultPath = "";
|
|
||||||
private String defaultDBName = "data.db";
|
|
||||||
private SQLiteOpenHelper sqLiteOpenHelper;
|
|
||||||
private SQLiteDatabase writableDatabase;
|
|
||||||
private List<Class> entityList;
|
|
||||||
|
|
||||||
private DataBaseUtil() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public DataBaseUtil(Context context, Register register) {
|
|
||||||
entityList = register.run();
|
|
||||||
File ownCacheDirectory = StorageUtil.getOwnCacheDirectory(context, Consant.DIR);
|
|
||||||
defaultPath = ownCacheDirectory.getAbsolutePath();
|
|
||||||
sqLiteOpenHelper = new SQLiteOpenHelperImpl(context, defaultDBName, null, 1);
|
|
||||||
writableDatabase = sqLiteOpenHelper.getWritableDatabase();
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> List<T> query(T t) {
|
|
||||||
return query(t, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> List<T> query(T t, int start, int size) {
|
|
||||||
ArrayList<T> list = new ArrayList<>();
|
|
||||||
try {
|
|
||||||
Class a = findEntity(t);
|
|
||||||
//1、获取表名
|
|
||||||
String table = a.getSimpleName();
|
|
||||||
//2、获取字段列表
|
|
||||||
List<Field> fs = new ArrayList<>();
|
|
||||||
for (Field f : a.getDeclaredFields()) {
|
|
||||||
if (f.isAnnotationPresent(DBField.class)) {
|
|
||||||
fs.add(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String[] columns = new String[fs.size()];
|
|
||||||
int where = 0;
|
|
||||||
for (int i = 0; i < columns.length; i++) {
|
|
||||||
fs.get(i).setAccessible(true);
|
|
||||||
columns[i] = fs.get(i).getName().toUpperCase();
|
|
||||||
try {
|
|
||||||
Object o = fs.get(i).get(t);
|
|
||||||
if (o != null) {
|
|
||||||
where++;
|
|
||||||
}
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
//3、获取where条件
|
|
||||||
StringBuilder selectionSB = new StringBuilder("");
|
|
||||||
String[] selectionArgs = null;
|
|
||||||
if (where > 0) {
|
|
||||||
selectionArgs = new String[where];
|
|
||||||
where = 0;
|
|
||||||
for (int i = 0; i < columns.length; i++) {
|
|
||||||
columns[i] = fs.get(i).getName().toUpperCase();
|
|
||||||
try {
|
|
||||||
Object o = fs.get(i).get(t);
|
|
||||||
if (o != null) {
|
|
||||||
if ("".equals(selectionSB.toString())) {
|
|
||||||
selectionSB.append(" ");
|
|
||||||
} else {
|
|
||||||
selectionSB.append(" and ");
|
|
||||||
}
|
|
||||||
selectionSB.append(columns[i]).append(" like ?");
|
|
||||||
selectionArgs[where] = o.toString();
|
|
||||||
where++;
|
|
||||||
}
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//4、分页
|
|
||||||
String limit = size != 0 ? (start + "," + size) : "";
|
|
||||||
|
|
||||||
//5、其他暂未支持
|
|
||||||
|
|
||||||
Cursor query = null;
|
|
||||||
try {
|
|
||||||
query = writableDatabase.query(table, columns, selectionSB.toString(), selectionArgs, null, null, "", limit);
|
|
||||||
} catch (SQLiteException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (query.moveToNext()) {
|
|
||||||
try {
|
|
||||||
T o = (T) a.newInstance();
|
|
||||||
for (int i = 0; i < fs.size(); i++) {
|
|
||||||
Field field = fs.get(i);
|
|
||||||
String string = query.getString(i);
|
|
||||||
field.set(o, string);
|
|
||||||
}
|
|
||||||
list.add(o);
|
|
||||||
} catch (InstantiationException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> void delete(T t) {
|
|
||||||
try {
|
|
||||||
Class aClass = findEntity(t);
|
|
||||||
//1、获取表名
|
|
||||||
String table = aClass.getSimpleName();
|
|
||||||
//2、获取字段列表
|
|
||||||
List<Field> fs = new ArrayList<>();
|
|
||||||
for (Field f : aClass.getDeclaredFields()) {
|
|
||||||
if (f.isAnnotationPresent(DBField.class)) {
|
|
||||||
fs.add(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String[] columns = new String[fs.size()];
|
|
||||||
int where = 0;
|
|
||||||
for (int i = 0; i < columns.length; i++) {
|
|
||||||
columns[i] = fs.get(i).getName().toUpperCase();
|
|
||||||
try {
|
|
||||||
fs.get(i).setAccessible(true);
|
|
||||||
Object o = fs.get(i).get(t);
|
|
||||||
if (o != null) {
|
|
||||||
where++;
|
|
||||||
}
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
//3、获取where条件
|
|
||||||
StringBuilder selectionSB = new StringBuilder("");
|
|
||||||
String[] selectionArgs = null;
|
|
||||||
if (where > 0) {
|
|
||||||
selectionArgs = new String[where];
|
|
||||||
where = 0;
|
|
||||||
for (int i = 0; i < columns.length; i++) {
|
|
||||||
columns[i] = fs.get(i).getName().toUpperCase();
|
|
||||||
try {
|
|
||||||
fs.get(i).setAccessible(true);
|
|
||||||
Object o = fs.get(i).get(t);
|
|
||||||
if (o != null) {
|
|
||||||
if ("".equals(selectionSB.toString())) {
|
|
||||||
selectionSB.append(" ");
|
|
||||||
} else {
|
|
||||||
selectionSB.append(" and ");
|
|
||||||
}
|
|
||||||
selectionSB.append(columns[i]).append(" = ?");
|
|
||||||
selectionArgs[where] = o.toString();
|
|
||||||
where++;
|
|
||||||
}
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writableDatabase.delete(table, selectionSB.toString(), selectionArgs);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> void insert(T t) {
|
|
||||||
try {
|
|
||||||
Class aClass = findEntity(t);
|
|
||||||
StringBuffer sql = new StringBuffer();
|
|
||||||
String tableName = aClass.getSimpleName();
|
|
||||||
sql.append("INSERT INTO ");
|
|
||||||
sql.append(tableName.toUpperCase());
|
|
||||||
sql.append("(");
|
|
||||||
|
|
||||||
ContentValues contentValues = new ContentValues();
|
|
||||||
StringBuffer fieldsSql = new StringBuffer();
|
|
||||||
StringBuffer valueSql = new StringBuffer();
|
|
||||||
for (Field f : aClass.getDeclaredFields()) {
|
|
||||||
if (f.isAnnotationPresent(DBField.class)) {
|
|
||||||
|
|
||||||
f.setAccessible(true);
|
|
||||||
try {
|
|
||||||
String value = "";
|
|
||||||
Object o = f.get(t);
|
|
||||||
if (o instanceof String) {
|
|
||||||
value = (String) o;
|
|
||||||
valueSql.append(value);
|
|
||||||
} else {
|
|
||||||
valueSql.append("null");
|
|
||||||
}
|
|
||||||
valueSql.append(",");
|
|
||||||
contentValues.put(f.getName().toUpperCase(), value);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
valueSql.append("null,");
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldsSql.append(f.getName().toUpperCase());
|
|
||||||
fieldsSql.append(",");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (",".equals(fieldsSql.substring(fieldsSql.length() - 1, fieldsSql.length()))) {
|
|
||||||
fieldsSql.replace(fieldsSql.length() - 1, fieldsSql.length(), "");
|
|
||||||
}
|
|
||||||
if (",".equals(valueSql.substring(valueSql.length() - 1, valueSql.length()))) {
|
|
||||||
valueSql.replace(valueSql.length() - 1, valueSql.length(), "");
|
|
||||||
}
|
|
||||||
sql.append(fieldsSql);
|
|
||||||
sql.append(") VALUES (");
|
|
||||||
sql.append(valueSql);
|
|
||||||
sql.append(")");
|
|
||||||
|
|
||||||
writableDatabase.insert(tableName, null, contentValues);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> void insertBitch(List<T> data) {
|
|
||||||
if (data == null || data.size() == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
writableDatabase.beginTransaction();
|
|
||||||
for (Object datum : data) {
|
|
||||||
insert(datum);
|
|
||||||
}
|
|
||||||
writableDatabase.setTransactionSuccessful();
|
|
||||||
writableDatabase.endTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查找注册的实体
|
|
||||||
*
|
|
||||||
* @param t
|
|
||||||
* @param <T>
|
|
||||||
* @return
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
private <T> Class findEntity(T t) throws Exception {
|
|
||||||
for (Class aClass : entityList) {
|
|
||||||
if (t.getClass() == aClass) {
|
|
||||||
return aClass;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new Exception("can not find Entity:" + t.getClass().getName() + ", make sure it is registered");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 数据库字段注解
|
|
||||||
*/
|
|
||||||
@Target(ElementType.FIELD)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
public @interface DBField {
|
|
||||||
String value() default "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 利用字段注解拼接sql
|
|
||||||
*
|
|
||||||
* @param mClass
|
|
||||||
* @param sql
|
|
||||||
*/
|
|
||||||
private void fillSql(Class mClass, StringBuffer sql) {
|
|
||||||
Field[] fields = mClass.getDeclaredFields();
|
|
||||||
for (Field f : fields) {
|
|
||||||
if (f.isAnnotationPresent(DBField.class)) {
|
|
||||||
DBField bind = f.getAnnotation(DBField.class);
|
|
||||||
String type = bind.value();
|
|
||||||
sql.append(f.getName().toUpperCase());
|
|
||||||
sql.append(" ");
|
|
||||||
sql.append(type);
|
|
||||||
sql.append(",");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SQLiteOpenHelperImpl extends SQLiteOpenHelper {
|
|
||||||
|
|
||||||
public SQLiteOpenHelperImpl(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
|
|
||||||
super(new DatabaseContext(context), name, factory, version);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SQLiteOpenHelperImpl(Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {
|
|
||||||
super(context, name, factory, version, errorHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(SQLiteDatabase sqLiteDatabase) {
|
|
||||||
for (Class object : entityList) {
|
|
||||||
StringBuffer sql = new StringBuffer();
|
|
||||||
String name = object.getSimpleName();
|
|
||||||
|
|
||||||
sql.append("CREATE TABLE ");
|
|
||||||
sql.append(name);
|
|
||||||
sql.append(" (");
|
|
||||||
fillSql(object, sql);
|
|
||||||
|
|
||||||
sql.replace(sql.length() - 1, sql.length(), "");
|
|
||||||
sql.append(")");
|
|
||||||
sqLiteDatabase.execSQL(sql.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建数据库辅助类,可以自定义数据库存放路径
|
|
||||||
*/
|
|
||||||
class DatabaseContext extends ContextWrapper {
|
|
||||||
|
|
||||||
public DatabaseContext(Context base) {
|
|
||||||
super(base);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public File getDatabasePath(String name) {
|
|
||||||
if ("".equals(defaultPath)) {//defaultPath如果为""则放在程序默认位置
|
|
||||||
defaultPath = getApplicationContext().getDatabasePath("database").getAbsolutePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
File path = new File(defaultPath);
|
|
||||||
if (!path.exists()) {
|
|
||||||
path.mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
File dbfile = new File(path, defaultDBName);
|
|
||||||
|
|
||||||
if (!dbfile.exists()) {
|
|
||||||
try {
|
|
||||||
dbfile.createNewFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dbfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLiteDatabase openOrCreateDatabase(String name, int mode,
|
|
||||||
SQLiteDatabase.CursorFactory factory,
|
|
||||||
DatabaseErrorHandler errorHandler) {
|
|
||||||
return openOrCreateDatabase(name, mode, factory);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SQLiteDatabase openOrCreateDatabase(String name, int mode,
|
|
||||||
SQLiteDatabase.CursorFactory factory) {
|
|
||||||
SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(
|
|
||||||
getDatabasePath(name), null);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface Register {
|
|
||||||
List<Class> run();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 以下为Demo
|
|
||||||
* @param args
|
|
||||||
*/
|
|
||||||
public static void main(String[] args) {
|
|
||||||
//Demo
|
|
||||||
// DataBaseUtil db = new DataBaseUtil(WBUIApplication.getInstance(), new Register() {
|
|
||||||
// @Override
|
|
||||||
// public List<Class> run() {
|
|
||||||
// List<Class> objects = new ArrayList<>();
|
|
||||||
// objects.add(User.class);
|
|
||||||
// return objects;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// //插入数据
|
|
||||||
// db.insert(new User("Test"));
|
|
||||||
// //删除数据
|
|
||||||
// db.delete(new User("Test"));
|
|
||||||
// //查询数据(不分页)
|
|
||||||
// db.query(new User("Test"));
|
|
||||||
// //查询数据(分页)
|
|
||||||
// db.query(new User("Test"),0,10);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Demo Entity
|
|
||||||
*/
|
|
||||||
public static class User {
|
|
||||||
@DataBaseUtil.DBField("VARCHAR(20)")
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public User(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
package ${domain}.base.util;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.TypedValue;
|
|
||||||
|
|
||||||
public class DensityUtil {
|
|
||||||
private DensityUtil() {
|
|
||||||
/* cannot be instantiated */
|
|
||||||
throw new UnsupportedOperationException("cannot be instantiated");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* dp转px
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param dpVal
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static int dp2px(Context context, float dpVal) {
|
|
||||||
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
|
|
||||||
dpVal, context.getResources().getDisplayMetrics());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* sp转px
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param spVal
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static int sp2px(Context context, float spVal) {
|
|
||||||
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
|
|
||||||
spVal, context.getResources().getDisplayMetrics());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* px转dp
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param pxVal
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static float px2dp(Context context, float pxVal) {
|
|
||||||
final float scale = context.getResources().getDisplayMetrics().density;
|
|
||||||
return (pxVal / scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* px转sp
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param pxVal
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static float px2sp(Context context, float pxVal) {
|
|
||||||
return (pxVal / context.getResources().getDisplayMetrics().scaledDensity);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
package ${domain}.base.util;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
|
|
||||||
import com.qmuiteam.qmui.widget.dialog.QMUIDialogAction;
|
|
||||||
|
|
||||||
|
|
||||||
public class DialogUtil {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 展示一个需要确认的消息提示
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param title 标题
|
|
||||||
* @param message 消息内容
|
|
||||||
*/
|
|
||||||
public static void showConfirmMessage(Context context, String title, String message) {
|
|
||||||
QMUIDialog qmuiDialog = new QMUIDialog.MessageDialogBuilder(context)
|
|
||||||
.setMessage(message)
|
|
||||||
.addAction("确定", new QMUIDialogAction.ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(QMUIDialog dialog, int index) {
|
|
||||||
dialog.dismiss();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.create(com.qmuiteam.qmui.R.style.QMUI_Dialog);
|
|
||||||
qmuiDialog.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 展示一个需要确认的消息提示(带回调)
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param title 标题
|
|
||||||
* @param message 消息内容
|
|
||||||
*/
|
|
||||||
public static void showConfirmMessage(Context context, String title, String message, QMUIDialogAction.ActionListener actionListener) {
|
|
||||||
QMUIDialog qmuiDialog = new QMUIDialog.MessageDialogBuilder(context)
|
|
||||||
.setMessage(message)
|
|
||||||
.addAction("取消", new QMUIDialogAction.ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(QMUIDialog dialog, int index) {
|
|
||||||
dialog.dismiss();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.addAction("确定", actionListener)
|
|
||||||
.create(com.qmuiteam.qmui.R.style.QMUI_Dialog);
|
|
||||||
qmuiDialog.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 展示一个信息弹窗
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param title 标题
|
|
||||||
* @param message 消息内容
|
|
||||||
*/
|
|
||||||
public static void showMessage(Context context, String title, String message) {
|
|
||||||
new QMUIDialog.MessageDialogBuilder(context)
|
|
||||||
.setTitle(title)
|
|
||||||
.setMessage(message)
|
|
||||||
.addAction("确认", new QMUIDialogAction.ActionListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(QMUIDialog dialog, int index) {
|
|
||||||
dialog.dismiss();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.create(com.qmuiteam.qmui.R.style.QMUI_Dialog).show();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,217 +0,0 @@
|
|||||||
package ${domain}.base.util;
|
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by wangbing on 16/6/7.
|
|
||||||
*/
|
|
||||||
public class FastBlur {
|
|
||||||
|
|
||||||
public static Bitmap doBlur(Bitmap sentBitmap, int radius,
|
|
||||||
boolean canReuseInBitmap) {
|
|
||||||
Bitmap bitmap;
|
|
||||||
if (canReuseInBitmap) {
|
|
||||||
bitmap = sentBitmap;
|
|
||||||
} else {
|
|
||||||
bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (radius < 1) {
|
|
||||||
return (null);
|
|
||||||
}
|
|
||||||
|
|
||||||
int w = bitmap.getWidth();
|
|
||||||
int h = bitmap.getHeight();
|
|
||||||
|
|
||||||
int[] pix = new int[w * h];
|
|
||||||
bitmap.getPixels(pix, 0, w, 0, 0, w, h);
|
|
||||||
|
|
||||||
int wm = w - 1;
|
|
||||||
int hm = h - 1;
|
|
||||||
int wh = w * h;
|
|
||||||
int div = radius + radius + 1;
|
|
||||||
|
|
||||||
int r[] = new int[wh];
|
|
||||||
int g[] = new int[wh];
|
|
||||||
int b[] = new int[wh];
|
|
||||||
int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
|
|
||||||
int vmin[] = new int[Math.max(w, h)];
|
|
||||||
|
|
||||||
int divsum = (div + 1) >> 1;
|
|
||||||
divsum *= divsum;
|
|
||||||
int dv[] = new int[256 * divsum];
|
|
||||||
for (i = 0; i < 256 * divsum; i++) {
|
|
||||||
dv[i] = (i / divsum);
|
|
||||||
}
|
|
||||||
|
|
||||||
yw = yi = 0;
|
|
||||||
|
|
||||||
int[][] stack = new int[div][3];
|
|
||||||
int stackpointer;
|
|
||||||
int stackstart;
|
|
||||||
int[] sir;
|
|
||||||
int rbs;
|
|
||||||
int r1 = radius + 1;
|
|
||||||
int routsum, goutsum, boutsum;
|
|
||||||
int rinsum, ginsum, binsum;
|
|
||||||
|
|
||||||
for (y = 0; y < h; y++) {
|
|
||||||
rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
|
|
||||||
for (i = -radius; i <= radius; i++) {
|
|
||||||
p = pix[yi + Math.min(wm, Math.max(i, 0))];
|
|
||||||
sir = stack[i + radius];
|
|
||||||
sir[0] = (p & 0xff0000) >> 16;
|
|
||||||
sir[1] = (p & 0x00ff00) >> 8;
|
|
||||||
sir[2] = (p & 0x0000ff);
|
|
||||||
rbs = r1 - Math.abs(i);
|
|
||||||
rsum += sir[0] * rbs;
|
|
||||||
gsum += sir[1] * rbs;
|
|
||||||
bsum += sir[2] * rbs;
|
|
||||||
if (i > 0) {
|
|
||||||
rinsum += sir[0];
|
|
||||||
ginsum += sir[1];
|
|
||||||
binsum += sir[2];
|
|
||||||
} else {
|
|
||||||
routsum += sir[0];
|
|
||||||
goutsum += sir[1];
|
|
||||||
boutsum += sir[2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stackpointer = radius;
|
|
||||||
|
|
||||||
for (x = 0; x < w; x++) {
|
|
||||||
|
|
||||||
r[yi] = dv[rsum];
|
|
||||||
g[yi] = dv[gsum];
|
|
||||||
b[yi] = dv[bsum];
|
|
||||||
|
|
||||||
rsum -= routsum;
|
|
||||||
gsum -= goutsum;
|
|
||||||
bsum -= boutsum;
|
|
||||||
|
|
||||||
stackstart = stackpointer - radius + div;
|
|
||||||
sir = stack[stackstart % div];
|
|
||||||
|
|
||||||
routsum -= sir[0];
|
|
||||||
goutsum -= sir[1];
|
|
||||||
boutsum -= sir[2];
|
|
||||||
|
|
||||||
if (y == 0) {
|
|
||||||
vmin[x] = Math.min(x + radius + 1, wm);
|
|
||||||
}
|
|
||||||
p = pix[yw + vmin[x]];
|
|
||||||
|
|
||||||
sir[0] = (p & 0xff0000) >> 16;
|
|
||||||
sir[1] = (p & 0x00ff00) >> 8;
|
|
||||||
sir[2] = (p & 0x0000ff);
|
|
||||||
|
|
||||||
rinsum += sir[0];
|
|
||||||
ginsum += sir[1];
|
|
||||||
binsum += sir[2];
|
|
||||||
|
|
||||||
rsum += rinsum;
|
|
||||||
gsum += ginsum;
|
|
||||||
bsum += binsum;
|
|
||||||
|
|
||||||
stackpointer = (stackpointer + 1) % div;
|
|
||||||
sir = stack[(stackpointer) % div];
|
|
||||||
|
|
||||||
routsum += sir[0];
|
|
||||||
goutsum += sir[1];
|
|
||||||
boutsum += sir[2];
|
|
||||||
|
|
||||||
rinsum -= sir[0];
|
|
||||||
ginsum -= sir[1];
|
|
||||||
binsum -= sir[2];
|
|
||||||
|
|
||||||
yi++;
|
|
||||||
}
|
|
||||||
yw += w;
|
|
||||||
}
|
|
||||||
for (x = 0; x < w; x++) {
|
|
||||||
rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
|
|
||||||
yp = -radius * w;
|
|
||||||
for (i = -radius; i <= radius; i++) {
|
|
||||||
yi = Math.max(0, yp) + x;
|
|
||||||
|
|
||||||
sir = stack[i + radius];
|
|
||||||
|
|
||||||
sir[0] = r[yi];
|
|
||||||
sir[1] = g[yi];
|
|
||||||
sir[2] = b[yi];
|
|
||||||
|
|
||||||
rbs = r1 - Math.abs(i);
|
|
||||||
|
|
||||||
rsum += r[yi] * rbs;
|
|
||||||
gsum += g[yi] * rbs;
|
|
||||||
bsum += b[yi] * rbs;
|
|
||||||
|
|
||||||
if (i > 0) {
|
|
||||||
rinsum += sir[0];
|
|
||||||
ginsum += sir[1];
|
|
||||||
binsum += sir[2];
|
|
||||||
} else {
|
|
||||||
routsum += sir[0];
|
|
||||||
goutsum += sir[1];
|
|
||||||
boutsum += sir[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < hm) {
|
|
||||||
yp += w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
yi = x;
|
|
||||||
stackpointer = radius;
|
|
||||||
for (y = 0; y < h; y++) {
|
|
||||||
// Preserve alpha channel: ( 0xff000000 & pix[yi] )
|
|
||||||
pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16)
|
|
||||||
| (dv[gsum] << 8) | dv[bsum];
|
|
||||||
|
|
||||||
rsum -= routsum;
|
|
||||||
gsum -= goutsum;
|
|
||||||
bsum -= boutsum;
|
|
||||||
|
|
||||||
stackstart = stackpointer - radius + div;
|
|
||||||
sir = stack[stackstart % div];
|
|
||||||
|
|
||||||
routsum -= sir[0];
|
|
||||||
goutsum -= sir[1];
|
|
||||||
boutsum -= sir[2];
|
|
||||||
|
|
||||||
if (x == 0) {
|
|
||||||
vmin[y] = Math.min(y + r1, hm) * w;
|
|
||||||
}
|
|
||||||
p = x + vmin[y];
|
|
||||||
|
|
||||||
sir[0] = r[p];
|
|
||||||
sir[1] = g[p];
|
|
||||||
sir[2] = b[p];
|
|
||||||
|
|
||||||
rinsum += sir[0];
|
|
||||||
ginsum += sir[1];
|
|
||||||
binsum += sir[2];
|
|
||||||
|
|
||||||
rsum += rinsum;
|
|
||||||
gsum += ginsum;
|
|
||||||
bsum += binsum;
|
|
||||||
|
|
||||||
stackpointer = (stackpointer + 1) % div;
|
|
||||||
sir = stack[stackpointer];
|
|
||||||
|
|
||||||
routsum += sir[0];
|
|
||||||
goutsum += sir[1];
|
|
||||||
boutsum += sir[2];
|
|
||||||
|
|
||||||
rinsum -= sir[0];
|
|
||||||
ginsum -= sir[1];
|
|
||||||
binsum -= sir[2];
|
|
||||||
|
|
||||||
yi += w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bitmap.setPixels(pix, 0, w, 0, 0, w, h);
|
|
||||||
|
|
||||||
return (bitmap);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,112 +0,0 @@
|
|||||||
package ${domain}.base.util;
|
|
||||||
|
|
||||||
import java.io.BufferedOutputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件及文件夹工具类
|
|
||||||
*/
|
|
||||||
public class FileUtil {
|
|
||||||
|
|
||||||
public static byte[] File2byte(File file) {
|
|
||||||
byte[] buffer = null;
|
|
||||||
try {
|
|
||||||
FileInputStream fis = new FileInputStream(file);
|
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
|
||||||
byte[] b = new byte[1024];
|
|
||||||
int n;
|
|
||||||
while ((n = fis.read(b)) != -1) {
|
|
||||||
bos.write(b, 0, n);
|
|
||||||
}
|
|
||||||
fis.close();
|
|
||||||
bos.close();
|
|
||||||
buffer = bos.toByteArray();
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void byte2File(byte[] buf, File file) {
|
|
||||||
BufferedOutputStream bos = null;
|
|
||||||
FileOutputStream fos = null;
|
|
||||||
try {
|
|
||||||
file.getParentFile().mkdirs();
|
|
||||||
file.createNewFile();
|
|
||||||
fos = new FileOutputStream(file);
|
|
||||||
bos = new BufferedOutputStream(fos);
|
|
||||||
bos.write(buf);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
if (bos != null) {
|
|
||||||
try {
|
|
||||||
bos.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fos != null) {
|
|
||||||
try {
|
|
||||||
fos.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long sizeOf(File file) {
|
|
||||||
|
|
||||||
if (!file.exists()) {
|
|
||||||
String message = file + " does not exist";
|
|
||||||
throw new IllegalArgumentException(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.isDirectory()) {
|
|
||||||
return sizeOfDirectory(file);
|
|
||||||
} else {
|
|
||||||
return file.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long sizeOfDirectory(File directory) {
|
|
||||||
checkDirectory(directory);
|
|
||||||
|
|
||||||
final File[] files = directory.listFiles();
|
|
||||||
if (files == null) { // null if security restricted
|
|
||||||
return 0L;
|
|
||||||
}
|
|
||||||
long size = 0;
|
|
||||||
|
|
||||||
for (final File file : files) {
|
|
||||||
|
|
||||||
size += sizeOf(file);
|
|
||||||
if (size < 0) {
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void checkDirectory(File directory) {
|
|
||||||
if (!directory.exists()) {
|
|
||||||
throw new IllegalArgumentException(directory + " does not exist");
|
|
||||||
}
|
|
||||||
if (!directory.isDirectory()) {
|
|
||||||
throw new IllegalArgumentException(directory
|
|
||||||
+ " is not a directory");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,156 +0,0 @@
|
|||||||
package ${domain}.base.util;
|
|
||||||
|
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.KeyFactory;
|
|
||||||
import java.security.KeyPair;
|
|
||||||
import java.security.KeyPairGenerator;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.PrivateKey;
|
|
||||||
import java.security.PublicKey;
|
|
||||||
import java.security.spec.InvalidKeySpecException;
|
|
||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
|
||||||
import java.security.spec.X509EncodedKeySpec;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.crypto.BadPaddingException;
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.crypto.IllegalBlockSizeException;
|
|
||||||
import javax.crypto.NoSuchPaddingException;
|
|
||||||
|
|
||||||
public class RSAUtil {
|
|
||||||
|
|
||||||
public static final String PUBLIC_KEY = "RSAPublicKey";
|
|
||||||
public static final String PRIVATE_KEY = "RSAPrivateKey";
|
|
||||||
private static final String KEY_ALGORITHM = "RSA";
|
|
||||||
private static int KEY_SIZE = 512;
|
|
||||||
|
|
||||||
private static PublicKey MOBILE_PUBLIC_KEY = null;
|
|
||||||
private static PrivateKey MOBILE_PRIVATE_KEY = null;
|
|
||||||
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
|
|
||||||
// 初始化公钥
|
|
||||||
X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64Util.decode("MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJChCOcEFsKdG9Ibwi23b3UreERc1D5+GhEjvByxmFZ2Q+mqco8V9CDsIZUfpb6pLQA8x32G17YHEyj34etpmBUCAwEAAQ=="));
|
|
||||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
|
||||||
MOBILE_PUBLIC_KEY = keyFactory.generatePublic(spec);
|
|
||||||
|
|
||||||
// 初始化私钥
|
|
||||||
PKCS8EncodedKeySpec specPri = new PKCS8EncodedKeySpec(Base64Util.decode("MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAkKEI5wQWwp0b0hvCLbdvdSt4RFzUPn4aESO8HLGYVnZD6apyjxX0IOwhlR+lvqktADzHfYbXtgcTKPfh62mYFQIDAQABAkBhuZ4lUxr592TEDOOhNnCGkI/cSYlUjKqaaDYEgW/5Azom4VLya/JXFQVMVeMKQoiwH8aXn8od6+l5O7m+mYVlAiEA5yPFXhM4GXY0Oxe7l0uHKRlLkHIz44kvnd4Fj2xNfK8CIQCgL0SljzvL+iilHb+5PKk1wmpLPaDKajZqInSOhkhQewIgFpGAkOnxfVL0UJzFnUUrolCs9yKffGUFuDVYd6OMgVMCICh2CBbxqR8K3z1l2EnH4s3rf8HlnTnDvl7suRhPHvEFAiAxvjwQl6yHoDH6IGB6jeE9+hYK/xvuGT2TAyztZhfVRA=="));
|
|
||||||
|
|
||||||
keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
|
||||||
MOBILE_PRIVATE_KEY = keyFactory.generatePrivate(specPri);
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (InvalidKeySpecException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Map<String, Object> generateKeys() throws Exception {
|
|
||||||
KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
|
|
||||||
generator.initialize(KEY_SIZE);
|
|
||||||
KeyPair keyPair = generator.generateKeyPair();
|
|
||||||
PublicKey publicKey = keyPair.getPublic();
|
|
||||||
PrivateKey privateKey = keyPair.getPrivate();
|
|
||||||
|
|
||||||
Map<String, Object> keys = new HashMap<String, Object>();
|
|
||||||
keys.put(PUBLIC_KEY, publicKey);
|
|
||||||
keys.put(PRIVATE_KEY, privateKey);
|
|
||||||
return keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PublicKey getPublicKey(byte[] content) throws Exception {
|
|
||||||
PublicKey publicKey = null;
|
|
||||||
try {
|
|
||||||
X509EncodedKeySpec spec = new X509EncodedKeySpec(content);
|
|
||||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
|
||||||
publicKey = keyFactory.generatePublic(spec);
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw e;
|
|
||||||
} catch (InvalidKeySpecException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
return publicKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PrivateKey getPrivateKey(byte[] content) throws Exception {
|
|
||||||
PrivateKey privateKey = null;
|
|
||||||
try {
|
|
||||||
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(content);
|
|
||||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
|
||||||
privateKey = keyFactory.generatePrivate(spec);
|
|
||||||
} catch (InvalidKeySpecException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw e;
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
return privateKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] encryptWithPublicKey(byte[] data, PublicKey key) throws Exception {
|
|
||||||
Cipher cipher;
|
|
||||||
try {
|
|
||||||
cipher = Cipher.getInstance(KEY_ALGORITHM);
|
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, key);
|
|
||||||
return cipher.doFinal(data);
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw e;
|
|
||||||
} catch (NoSuchPaddingException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw e;
|
|
||||||
} catch (InvalidKeyException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw e;
|
|
||||||
} catch (IllegalBlockSizeException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw e;
|
|
||||||
} catch (BadPaddingException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] decryptWithPrivateKey(byte[] data, PrivateKey key) throws Exception {
|
|
||||||
try {
|
|
||||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
|
||||||
cipher.init(Cipher.DECRYPT_MODE, key);
|
|
||||||
|
|
||||||
return cipher.doFinal(data);
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw e;
|
|
||||||
} catch (NoSuchPaddingException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw e;
|
|
||||||
} catch (InvalidKeyException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw e;
|
|
||||||
} catch (IllegalBlockSizeException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw e;
|
|
||||||
} catch (BadPaddingException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] encryptMobile(byte[] data) throws Exception {
|
|
||||||
return encryptWithPublicKey(data, MOBILE_PUBLIC_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] decryptMobile(byte[] data) throws Exception {
|
|
||||||
return decryptWithPrivateKey(data, MOBILE_PRIVATE_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,166 +0,0 @@
|
|||||||
package ${domain}.base.util;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
import ${domain}.WBUIApplication;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Administrator on 2018/3/11 0011.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class SPUtil {
|
|
||||||
|
|
||||||
public static final String FILE_DEFAULT = "default";
|
|
||||||
|
|
||||||
public static int getInt(String key) {
|
|
||||||
SharedPreferences sharedPreferences = getSharePreferences(FILE_DEFAULT);
|
|
||||||
return sharedPreferences.getInt(key, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean getBoolean(String key) {
|
|
||||||
SharedPreferences sharedPreferences = getSharePreferences(FILE_DEFAULT);
|
|
||||||
return sharedPreferences.getBoolean(key, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float getFloat(String key) {
|
|
||||||
SharedPreferences sharedPreferences = getSharePreferences(FILE_DEFAULT);
|
|
||||||
return sharedPreferences.getFloat(key, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean getBoolean(String key, boolean defValue) {
|
|
||||||
SharedPreferences sharedPreferences = getSharePreferences(FILE_DEFAULT);
|
|
||||||
return sharedPreferences.getBoolean(key, defValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getString(String key) {
|
|
||||||
SharedPreferences sharedPreferences = getSharePreferences(FILE_DEFAULT);
|
|
||||||
return sharedPreferences.getString(key, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getStringWithDefault(String key, String defStr) {
|
|
||||||
SharedPreferences sharedPreferences = getSharePreferences(FILE_DEFAULT);
|
|
||||||
return sharedPreferences.getString(key, defStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void putInt(String key, int value) {
|
|
||||||
SharedPreferences.Editor editor = getEditor(getSharePreferences(FILE_DEFAULT));
|
|
||||||
editor.putInt(key, value);
|
|
||||||
editor.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void putBoolean(String key, boolean value) {
|
|
||||||
SharedPreferences.Editor editor = getEditor(getSharePreferences(FILE_DEFAULT));
|
|
||||||
editor.putBoolean(key, value);
|
|
||||||
editor.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void putString(String key, String value) {
|
|
||||||
SharedPreferences.Editor editor = getEditor(getSharePreferences(FILE_DEFAULT));
|
|
||||||
editor.putString(key, value);
|
|
||||||
editor.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void putFloat(String key, float value) {
|
|
||||||
SharedPreferences.Editor editor = getEditor(getSharePreferences(FILE_DEFAULT));
|
|
||||||
|
|
||||||
editor.putFloat(key, value);
|
|
||||||
editor.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void putLong(String key, long value) {
|
|
||||||
SharedPreferences.Editor editor = getEditor(getSharePreferences(FILE_DEFAULT));
|
|
||||||
|
|
||||||
editor.putLong(key, value);
|
|
||||||
editor.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static long getLong(String key) {
|
|
||||||
SharedPreferences sharedPreferences = getSharePreferences(FILE_DEFAULT);
|
|
||||||
return sharedPreferences.getLong(key, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getInt(String key, int defValue) {
|
|
||||||
SharedPreferences sharedPreferences = getSharePreferences(FILE_DEFAULT);
|
|
||||||
return sharedPreferences.getInt(key, defValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getInt(String key, String fileName) {
|
|
||||||
|
|
||||||
SharedPreferences sharedPreferences = getSharePreferences(getFileName(fileName));
|
|
||||||
return sharedPreferences.getInt(key, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean getBoolean(String key, String fileName) {
|
|
||||||
SharedPreferences sharedPreferences = getSharePreferences(getFileName(fileName));
|
|
||||||
return sharedPreferences.getBoolean(key, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getString(String key, String fileName) {
|
|
||||||
SharedPreferences sharedPreferences = getSharePreferences(getFileName(fileName));
|
|
||||||
return sharedPreferences.getString(key, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float getFloat(String key, String fileName) {
|
|
||||||
SharedPreferences sharedPreferences = getSharePreferences(getFileName(fileName));
|
|
||||||
return sharedPreferences.getFloat(key, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long getLong(String key, String fileName) {
|
|
||||||
SharedPreferences sharedPreferences = getSharePreferences(getFileName(fileName));
|
|
||||||
return sharedPreferences.getLong(key, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void putInt(String key, int value, String fileName) {
|
|
||||||
SharedPreferences.Editor editor = getEditor(getSharePreferences(getFileName(fileName)));
|
|
||||||
editor.putInt(key, value);
|
|
||||||
editor.commit();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void putBoolean(String key, boolean value, String fileName) {
|
|
||||||
SharedPreferences.Editor editor = getEditor(getSharePreferences(getFileName(fileName)));
|
|
||||||
|
|
||||||
editor.putBoolean(key, value);
|
|
||||||
editor.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void putString(String key, String value, String fileName) {
|
|
||||||
SharedPreferences.Editor editor = getEditor(getSharePreferences(getFileName(fileName)));
|
|
||||||
|
|
||||||
editor.putString(key, value);
|
|
||||||
editor.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void putFloat(String key, float value, String fileName) {
|
|
||||||
SharedPreferences.Editor editor = getEditor(getSharePreferences(getFileName(fileName)));
|
|
||||||
|
|
||||||
editor.putFloat(key, value);
|
|
||||||
editor.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void putLong(String key, long value, String fileName) {
|
|
||||||
SharedPreferences.Editor editor = getEditor(getSharePreferences(getFileName(fileName)));
|
|
||||||
|
|
||||||
editor.putLong(key, value);
|
|
||||||
editor.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static SharedPreferences getSharePreferences(String fileName) {
|
|
||||||
return WBUIApplication.getInstance().getSharedPreferences(fileName, Context.MODE_PRIVATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static SharedPreferences.Editor getEditor(SharedPreferences sharedPreferences) {
|
|
||||||
return sharedPreferences.edit();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getFileName(String fileName) {
|
|
||||||
if (!TextUtils.isEmpty(fileName)) {
|
|
||||||
return fileName;
|
|
||||||
} else {
|
|
||||||
return FILE_DEFAULT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
package ${domain}.base.util;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.TypedValue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 尺寸单位转换
|
|
||||||
*/
|
|
||||||
public class SizeUtil {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* dp转px
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param dpVal
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static int dp2px(Context context, float dpVal) {
|
|
||||||
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
|
|
||||||
dpVal, context.getResources().getDisplayMetrics());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* sp转px
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param spVal
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static int sp2px(Context context, float spVal) {
|
|
||||||
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
|
|
||||||
spVal, context.getResources().getDisplayMetrics());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* px转dp
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param pxVal
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static float px2dp(Context context, float pxVal) {
|
|
||||||
final float scale = context.getResources().getDisplayMetrics().density;
|
|
||||||
return (pxVal / scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* px转sp
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param pxVal
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static float px2sp(Context context, float pxVal) {
|
|
||||||
return (pxVal / context.getResources().getDisplayMetrics().scaledDensity);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package ${domain}.base.util;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
|
|
||||||
public class StreamUtil {
|
|
||||||
|
|
||||||
public static InputStream string2Stream(String str) {
|
|
||||||
return new ByteArrayInputStream(str.getBytes());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String stream2String(InputStream is) {
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
BufferedReader br = new BufferedReader(new InputStreamReader(is));
|
|
||||||
String line;
|
|
||||||
try {
|
|
||||||
while ((line = br.readLine()) != null) {
|
|
||||||
sb.append(line);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
String str = sb.toString();
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package ${domain}.base.util;
|
|
||||||
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import ${domain}.WBUIApplication;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 消息发生器
|
|
||||||
*/
|
|
||||||
public class Toaster {
|
|
||||||
/**
|
|
||||||
* 展示Toast消息。
|
|
||||||
*
|
|
||||||
* @param message 消息内容
|
|
||||||
*/
|
|
||||||
public static void showToast(String message) {
|
|
||||||
WBUIApplication.getInstance().showToast(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 引起注意或聚焦的消息提示
|
|
||||||
*
|
|
||||||
* @param message
|
|
||||||
* @param view
|
|
||||||
*/
|
|
||||||
public static void showError(String message, View view) {
|
|
||||||
showToast(message);
|
|
||||||
if (view != null) {
|
|
||||||
view.requestFocus();
|
|
||||||
AnimationUtil.shake(view, 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,154 +0,0 @@
|
|||||||
package ${domain}.base.util;
|
|
||||||
|
|
||||||
import android.content.ContentUris;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Environment;
|
|
||||||
import android.provider.DocumentsContract;
|
|
||||||
import android.provider.MediaStore;
|
|
||||||
|
|
||||||
public class UriUtil {
|
|
||||||
/**
|
|
||||||
* Get a file path from a Uri. This will get the the path for Storage Access
|
|
||||||
* Framework Documents, as well as the _data field for the MediaStore and
|
|
||||||
* other file-based ContentProviders.
|
|
||||||
*
|
|
||||||
* @param context The context.
|
|
||||||
* @param uri The Uri to query.
|
|
||||||
* @author paulburke
|
|
||||||
*/
|
|
||||||
public static String getPath(final Context context, final Uri uri) {
|
|
||||||
|
|
||||||
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
|
|
||||||
|
|
||||||
// DocumentProvider
|
|
||||||
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
|
|
||||||
// ExternalStorageProvider
|
|
||||||
if (isExternalStorageDocument(uri)) {
|
|
||||||
final String docId = DocumentsContract.getDocumentId(uri);
|
|
||||||
final String[] split = docId.split(":");
|
|
||||||
final String type = split[0];
|
|
||||||
|
|
||||||
if ("primary".equalsIgnoreCase(type)) {
|
|
||||||
return Environment.getExternalStorageDirectory() + "/" + split[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO handle non-primary volumes
|
|
||||||
}
|
|
||||||
// DownloadsProvider
|
|
||||||
else if (isDownloadsDocument(uri)) {
|
|
||||||
|
|
||||||
final String id = DocumentsContract.getDocumentId(uri);
|
|
||||||
final Uri contentUri = ContentUris.withAppendedId(
|
|
||||||
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
|
|
||||||
|
|
||||||
return getDataColumn(context, contentUri, null, null);
|
|
||||||
}
|
|
||||||
// MediaProvider
|
|
||||||
else if (isMediaDocument(uri)) {
|
|
||||||
final String docId = DocumentsContract.getDocumentId(uri);
|
|
||||||
final String[] split = docId.split(":");
|
|
||||||
final String type = split[0];
|
|
||||||
|
|
||||||
Uri contentUri = null;
|
|
||||||
if ("image".equals(type)) {
|
|
||||||
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
|
||||||
} else if ("video".equals(type)) {
|
|
||||||
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
|
||||||
} else if ("audio".equals(type)) {
|
|
||||||
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
|
||||||
}
|
|
||||||
|
|
||||||
final String selection = "_id=?";
|
|
||||||
final String[] selectionArgs = new String[]{
|
|
||||||
split[1]
|
|
||||||
};
|
|
||||||
|
|
||||||
return getDataColumn(context, contentUri, selection, selectionArgs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// MediaStore (and general)
|
|
||||||
else if ("content".equalsIgnoreCase(uri.getScheme())) {
|
|
||||||
|
|
||||||
// Return the remote address
|
|
||||||
if (isGooglePhotosUri(uri))
|
|
||||||
return uri.getLastPathSegment();
|
|
||||||
|
|
||||||
return getDataColumn(context, uri, null, null);
|
|
||||||
}
|
|
||||||
// File
|
|
||||||
else if ("file".equalsIgnoreCase(uri.getScheme())) {
|
|
||||||
return uri.getPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* *
|
|
||||||
* Get the value of the data column for this Uri. This is useful for
|
|
||||||
* MediaStore Uris, and other file-based ContentProviders.
|
|
||||||
*
|
|
||||||
* @param context The context.
|
|
||||||
* @param uri The Uri to query.
|
|
||||||
* @param selection (Optional) Filter used in the query.
|
|
||||||
* @param selectionArgs (Optional) Selection arguments used in the query.
|
|
||||||
* @return The value of the _data column, which is typically a file path.
|
|
||||||
*/
|
|
||||||
public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
|
|
||||||
|
|
||||||
Cursor cursor = null;
|
|
||||||
final String column = "_data";
|
|
||||||
final String[] projection = {
|
|
||||||
column
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
|
|
||||||
null);
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
|
||||||
final int index = cursor.getColumnIndexOrThrow(column);
|
|
||||||
return cursor.getString(index);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (cursor != null)
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param uri The Uri to check.
|
|
||||||
* @return Whether the Uri authority is ExternalStorageProvider.
|
|
||||||
*/
|
|
||||||
public static boolean isExternalStorageDocument(Uri uri) {
|
|
||||||
return "com.android.externalstorage.documents".equals(uri.getAuthority());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param uri The Uri to check.
|
|
||||||
* @return Whether the Uri authority is DownloadsProvider.
|
|
||||||
*/
|
|
||||||
public static boolean isDownloadsDocument(Uri uri) {
|
|
||||||
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param uri The Uri to check.
|
|
||||||
* @return Whether the Uri authority is MediaProvider.
|
|
||||||
*/
|
|
||||||
public static boolean isMediaDocument(Uri uri) {
|
|
||||||
return "com.android.providers.media.documents".equals(uri.getAuthority());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param uri The Uri to check.
|
|
||||||
* @return Whether the Uri authority is Google Photos.
|
|
||||||
*/
|
|
||||||
public static boolean isGooglePhotosUri(Uri uri) {
|
|
||||||
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
package ${domain}.fragment;
|
|
||||||
|
|
||||||
import com.qmuiteam.qmui.widget.QMUITopBarLayout;
|
|
||||||
import butterknife.BindView;
|
|
||||||
import ${domain}.base.BaseSPAFragment;
|
|
||||||
import ${package}.R;
|
|
||||||
|
|
||||||
public class MainFragment extends BaseSPAFragment {
|
|
||||||
|
|
||||||
@BindView(R.id.topbar)
|
|
||||||
QMUITopBarLayout topbar;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getFragmnetLayout() {
|
|
||||||
return R.layout.fragment_main;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onViewInit() {
|
|
||||||
topbar.setTitle("Hello world");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<solid android:color="@color/colorBackground"></solid>
|
|
||||||
</shape>
|
|
@ -1,60 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent" >
|
|
||||||
|
|
||||||
<com.journeyapps.barcodescanner.DecoratedBarcodeView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:id="@+id/dbv_custom">
|
|
||||||
</com.journeyapps.barcodescanner.DecoratedBarcodeView>
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="#202020"
|
|
||||||
android:id="@+id/action_bar_id"
|
|
||||||
android:layout_weight="0">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:gravity="center"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:id="@+id/back_btn_id">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/main_person_id"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:paddingLeft="12dp"
|
|
||||||
android:paddingTop="14dp"
|
|
||||||
android:paddingBottom="14dp"
|
|
||||||
android:paddingRight="4dp"/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textColor="@android:color/white"
|
|
||||||
android:text="返回"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_centerInParent="true"
|
|
||||||
android:id="@+id/main_title_id"
|
|
||||||
android:text="扫描二维码"
|
|
||||||
android:textColor="@android:color/white"
|
|
||||||
android:textSize="18sp"/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
@ -1,34 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<com.qmuiteam.qmui.widget.QMUIWindowInsetLayout 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:background="@drawable/background">
|
|
||||||
|
|
||||||
<com.qmuiteam.qmui.widget.QMUITopBarLayout
|
|
||||||
android:id="@+id/topbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:fitsSystemWindows="true"
|
|
||||||
app:qmui_topbar_separator_color="@color/colorGray_10"
|
|
||||||
app:qmui_topbar_separator_height="0dp" />
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_marginTop="?attr/qmui_topbar_height"
|
|
||||||
android:fitsSystemWindows="true">
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:gravity="center"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:text="Hello World"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</FrameLayout>
|
|
||||||
</com.qmuiteam.qmui.widget.QMUIWindowInsetLayout>
|
|
@ -1,18 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<com.qmuiteam.qmui.widget.QMUIWindowInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:background="@color/colorPrimary"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:fitsSystemWindows="true">
|
|
||||||
|
|
||||||
<WebView
|
|
||||||
android:id="@+id/webView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"/>
|
|
||||||
</LinearLayout>
|
|
||||||
</com.qmuiteam.qmui.widget.QMUIWindowInsetLayout>
|
|
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 6.3 KiB |