集成完直播后提交代码
This commit is contained in:
1
basicLib/.gitignore
vendored
Normal file
1
basicLib/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
59
basicLib/build.gradle
Normal file
59
basicLib/build.gradle
Normal file
@@ -0,0 +1,59 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdk 31
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 23
|
||||
targetSdk 31
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
//启用DataBinding
|
||||
buildFeatures{
|
||||
dataBinding = true
|
||||
// for view binding :
|
||||
// viewBinding = true
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
|
||||
api 'android.arch.lifecycle:extensions:1.1.1'
|
||||
api 'com.squareup.retrofit2:retrofit:2.5.0'
|
||||
api 'com.squareup.retrofit2:converter-scalars:2.3.0'
|
||||
api 'com.squareup.retrofit2:converter-gson:2.4.0'
|
||||
api 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
|
||||
api 'io.reactivex.rxjava2:rxjava:2.1.16'
|
||||
api 'io.reactivex.rxjava2:rxandroid:2.0.2'
|
||||
|
||||
api 'androidx.recyclerview:recyclerview:1.1.0'
|
||||
api 'com.github.bumptech.glide:glide:4.11.0'
|
||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
|
||||
// api 'com.android.support:design:28.0.0'
|
||||
api 'androidx.appcompat:appcompat:1.1.0'
|
||||
api 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
api 'androidx.viewpager2:viewpager2:1.0.0'
|
||||
api 'com.google.android.material:material:1.1.0'
|
||||
testImplementation "junit:junit:4.13.1"
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||
api 'io.github.hariprasanths:bounceview-android:0.2.0'
|
||||
api 'com.blankj:utilcodex:1.31.0'
|
||||
|
||||
}
|
||||
22
basicLib/proguard-rules.pro
vendored
Normal file
22
basicLib/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
# 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
|
||||
|
||||
2
basicLib/src/main/AndroidManifest.xml
Normal file
2
basicLib/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.azhon.basic" />
|
||||
@@ -0,0 +1,132 @@
|
||||
package com.azhon.basic.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.databinding.DataBindingUtil;
|
||||
import androidx.databinding.ViewDataBinding;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 项目名: TODO-MVVM
|
||||
* 包名 com.azhon.basic.adapter
|
||||
* 文件名: BaseDBRVAdapter
|
||||
* 创建时间: 2019-03-27 on 16:22
|
||||
* 描述: TODO 结合dataBinding的RecyclerView Adapter
|
||||
*
|
||||
* @author
|
||||
*/
|
||||
|
||||
public abstract class BaseDBRVAdapter<Data, DB extends ViewDataBinding> extends RecyclerView.Adapter<BaseDBRVHolder> {
|
||||
|
||||
private List<Data> data;
|
||||
private int itemId;
|
||||
protected Context context;
|
||||
protected int variableId;
|
||||
protected OnItemClickListener<Data> listener;
|
||||
|
||||
|
||||
public BaseDBRVAdapter(@LayoutRes int itemId, int variableId) {
|
||||
this.itemId = itemId;
|
||||
this.variableId = variableId;
|
||||
data = new ArrayList<>();
|
||||
}
|
||||
|
||||
public BaseDBRVAdapter(List<Data> data, @LayoutRes int itemId, int variableId) {
|
||||
this.data = data == null ? new ArrayList<Data>() : data;
|
||||
this.itemId = itemId;
|
||||
this.variableId = variableId;
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public BaseDBRVHolder onCreateViewHolder(@NonNull ViewGroup parent, int position) {
|
||||
this.context = parent.getContext();
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
DB binding = DataBindingUtil.inflate(inflater, itemId, parent, false);
|
||||
return new BaseDBRVHolder(binding.getRoot());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull BaseDBRVHolder holder, final int position) {
|
||||
DB binding = DataBindingUtil.getBinding(holder.itemView);
|
||||
final Data itemData = data.get(position);
|
||||
binding.setVariable(variableId, itemData);
|
||||
onBindViewHolder(itemData, binding, position);
|
||||
//迫使数据立即绑定
|
||||
binding.executePendingBindings();
|
||||
//设置点击事件
|
||||
if (listener != null) {
|
||||
holder.itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
listener.onItemClick(itemData, position);
|
||||
}
|
||||
});
|
||||
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
return listener.onItemLongClick(itemData, position);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return data.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定数据
|
||||
*/
|
||||
protected void onBindViewHolder(Data data, DB binding, int position) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置新数据
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
public void setNewData(List<Data> data) {
|
||||
this.data.clear();
|
||||
this.data.addAll(data);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加数据
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
public void addData(Data data) {
|
||||
this.data.add(data);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加数据
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
public void addData(List<Data> data) {
|
||||
this.data.addAll(data);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Item 长按、点击事件
|
||||
*/
|
||||
public void setOnItemListener(OnItemClickListener<Data> listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.azhon.basic.adapter;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* 项目名: TODO-MVVM
|
||||
* 包名 com.azhon.basic.adapter
|
||||
* 文件名: BaseDBRVHolder
|
||||
* 创建时间: 2019-03-27 on 22:12
|
||||
* 描述: TODO 结合dataBinding的RecyclerView Holder
|
||||
*
|
||||
* @author
|
||||
*/
|
||||
|
||||
public final class BaseDBRVHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
public BaseDBRVHolder(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.azhon.basic.adapter;
|
||||
|
||||
/**
|
||||
* 项目名: TODO-MVVM
|
||||
* 包名 com.azhon.basic.adapter
|
||||
* 文件名: OnItemClickListener
|
||||
* 创建时间: 2019-03-29 on 13:53
|
||||
* 描述: TODO RecyclerView Item 长按、点击事件
|
||||
*
|
||||
* @author
|
||||
*/
|
||||
|
||||
public interface OnItemClickListener<Data> {
|
||||
|
||||
/**
|
||||
* Item 点击事件
|
||||
*
|
||||
* @param data item的数据
|
||||
* @param position item的下标
|
||||
*/
|
||||
void onItemClick(Data data, int position);
|
||||
|
||||
/**
|
||||
* Item 长按事件
|
||||
*
|
||||
* @param data item的数据
|
||||
* @param position item的下标
|
||||
*/
|
||||
boolean onItemLongClick(Data data, int position);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.azhon.basic.base;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Build;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.databinding.ViewDataBinding;
|
||||
import androidx.lifecycle.Observer;
|
||||
|
||||
import com.azhon.basic.bean.DialogBean;
|
||||
import com.azhon.basic.lifecycle.BaseViewModel;
|
||||
|
||||
|
||||
/**
|
||||
* 项目名: TODO-MVVM
|
||||
* 包名 com.azhon.basic.base
|
||||
* 文件名: BaseActivity
|
||||
* 创建时间: 2019-03-27 on 10:46
|
||||
* 描述: TODO ViewModel、ViewDataBinding都需要的基类
|
||||
*
|
||||
* @author
|
||||
*/
|
||||
|
||||
public abstract class BaseActivity<VM extends BaseViewModel, DB extends ViewDataBinding>
|
||||
extends BaseNoModelActivity<DB> {
|
||||
|
||||
protected VM viewModel;
|
||||
|
||||
@Override
|
||||
protected DB initDataBinding(int layoutId) {
|
||||
DB db = super.initDataBinding(layoutId);
|
||||
/**
|
||||
* 将这两个初始化函数插在{@link BaseActivity#initDataBinding}
|
||||
*/
|
||||
viewModel = initViewModel();
|
||||
initObserve();
|
||||
return db;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 初始化ViewModel
|
||||
*/
|
||||
protected abstract VM initViewModel();
|
||||
|
||||
/**
|
||||
* 监听当前ViewModel中 showDialog和error的值
|
||||
*/
|
||||
private void initObserve() {
|
||||
if (viewModel == null) return;
|
||||
viewModel.getShowDialog(this, bean -> {
|
||||
if (bean.isShow()) {
|
||||
showDialog(bean.getMsg());
|
||||
} else {
|
||||
dismissDialog();
|
||||
}
|
||||
});
|
||||
viewModel.getError(this, obj -> showError(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* ViewModel层发生了错误
|
||||
*/
|
||||
protected abstract void showError(Object obj);
|
||||
|
||||
|
||||
}
|
||||
105
basicLib/src/main/java/com/azhon/basic/base/BaseFragment.java
Normal file
105
basicLib/src/main/java/com/azhon/basic/base/BaseFragment.java
Normal file
@@ -0,0 +1,105 @@
|
||||
package com.azhon.basic.base;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.os.Looper;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.databinding.ViewDataBinding;
|
||||
import androidx.lifecycle.Observer;
|
||||
|
||||
import com.azhon.basic.bean.DialogBean;
|
||||
import com.azhon.basic.lifecycle.BaseViewModel;
|
||||
|
||||
|
||||
/**
|
||||
* 项目名: TODO-MVVM
|
||||
* 包名 com.azhon.basic.base
|
||||
* 文件名: BaseFragment
|
||||
* 创建时间: 2019-03-28 on 17:35
|
||||
* 描述: TODO ViewModel、ViewDataBinding都需要的基类
|
||||
*
|
||||
* @author
|
||||
*/
|
||||
|
||||
public abstract class BaseFragment<VM extends BaseViewModel, DB extends ViewDataBinding>
|
||||
extends BaseNoModelFragment<DB> {
|
||||
|
||||
protected VM viewModel;
|
||||
private static Toast toast;
|
||||
|
||||
@Override
|
||||
protected DB initDataBinding(LayoutInflater inflater, int layoutId, ViewGroup container) {
|
||||
DB db = super.initDataBinding(inflater, layoutId, container);
|
||||
/**
|
||||
* 将这两个初始化函数插在{@link BaseFragment#initDataBinding}
|
||||
*/
|
||||
viewModel = initViewModel();
|
||||
initObserve();
|
||||
return db;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化ViewModel
|
||||
*/
|
||||
protected abstract VM initViewModel();
|
||||
|
||||
/**
|
||||
* 监听当前ViewModel中 showDialog和error的值
|
||||
*/
|
||||
private void initObserve() {
|
||||
if (viewModel == null) return;
|
||||
viewModel.getShowDialog(this, new Observer<DialogBean>() {
|
||||
@Override
|
||||
public void onChanged(DialogBean bean) {
|
||||
if (bean.isShow()) {
|
||||
showDialog(bean.getMsg());
|
||||
} else {
|
||||
dismissDialog();
|
||||
}
|
||||
}
|
||||
});
|
||||
viewModel.getError(this, new Observer<Object>() {
|
||||
@Override
|
||||
public void onChanged(Object obj) {
|
||||
showError(obj);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* ViewModel层发生了错误
|
||||
*/
|
||||
protected abstract void showError(Object obj);
|
||||
|
||||
|
||||
// /**
|
||||
// * 显示提示 toast
|
||||
// *
|
||||
// * @param msg 提示信息
|
||||
// */
|
||||
// @SuppressLint("ShowToast")
|
||||
// public void showToast(String msg) {
|
||||
// try {
|
||||
// if (null == toast) {
|
||||
// toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
|
||||
// } else {
|
||||
// toast.setText(msg);
|
||||
// }
|
||||
// getActivity().runOnUiThread(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// toast.show();
|
||||
// }
|
||||
// });
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// //解决在子线程中调用Toast的异常情况处理
|
||||
// Looper.prepare();
|
||||
// Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
|
||||
// Looper.loop();
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.azhon.basic.base;
|
||||
|
||||
import androidx.databinding.ViewDataBinding;
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
|
||||
import com.azhon.basic.lifecycle.BaseViewModel;
|
||||
|
||||
/**
|
||||
* 项目名: TODO-MVVM
|
||||
* 包名 com.azhon.basic.base
|
||||
* 文件名: BaseLazyFragment
|
||||
* 创建时间: 2019-03-28 on 18:01
|
||||
* 描述: TODO 懒加载Fragment基类,适用于一个页面多个Tab页面
|
||||
*
|
||||
* @author
|
||||
*/
|
||||
|
||||
public abstract class BaseLazyFragment<VM extends BaseViewModel, DB extends ViewDataBinding>
|
||||
extends BaseFragment<VM, DB> implements LifecycleObserver {
|
||||
|
||||
public boolean visibleToUser;
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (!visibleToUser) {
|
||||
visibleToUser = true;
|
||||
lazyLoad();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 懒加载,只有在Fragment第一次创建且第一次对用户可见
|
||||
*/
|
||||
protected abstract void lazyLoad();
|
||||
}
|
||||
@@ -0,0 +1,414 @@
|
||||
package com.azhon.basic.base;
|
||||
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.ActionBar;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ColorMatrix;
|
||||
import android.graphics.ColorMatrixColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.databinding.DataBindingUtil;
|
||||
import androidx.databinding.ViewDataBinding;
|
||||
|
||||
import com.azhon.basic.utils.ActivityUtil;
|
||||
import com.azhon.basic.view.LoadingDialog;
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
|
||||
/**
|
||||
* 项目名: TODO-MVVM
|
||||
* 包名 com.azhon.basic.base
|
||||
* 文件名: BaseNoModelActivity
|
||||
* 创建时间: 2019-03-28 on 10:28
|
||||
* 描述: TODO 不需要ViewModel的页面基类
|
||||
*
|
||||
* @author
|
||||
*/
|
||||
|
||||
public abstract class BaseNoModelActivity<DB extends ViewDataBinding> extends AppCompatActivity {
|
||||
public static boolean isUIMODENIGHTNO = true;
|
||||
protected DB dataBinding;
|
||||
protected Context context;
|
||||
private LoadingDialog loadingDialog;
|
||||
public Bundle bundle;
|
||||
//获取TAG的activity名称
|
||||
protected final String TAG = this.getClass().getSimpleName();
|
||||
//是否显示标题栏
|
||||
private boolean isShowTitle = false;
|
||||
//是否显示状态栏
|
||||
private boolean isShowStatusBar = true;
|
||||
//是否允许旋转屏幕
|
||||
private boolean isAllowScreenRoate = true;
|
||||
//封装Toast对象
|
||||
private static Toast toast;
|
||||
|
||||
|
||||
@SuppressLint("SourceLockedOrientationActivity")
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
//
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
// Window window = getWindow();
|
||||
// View decor = window.getDecorView();
|
||||
// window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||
// decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
// | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
|
||||
// window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
// window.setStatusBarColor(Color.TRANSPARENT);
|
||||
//// if(this.getApplicationContext().getResources().getConfiguration().uiMode == 0x21){
|
||||
//// decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
|
||||
//// }else {
|
||||
// decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||
//// }
|
||||
//
|
||||
// }
|
||||
int nightModeFlags = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
|
||||
isUIMODENIGHTNO = !(nightModeFlags == Configuration.UI_MODE_NIGHT_YES);
|
||||
|
||||
translucentStatusBar(this);
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
context = this;
|
||||
this.bundle = savedInstanceState;
|
||||
|
||||
ActivityUtil.getInstance().addActivity(this);
|
||||
int layoutId = initLayout();
|
||||
setContentView(layoutId);
|
||||
// setStatusBarColor(this,Color.TRANSPARENT);
|
||||
dataBinding = initDataBinding(layoutId);
|
||||
initView();
|
||||
initData();
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 透明状态栏
|
||||
*
|
||||
* @param activity
|
||||
*/
|
||||
public static void translucentStatusBar(Activity activity) {
|
||||
translucentStatusBar(activity,false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 透明状态栏
|
||||
*
|
||||
* @param activity
|
||||
*/
|
||||
public static void translucentStatusBar(Activity activity,boolean isWhite) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
Window window = activity.getWindow();
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(Color.TRANSPARENT);
|
||||
}
|
||||
|
||||
// 确保内容视图延伸到状态栏下
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
View decorView = activity.getWindow().getDecorView();
|
||||
|
||||
if(isUIMODENIGHTNO) {
|
||||
int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
|
||||
if (isWhite) {
|
||||
uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
|
||||
}
|
||||
decorView.setSystemUiVisibility(uiOptions);
|
||||
|
||||
}else{
|
||||
int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
|
||||
if (isWhite) {
|
||||
uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
|
||||
}
|
||||
decorView.setSystemUiVisibility(uiOptions);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改状态栏颜色,支持4.4以上版本
|
||||
*
|
||||
* @param activity
|
||||
* @param colorId
|
||||
*/
|
||||
public static void setStatusBarColor(Activity activity, int colorId) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
Window window = activity.getWindow();
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(colorId);
|
||||
window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
int uiMode = newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK;
|
||||
switch (uiMode) {
|
||||
case Configuration.UI_MODE_NIGHT_NO:
|
||||
// 白天模式
|
||||
// Toast.makeText(this, "白天模式", Toast.LENGTH_SHORT).show();
|
||||
LogUtils.i("白天模式");
|
||||
isUIMODENIGHTNO = true;
|
||||
break;
|
||||
case Configuration.UI_MODE_NIGHT_YES:
|
||||
// 夜晚模式
|
||||
// Toast.makeText(this, "夜晚模式", Toast.LENGTH_SHORT).show();
|
||||
LogUtils.i("夜间模式");
|
||||
isUIMODENIGHTNO = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// /**
|
||||
// * 修改状态栏颜色,支持4.4以上版本
|
||||
// *
|
||||
// * @param activity
|
||||
// * @param colorId
|
||||
// */
|
||||
// public static void setStatusBarColorW(Activity activity, int colorId, boolean statusBarTextIsWhiteColor) {
|
||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
// Window window = activity.getWindow();
|
||||
// window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||
// window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
// window.setStatusBarColor(activity.getResources().getColor(colorId));
|
||||
// if (statusBarTextIsWhiteColor) {
|
||||
// window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
|
||||
// } else {
|
||||
// window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
public void hideActionBar() {
|
||||
//this.getSupportActionBar().hide();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化要加载的布局资源ID
|
||||
* 此函数优先执行于onCreate()可以做window操作
|
||||
*/
|
||||
protected abstract int initLayout();
|
||||
|
||||
|
||||
/**
|
||||
* 初始化DataBinding
|
||||
*/
|
||||
protected DB initDataBinding(@LayoutRes int layoutId) {
|
||||
return DataBindingUtil.setContentView(this, layoutId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化视图
|
||||
*/
|
||||
protected abstract void initView();
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
protected abstract void initData();
|
||||
|
||||
/**
|
||||
* 显示用户等待框
|
||||
*
|
||||
* @param msg 提示信息
|
||||
*/
|
||||
protected void showDialog(String msg) {
|
||||
if (loadingDialog != null && loadingDialog.isShowing()) {
|
||||
loadingDialog.setLoadingMsg(msg);
|
||||
} else {
|
||||
loadingDialog = new LoadingDialog(context);
|
||||
loadingDialog.setLoadingMsg(msg);
|
||||
loadingDialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 隐藏等待框
|
||||
*/
|
||||
protected void dismissDialog() {
|
||||
if (loadingDialog != null && loadingDialog.isShowing()) {
|
||||
loadingDialog.dismiss();
|
||||
loadingDialog = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (dataBinding != null) {
|
||||
dataBinding.unbind();
|
||||
}
|
||||
ActivityUtil.getInstance().removeActivity(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置是否显示标题栏
|
||||
*
|
||||
* @param showTitle true or false
|
||||
*/
|
||||
public void setShowTitle(boolean showTitle) {
|
||||
isShowTitle = showTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置是否显示状态栏
|
||||
*
|
||||
* @param showStatusBar true or false
|
||||
*/
|
||||
public void setShowStatusBar(boolean showStatusBar) {
|
||||
isShowStatusBar = showStatusBar;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否允许屏幕旋转
|
||||
*
|
||||
* @param allowScreenRoate true or false
|
||||
*/
|
||||
public void setAllowScreenRoate(boolean allowScreenRoate) {
|
||||
isAllowScreenRoate = allowScreenRoate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保证同一按钮在1秒内只会响应一次点击事件
|
||||
*/
|
||||
public abstract class OnSingleClickListener implements View.OnClickListener {
|
||||
//两次点击按钮之间的间隔,目前为1000ms
|
||||
private static final int MIN_CLICK_DELAY_TIME = 1000;
|
||||
private long lastClickTime;
|
||||
|
||||
public abstract void onSingleClick(View view);
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
long curClickTime = System.currentTimeMillis();
|
||||
if ((curClickTime - lastClickTime) >= MIN_CLICK_DELAY_TIME) {
|
||||
lastClickTime = curClickTime;
|
||||
onSingleClick(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 同一按钮在短时间内可重复响应点击事件
|
||||
*/
|
||||
public abstract class OnMultiClickListener implements View.OnClickListener {
|
||||
public abstract void onMultiClick(View view);
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onMultiClick(v);
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 显示提示 toast
|
||||
// *
|
||||
// * @param msg 提示信息
|
||||
// */
|
||||
// @SuppressLint("ShowToast")
|
||||
// public void showToast(String msg) {
|
||||
// try {
|
||||
// if (null == toast) {
|
||||
// toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
|
||||
// } else {
|
||||
// toast.setText(msg);
|
||||
// }
|
||||
// runOnUiThread(new Runnable() {
|
||||
// @Override
|
||||
// public void run() {
|
||||
// toast.show();
|
||||
// }
|
||||
// });
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// //解决在子线程中调用Toast的异常情况处理
|
||||
// Looper.prepare();
|
||||
// Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
|
||||
// Looper.loop();
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* 隐藏软键盘
|
||||
*/
|
||||
public void hideSoftInput() {
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
|
||||
if (getCurrentFocus() != null && null != imm) {
|
||||
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示软键盘
|
||||
*/
|
||||
public void showSoftInput() {
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
|
||||
if (getCurrentFocus() != null && null != imm) {
|
||||
imm.showSoftInputFromInputMethod(getCurrentFocus().getWindowToken(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void showToast(String message) {
|
||||
// try {
|
||||
// SnackbarUtils.Short(dataBinding.getRoot(),message).show();
|
||||
//
|
||||
// }catch (Exception e){e.printStackTrace();}
|
||||
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
|
||||
|
||||
}
|
||||
|
||||
protected void showToast(String message, int color) {
|
||||
try {
|
||||
// SnackbarUtils.Short(dataBinding.getRoot(),message,color).show();
|
||||
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void showToast(View view, String message) {
|
||||
try {
|
||||
// SnackbarUtils.Short(view,message).show();
|
||||
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
package com.azhon.basic.base;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.databinding.DataBindingUtil;
|
||||
import androidx.databinding.ViewDataBinding;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import com.azhon.basic.view.LoadingDialog;
|
||||
|
||||
/**
|
||||
* 项目名: TODO-MVVM
|
||||
* 包名 com.azhon.basic.base
|
||||
* 文件名: BaseNoModelFragment
|
||||
* 创建时间: 2019-03-28 on 17:06
|
||||
* 描述: TODO 不需要ViewModel的页面基类
|
||||
*
|
||||
* @author
|
||||
*/
|
||||
|
||||
public abstract class BaseNoModelFragment<DB extends ViewDataBinding> extends Fragment {
|
||||
|
||||
protected DB dataBinding;
|
||||
protected Context context;
|
||||
protected FragmentActivity activity;
|
||||
private LoadingDialog loadingDialog;
|
||||
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
dataBinding = initDataBinding(inflater, setLayoutResourceID(), container);
|
||||
return dataBinding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
activity = getActivity();
|
||||
setUpView();
|
||||
setUpData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化要加载的布局资源ID
|
||||
*/
|
||||
protected abstract int setLayoutResourceID();
|
||||
|
||||
|
||||
/**
|
||||
* 初始化DataBinding
|
||||
*/
|
||||
protected DB initDataBinding(LayoutInflater inflater, @LayoutRes int layoutId, ViewGroup container) {
|
||||
return DataBindingUtil.inflate(inflater, layoutId, container, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化视图
|
||||
*/
|
||||
protected abstract void setUpView();
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
protected abstract void setUpData();
|
||||
|
||||
/**
|
||||
* 显示用户等待框
|
||||
*
|
||||
* @param msg 提示信息
|
||||
*/
|
||||
protected void showDialog(String msg) {
|
||||
if (loadingDialog != null && loadingDialog.isShowing()) {
|
||||
loadingDialog.setLoadingMsg(msg);
|
||||
} else {
|
||||
loadingDialog = new LoadingDialog(context);
|
||||
loadingDialog.setLoadingMsg(msg);
|
||||
loadingDialog.show();
|
||||
}
|
||||
}
|
||||
protected void showToast(String message){
|
||||
try {
|
||||
// SnackbarUtils.Short(dataBinding.getRoot(),message).show();
|
||||
Toast.makeText(dataBinding.getRoot().getContext(),message,Toast.LENGTH_SHORT).show();
|
||||
|
||||
|
||||
}catch (Exception e){e.printStackTrace();}
|
||||
|
||||
}
|
||||
|
||||
protected void showToast(View view,String message){
|
||||
try {
|
||||
// SnackbarUtils.Short(view,message).show();
|
||||
Toast.makeText(dataBinding.getRoot().getContext(),message,Toast.LENGTH_SHORT).show();
|
||||
|
||||
}catch (Exception e){e.printStackTrace();}
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected void showToast(View view,String message,int color){
|
||||
try {
|
||||
// SnackbarUtils.Short(view,message,color).show();
|
||||
Toast.makeText(dataBinding.getRoot().getContext(),message,Toast.LENGTH_SHORT).show();
|
||||
|
||||
}catch (Exception e){e.printStackTrace();}
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected void showToast(String message,int color){
|
||||
try {
|
||||
// SnackbarUtils.Short(dataBinding.getRoot(),message,color).show();
|
||||
Toast.makeText(dataBinding.getRoot().getContext(),message,Toast.LENGTH_SHORT).show();
|
||||
|
||||
|
||||
}catch (Exception e){e.printStackTrace();}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏等待框
|
||||
*/
|
||||
protected void dismissDialog() {
|
||||
if (loadingDialog != null && loadingDialog.isShowing()) {
|
||||
loadingDialog.dismiss();
|
||||
loadingDialog = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (dataBinding != null) {
|
||||
dataBinding.unbind();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public View getContentView() {
|
||||
return dataBinding.getRoot();
|
||||
}
|
||||
|
||||
public Context getMContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 隐藏软键盘
|
||||
*/
|
||||
public void hideSoftInput() {
|
||||
View v = getActivity().getCurrentFocus();
|
||||
if (v != null && v.getWindowToken() != null) {
|
||||
InputMethodManager manager = (InputMethodManager) getContext()
|
||||
.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
boolean isOpen = manager.isActive();
|
||||
if (isOpen) {
|
||||
manager.hideSoftInputFromWindow(v.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
basicLib/src/main/java/com/azhon/basic/bean/DialogBean.java
Normal file
33
basicLib/src/main/java/com/azhon/basic/bean/DialogBean.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package com.azhon.basic.bean;
|
||||
|
||||
/**
|
||||
* 项目名: TODO-MVVM
|
||||
* 包名 com.azhon.basic.bean
|
||||
* 文件名: DialogBean
|
||||
* 创建时间: 2019-03-27 on 20:54
|
||||
* 描述: TODO 封装的对话框实体类
|
||||
*
|
||||
* @author
|
||||
*/
|
||||
|
||||
public final class DialogBean {
|
||||
|
||||
private boolean isShow;
|
||||
private String msg;
|
||||
|
||||
public boolean isShow() {
|
||||
return isShow;
|
||||
}
|
||||
|
||||
public void setShow(boolean show) {
|
||||
isShow = show;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.azhon.basic.lifecycle;
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
import com.azhon.basic.bean.DialogBean;
|
||||
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
|
||||
/**
|
||||
* 项目名: TODO-MVVM
|
||||
* 包名 com.azhon.basic.lifecycle
|
||||
* 文件名: BaseViewModel
|
||||
* 创建时间: 2019-03-27 on 10:44
|
||||
* 描述: TODO ViewModel基类,管理rxJava发出的请求,ViewModel销毁同时也取消请求
|
||||
*
|
||||
* @author
|
||||
*/
|
||||
|
||||
public abstract class BaseViewModel extends ViewModel {
|
||||
|
||||
/**
|
||||
* 管理RxJava请求
|
||||
*/
|
||||
private CompositeDisposable compositeDisposable;
|
||||
/**
|
||||
* 用来通知 Activity/Fragment 是否显示等待Dialog
|
||||
*/
|
||||
protected DialogLiveData<DialogBean> showDialog = new DialogLiveData<>();
|
||||
/**
|
||||
* 当ViewModel层出现错误需要通知到Activity/Fragment
|
||||
*/
|
||||
protected MutableLiveData<Object> error = new MutableLiveData<>();
|
||||
|
||||
/**
|
||||
* 添加 rxJava 发出的请求
|
||||
*/
|
||||
protected void addDisposable(Disposable disposable) {
|
||||
if (compositeDisposable == null || compositeDisposable.isDisposed()) {
|
||||
compositeDisposable = new CompositeDisposable();
|
||||
}
|
||||
compositeDisposable.add(disposable);
|
||||
}
|
||||
|
||||
public void getShowDialog(LifecycleOwner owner, Observer<DialogBean> observer) {
|
||||
showDialog.observe(owner, observer);
|
||||
}
|
||||
|
||||
public void getError(LifecycleOwner owner, Observer<Object> observer) {
|
||||
error.observe(owner, observer);
|
||||
}
|
||||
|
||||
/**
|
||||
* ViewModel销毁同时也取消请求
|
||||
*/
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
super.onCleared();
|
||||
if (compositeDisposable != null) {
|
||||
compositeDisposable.dispose();
|
||||
compositeDisposable = null;
|
||||
}
|
||||
showDialog = null;
|
||||
error = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.azhon.basic.lifecycle;
|
||||
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.azhon.basic.bean.DialogBean;
|
||||
|
||||
/**
|
||||
* 项目名: TODO-MVVM
|
||||
* 包名 com.azhon.basic.lifecycle
|
||||
* 文件名: DialogLiveData
|
||||
* 创建时间: 2019-03-27 on 20:57
|
||||
* 描述: TODO
|
||||
*
|
||||
* @author
|
||||
*/
|
||||
|
||||
public final class DialogLiveData<T> extends MutableLiveData<T> {
|
||||
|
||||
private DialogBean bean = new DialogBean();
|
||||
|
||||
public void setValue(boolean isShow) {
|
||||
bean.setShow(isShow);
|
||||
bean.setMsg("");
|
||||
setValue((T) bean);
|
||||
}
|
||||
|
||||
public void setValue(boolean isShow, String msg) {
|
||||
bean.setShow(isShow);
|
||||
bean.setMsg(msg);
|
||||
setValue((T) bean);
|
||||
}
|
||||
}
|
||||
46
basicLib/src/main/java/com/azhon/basic/retrofit/BaseApi.java
Normal file
46
basicLib/src/main/java/com/azhon/basic/retrofit/BaseApi.java
Normal file
@@ -0,0 +1,46 @@
|
||||
package com.azhon.basic.retrofit;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
import retrofit2.converter.scalars.ScalarsConverterFactory;
|
||||
|
||||
/**
|
||||
* 项目名: TODO-MVVM
|
||||
* 包名 com.azhon.basic.retrofit
|
||||
* 文件名: BaseApi
|
||||
* 创建时间: 2019-03-27 on 14:52
|
||||
* 描述: TODO 封装基础的Retrofit
|
||||
*
|
||||
* @author
|
||||
*/
|
||||
|
||||
public abstract class BaseApi {
|
||||
|
||||
/**
|
||||
* 初始化Retrofit
|
||||
*/
|
||||
public Retrofit initRetrofit(String baseUrl) {
|
||||
Retrofit.Builder builder = new Retrofit.Builder();
|
||||
//支持返回Call<String>
|
||||
builder.addConverterFactory(ScalarsConverterFactory.create());
|
||||
//支持直接格式化json返回Bean对象
|
||||
builder.addConverterFactory(GsonConverterFactory.create());
|
||||
//支持RxJava
|
||||
builder.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
|
||||
builder.baseUrl(baseUrl);
|
||||
OkHttpClient client = setClient();
|
||||
if (client != null) {
|
||||
builder.client(client);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置OkHttpClient,添加拦截器等
|
||||
*
|
||||
* @return 可以返回为null
|
||||
*/
|
||||
protected abstract OkHttpClient setClient();
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.azhon.basic.utils;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
* 项目名: TODO-MVVM
|
||||
* 包名 com.azhon.basic.utils
|
||||
* 文件名: ActivityUtil
|
||||
* 创建时间: 2019-03-29 on 17:13
|
||||
* 描述: TODO 管理所有Activity的实例
|
||||
*
|
||||
* @author
|
||||
*/
|
||||
|
||||
public class ActivityUtil {
|
||||
|
||||
private static Stack<Activity> stack;
|
||||
private static ActivityUtil manager;
|
||||
|
||||
/**
|
||||
* 获取实例
|
||||
*/
|
||||
public static synchronized ActivityUtil getInstance() {
|
||||
if (manager == null) {
|
||||
manager = new ActivityUtil();
|
||||
stack = new Stack<>();
|
||||
}
|
||||
return manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加Activity
|
||||
*/
|
||||
public synchronized void addActivity(Activity activity) {
|
||||
stack.add(activity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除Activity
|
||||
*/
|
||||
public synchronized void removeActivity(Activity activity) {
|
||||
stack.remove(activity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束指定类名的Activity
|
||||
*/
|
||||
public void finishActivity(Class<?> cls) {
|
||||
for (Activity activity : stack) {
|
||||
if (activity.getClass().equals(cls)) {
|
||||
finishActivity(activity);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束指定的Activity
|
||||
*/
|
||||
public void finishActivity(Activity activity) {
|
||||
if (activity != null) {
|
||||
activity.finish();
|
||||
stack.remove(activity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在Activity
|
||||
*/
|
||||
public boolean containsActivity(Class<?> cls) {
|
||||
for (Activity activity : stack) {
|
||||
if (activity.getClass().equals(cls)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束所有Activity
|
||||
*/
|
||||
public void finishAllActivity() {
|
||||
for (Activity activity : stack) {
|
||||
if (activity != null) {
|
||||
activity.finish();
|
||||
}
|
||||
}
|
||||
stack.clear();
|
||||
}
|
||||
}
|
||||
26
basicLib/src/main/java/com/azhon/basic/utils/AnimUtil.java
Normal file
26
basicLib/src/main/java/com/azhon/basic/utils/AnimUtil.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package com.azhon.basic.utils;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import com.github.hariprasanths.bounceview.BounceView;
|
||||
|
||||
/**
|
||||
* 控件的点击缩放事件
|
||||
*/
|
||||
public class AnimUtil {
|
||||
/**
|
||||
* 控件设置动画事件
|
||||
* @param view
|
||||
*/
|
||||
public static void setAnimView(View view){
|
||||
BounceView.addAnimTo(view).setScaleForPushInAnim(1.02f,1.02f).setScaleForPopOutAnim(1.0f,1.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* 控件设置动画事件
|
||||
* @param view
|
||||
*/
|
||||
public static void setAnimView(View view,float inAnim){
|
||||
BounceView.addAnimTo(view).setScaleForPushInAnim(inAnim,inAnim).setScaleForPopOutAnim(1.0f,1.0f);
|
||||
}
|
||||
}
|
||||
76
basicLib/src/main/java/com/azhon/basic/utils/ApkUtil.java
Normal file
76
basicLib/src/main/java/com/azhon/basic/utils/ApkUtil.java
Normal file
@@ -0,0 +1,76 @@
|
||||
package com.azhon.basic.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.core.content.FileProvider;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 文件名: ApkUtil
|
||||
* 创建时间: 2018/5/4 on 15:49
|
||||
* 描述: TODO
|
||||
*
|
||||
* @author
|
||||
*/
|
||||
|
||||
public class ApkUtil {
|
||||
/**
|
||||
* 安装一个apk
|
||||
*
|
||||
* @param context 上下文
|
||||
* @param apk 安装包文件
|
||||
*/
|
||||
public static void installApk(Context context, File apk) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setAction(Intent.ACTION_VIEW);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
Uri uri;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
uri = FileProvider.getUriForFile(context, context.getPackageName(), apk);
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
} else {
|
||||
uri = Uri.fromFile(apk);
|
||||
}
|
||||
intent.setDataAndType(uri, "application/vnd.android.package-archive");
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前app的升级版本号
|
||||
*
|
||||
* @param context 上下文
|
||||
*/
|
||||
public static long getVersionCode(Context context) {
|
||||
try {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
|
||||
return packageInfo.getLongVersionCode();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前app的版本号
|
||||
*
|
||||
* @param context 上下文
|
||||
*/
|
||||
public static String getVersionName(Context context) {
|
||||
try {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
|
||||
return packageInfo.versionName;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "1.0.0";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.azhon.basic.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.DisplayMetrics;
|
||||
|
||||
/**
|
||||
* 文件名: DensityUtil
|
||||
* 创建时间: 2018/3/18 on 13:32
|
||||
* 描述: TODO
|
||||
*
|
||||
* @author
|
||||
*/
|
||||
|
||||
|
||||
public class DensityUtil {
|
||||
|
||||
/**
|
||||
* 获取屏幕宽度(像素)
|
||||
*
|
||||
* @param context 上下文
|
||||
* @return px
|
||||
*/
|
||||
public static int getWith(Context context) {
|
||||
DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
||||
return dm.widthPixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取屏幕高度(像素)
|
||||
*
|
||||
* @param context 上下文
|
||||
* @return px
|
||||
*/
|
||||
public static int getHeight(Context context) {
|
||||
DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
||||
return dm.heightPixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取状态栏的高度
|
||||
*
|
||||
* @param context 上下文
|
||||
* @return px
|
||||
*/
|
||||
public static int getStatusBarHeight(Context context) {
|
||||
int statusBarHeight = 0;
|
||||
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
|
||||
if (resourceId > 0) {
|
||||
statusBarHeight = context.getResources().getDimensionPixelSize(resourceId);
|
||||
}
|
||||
return statusBarHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取标题栏(ActionBar)的高度
|
||||
*
|
||||
* @param context 上下文
|
||||
* @return px
|
||||
*/
|
||||
public static int getActionBarHeight(Context context) {
|
||||
TypedArray values = context.getTheme().obtainStyledAttributes(new int[]{android.R.attr.actionBarSize});
|
||||
int actionBarHeight = values.getDimensionPixelSize(0, 0);
|
||||
values.recycle();
|
||||
return actionBarHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
|
||||
*/
|
||||
public static int dip2px(Context context, float dpValue) {
|
||||
final float scale = context.getResources().getDisplayMetrics().density;
|
||||
return (int) (dpValue * scale + 0.5f);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
|
||||
*/
|
||||
public static int px2dip(Context context, float pxValue) {
|
||||
final float scale = context.getResources().getDisplayMetrics().density;
|
||||
return (int) (pxValue / scale + 0.5f);
|
||||
}
|
||||
}
|
||||
144
basicLib/src/main/java/com/azhon/basic/utils/SharePreUtil.java
Normal file
144
basicLib/src/main/java/com/azhon/basic/utils/SharePreUtil.java
Normal file
@@ -0,0 +1,144 @@
|
||||
package com.azhon.basic.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
/**
|
||||
* 文件名: SharePreUtil
|
||||
* 创建者:
|
||||
* 创建时间: 2016/12/12 on 11:58
|
||||
* 描述: SharedPreferences存取工具类
|
||||
*/
|
||||
|
||||
public class SharePreUtil {
|
||||
/**
|
||||
* 配置文件,文件名
|
||||
*/
|
||||
private static final String SHARE_NAME = "config";
|
||||
|
||||
/**
|
||||
* 存字符串
|
||||
*
|
||||
* @param context 上下文
|
||||
* @param key 键
|
||||
* @param values 值
|
||||
*/
|
||||
public static void putString(Context context, String key, String values) {
|
||||
SharedPreferences sp = context.getSharedPreferences(SHARE_NAME, Context.MODE_PRIVATE);
|
||||
sp.edit().putString(key, values).apply();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 取字符串
|
||||
*
|
||||
* @param context 上下文
|
||||
* @param key 键
|
||||
* @param values 默认值
|
||||
* @return 取出的值
|
||||
*/
|
||||
public static String getString(Context context, String key, String values) {
|
||||
SharedPreferences sp = context.getSharedPreferences(SHARE_NAME, Context.MODE_PRIVATE);
|
||||
return sp.getString(key, values);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 存布尔值
|
||||
*
|
||||
* @param context 上下文
|
||||
* @param key 键
|
||||
* @param values 值
|
||||
*/
|
||||
public static void putBoolean(Context context, String key, boolean values) {
|
||||
SharedPreferences sp = context.getSharedPreferences(SHARE_NAME, Context.MODE_PRIVATE);
|
||||
sp.edit().putBoolean(key, values).apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* 取布尔值
|
||||
*
|
||||
* @param context 上下文
|
||||
* @param key 键
|
||||
* @param values 默认值
|
||||
* @return true/false
|
||||
*/
|
||||
public static boolean getBoolean(Context context, String key, boolean values) {
|
||||
SharedPreferences sp = context.getSharedPreferences(SHARE_NAME, Context.MODE_PRIVATE);
|
||||
return sp.getBoolean(key, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* 存int值
|
||||
*
|
||||
* @param context 上下文
|
||||
* @param key 键
|
||||
* @param values 值
|
||||
*/
|
||||
public static void putInt(Context context, String key, int values) {
|
||||
SharedPreferences sp = context.getSharedPreferences(SHARE_NAME, Context.MODE_PRIVATE);
|
||||
sp.edit().putInt(key, values).apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* 取int值
|
||||
*
|
||||
* @param context 上下文
|
||||
* @param key 键
|
||||
* @param values 默认值
|
||||
* @return
|
||||
*/
|
||||
public static int getInt(Context context, String key, int values) {
|
||||
SharedPreferences sp = context.getSharedPreferences(SHARE_NAME, Context.MODE_PRIVATE);
|
||||
return sp.getInt(key, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一条字段
|
||||
*
|
||||
* @param context 上下文
|
||||
* @param key 键
|
||||
*/
|
||||
public static void deleShare(Context context, String key) {
|
||||
SharedPreferences sp = context.getSharedPreferences(SHARE_NAME, Context.MODE_PRIVATE);
|
||||
//单个清理
|
||||
sp.edit().remove(key).apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除全部数据
|
||||
*
|
||||
* @param context 上下文
|
||||
*/
|
||||
public static void deleShareAll(Context context) {
|
||||
SharedPreferences sp = context.getSharedPreferences(SHARE_NAME, Context.MODE_PRIVATE);
|
||||
//全部清理
|
||||
sp.edit().clear().apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看SharedPreferences的内容
|
||||
*/
|
||||
public static String lookSharePre(Context context) {
|
||||
try {
|
||||
FileInputStream stream = new FileInputStream(new File("/data/data/" +
|
||||
context.getPackageName() + "/shared_prefs", SHARE_NAME + ".xml"));
|
||||
BufferedReader bff = new BufferedReader(new InputStreamReader(stream));
|
||||
String line;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while ((line = bff.readLine()) != null) {
|
||||
sb.append(line);
|
||||
sb.append("\n");
|
||||
}
|
||||
return sb.toString();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "未找到当前配置文件!";
|
||||
}
|
||||
}
|
||||
475
basicLib/src/main/java/com/azhon/basic/utils/SnackbarUtils.java
Normal file
475
basicLib/src/main/java/com/azhon/basic/utils/SnackbarUtils.java
Normal file
@@ -0,0 +1,475 @@
|
||||
package com.azhon.basic.utils;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Space;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
|
||||
import com.azhon.basic.R;
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
|
||||
public class SnackbarUtils {
|
||||
//设置Snackbar背景颜色
|
||||
private static final int color_info = 0XFF2094F3;
|
||||
private static final int color_confirm = 0XFF4CB04E;
|
||||
private static final int color_warning = 0XFFFEC005;
|
||||
private static final int color_danger = 0XFFF44336;
|
||||
//工具类当前持有的Snackbar实例
|
||||
private static Snackbar mSnackbar = null;
|
||||
|
||||
|
||||
private SnackbarUtils(){
|
||||
throw new RuntimeException("禁止无参创建实例");
|
||||
}
|
||||
|
||||
public SnackbarUtils(@NonNull Snackbar snackbar){
|
||||
this.mSnackbar = snackbar;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 mSnackbar
|
||||
* @return
|
||||
*/
|
||||
public Snackbar getSnackbar() {
|
||||
return mSnackbar;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化Snackbar实例
|
||||
* 展示时间:Snackbar.LENGTH_SHORT
|
||||
* @param view
|
||||
* @param message
|
||||
* @return
|
||||
*/
|
||||
public static SnackbarUtils Short(View view, String message){
|
||||
mSnackbar = Snackbar.make(view,message,Snackbar.LENGTH_SHORT);
|
||||
return new SnackbarUtils(mSnackbar).backColor(0XCC1771E3);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化Snackbar实例
|
||||
* 展示时间:Snackbar.LENGTH_SHORT
|
||||
* @param view
|
||||
* @param message
|
||||
* @return
|
||||
*/
|
||||
public static SnackbarUtils Short(View view, String message,int Color){
|
||||
mSnackbar = Snackbar.make(view,message,Snackbar.LENGTH_SHORT);
|
||||
return new SnackbarUtils(mSnackbar).backColor(Color);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化Snackbar实例
|
||||
* 展示时间:Snackbar.LENGTH_LONG
|
||||
* @param view
|
||||
* @param message
|
||||
* @return
|
||||
*/
|
||||
public static SnackbarUtils Long(View view, String message){
|
||||
mSnackbar = Snackbar.make(view,message,Snackbar.LENGTH_LONG);
|
||||
return new SnackbarUtils(mSnackbar).backColor(0XCC1771E3);
|
||||
}
|
||||
/**
|
||||
* 初始化Snackbar实例
|
||||
* 展示时间:Snackbar.LENGTH_INDEFINITE
|
||||
* @param view
|
||||
* @param message
|
||||
* @return
|
||||
*/
|
||||
public static SnackbarUtils Indefinite(View view, String message){
|
||||
mSnackbar = Snackbar.make(view,message,Snackbar.LENGTH_INDEFINITE);
|
||||
return new SnackbarUtils(mSnackbar).backColor(0XCC1771E3);
|
||||
}
|
||||
/**
|
||||
* 初始化Snackbar实例
|
||||
* 展示时间:duration 毫秒
|
||||
* @param view
|
||||
* @param message
|
||||
* @param duration 展示时长(毫秒)
|
||||
* @return
|
||||
*/
|
||||
public static SnackbarUtils Custom(View view, String message, int duration){
|
||||
mSnackbar = Snackbar.make(view,message,Snackbar.LENGTH_SHORT);
|
||||
mSnackbar.setDuration(duration);
|
||||
return new SnackbarUtils(mSnackbar).backColor(0XCC1771E3);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置mSnackbar背景色为 color_info
|
||||
*/
|
||||
public SnackbarUtils info(){
|
||||
mSnackbar.getView().setBackgroundColor(color_info);
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
/**
|
||||
* 设置mSnackbar背景色为 color_confirm
|
||||
*/
|
||||
public SnackbarUtils confirm(){
|
||||
mSnackbar.getView().setBackgroundColor(color_confirm);
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
/**
|
||||
* 设置Snackbar背景色为 color_warning
|
||||
*/
|
||||
public SnackbarUtils warning(){
|
||||
mSnackbar.getView().setBackgroundColor(color_warning);
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
/**
|
||||
* 设置Snackbar背景色为 color_warning
|
||||
*/
|
||||
public SnackbarUtils danger(){
|
||||
mSnackbar.getView().setBackgroundColor(color_danger);
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Snackbar背景色
|
||||
* @param backgroundColor
|
||||
*/
|
||||
public SnackbarUtils backColor(@ColorInt int backgroundColor){
|
||||
mSnackbar.getView().setBackgroundColor(backgroundColor);
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置TextView(@+id/snackbar_text)的文字颜色
|
||||
* @param messageColor
|
||||
*/
|
||||
public SnackbarUtils messageColor(@ColorInt int messageColor){
|
||||
((TextView)mSnackbar.getView().findViewById(R.id.snackbar_text)).setTextColor(messageColor);
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Button(@+id/snackbar_action)的文字颜色
|
||||
* @param actionTextColor
|
||||
*/
|
||||
public SnackbarUtils actionColor(@ColorInt int actionTextColor){
|
||||
((Button)mSnackbar.getView().findViewById(R.id.snackbar_action)).setTextColor(actionTextColor);
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 Snackbar背景色 + TextView(@+id/snackbar_text)的文字颜色 + Button(@+id/snackbar_action)的文字颜色
|
||||
* @param backgroundColor
|
||||
* @param messageColor
|
||||
* @param actionTextColor
|
||||
*/
|
||||
public SnackbarUtils colors(@ColorInt int backgroundColor, @ColorInt int messageColor, @ColorInt int actionTextColor){
|
||||
mSnackbar.getView().setBackgroundColor(backgroundColor);
|
||||
((TextView)mSnackbar.getView().findViewById(R.id.snackbar_text)).setTextColor(messageColor);
|
||||
((Button)mSnackbar.getView().findViewById(R.id.snackbar_action)).setTextColor(actionTextColor);
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Snackbar 背景透明度
|
||||
* @param alpha
|
||||
* @return
|
||||
*/
|
||||
public SnackbarUtils alpha(float alpha){
|
||||
alpha = alpha>=1.0f?1.0f:(alpha<=0.0f?0.0f:alpha);
|
||||
mSnackbar.getView().setAlpha(alpha);
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Snackbar显示的位置
|
||||
* @param gravity
|
||||
*/
|
||||
public SnackbarUtils gravityFrameLayout(int gravity){
|
||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(mSnackbar.getView().getLayoutParams().width,mSnackbar.getView().getLayoutParams().height);
|
||||
params.gravity = gravity;
|
||||
mSnackbar.getView().setLayoutParams(params);
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Snackbar显示的位置,当Snackbar和CoordinatorLayout组合使用的时候
|
||||
* @param gravity
|
||||
*/
|
||||
public SnackbarUtils gravityCoordinatorLayout(int gravity){
|
||||
CoordinatorLayout.LayoutParams params = new CoordinatorLayout.LayoutParams(mSnackbar.getView().getLayoutParams().width,mSnackbar.getView().getLayoutParams().height);
|
||||
params.gravity = gravity;
|
||||
mSnackbar.getView().setLayoutParams(params);
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置按钮文字内容 及 点击监听
|
||||
* {@link Snackbar#setAction(CharSequence, View.OnClickListener)}
|
||||
* @param resId
|
||||
* @param listener
|
||||
* @return
|
||||
*/
|
||||
public SnackbarUtils setAction(@StringRes int resId, View.OnClickListener listener){
|
||||
return setAction(getSnackbar().getView().getResources().getText(resId), listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置按钮文字内容 及 点击监听
|
||||
* {@link Snackbar#setAction(CharSequence, View.OnClickListener)}
|
||||
* @param text
|
||||
* @param listener
|
||||
* @return
|
||||
*/
|
||||
public SnackbarUtils setAction(CharSequence text, View.OnClickListener listener){
|
||||
mSnackbar.setAction(text,listener);
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 mSnackbar 展示完成 及 隐藏完成 的监听
|
||||
* @param setCallback
|
||||
* @return
|
||||
*/
|
||||
public SnackbarUtils setCallback(Snackbar.Callback setCallback){
|
||||
mSnackbar.setCallback(setCallback);
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置TextView(@+id/snackbar_text)左右两侧的图片
|
||||
* @param leftDrawable
|
||||
* @param rightDrawable
|
||||
* @return
|
||||
*/
|
||||
public SnackbarUtils leftAndRightDrawable(@Nullable @DrawableRes Integer leftDrawable, @Nullable @DrawableRes Integer rightDrawable){
|
||||
Drawable drawableLeft = null;
|
||||
Drawable drawableRight = null;
|
||||
if(leftDrawable!=null){
|
||||
try {
|
||||
drawableLeft = getSnackbar().getView().getResources().getDrawable(leftDrawable.intValue());
|
||||
}catch (Exception e){
|
||||
Log.e("Jet","getSnackbar().getView().getResources().getDrawable(leftDrawable.intValue())");
|
||||
}
|
||||
}
|
||||
if(rightDrawable!=null){
|
||||
try {
|
||||
drawableRight = getSnackbar().getView().getResources().getDrawable(rightDrawable.intValue());
|
||||
}catch (Exception e){
|
||||
Log.e("Jet","getSnackbar().getView().getResources().getDrawable(rightDrawable.intValue())");
|
||||
}
|
||||
}
|
||||
return leftAndRightDrawable(drawableLeft,drawableRight);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置TextView(@+id/snackbar_text)左右两侧的图片
|
||||
* @param leftDrawable
|
||||
* @param rightDrawable
|
||||
* @return
|
||||
*/
|
||||
public SnackbarUtils leftAndRightDrawable(@Nullable Drawable leftDrawable, @Nullable Drawable rightDrawable){
|
||||
TextView message = (TextView) mSnackbar.getView().findViewById(R.id.snackbar_text);
|
||||
LinearLayout.LayoutParams paramsMessage = (LinearLayout.LayoutParams) message.getLayoutParams();
|
||||
paramsMessage = new LinearLayout.LayoutParams(paramsMessage.width, paramsMessage.height,0.0f);
|
||||
message.setLayoutParams(paramsMessage);
|
||||
message.setCompoundDrawablePadding(message.getPaddingLeft());
|
||||
int textSize = (int) message.getTextSize();
|
||||
Log.e("Jet","textSize:"+textSize);
|
||||
if(leftDrawable!=null){
|
||||
leftDrawable.setBounds(0,0,textSize,textSize);
|
||||
}
|
||||
if(rightDrawable!=null){
|
||||
rightDrawable.setBounds(0,0,textSize,textSize);
|
||||
}
|
||||
message.setCompoundDrawables(leftDrawable,null,rightDrawable,null);
|
||||
LinearLayout.LayoutParams paramsSpace = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT,1.0f);
|
||||
((Snackbar.SnackbarLayout)mSnackbar.getView()).addView(new Space(mSnackbar.getView().getContext()),1,paramsSpace);
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置TextView(@+id/snackbar_text)中文字的对齐方式 居中
|
||||
* @return
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
public SnackbarUtils messageCenter(){
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
|
||||
TextView message = (TextView) mSnackbar.getView().findViewById(R.id.snackbar_text);
|
||||
//View.setTextAlignment需要SDK>=17
|
||||
message.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
|
||||
message.setGravity(Gravity.CENTER);
|
||||
}
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置TextView(@+id/snackbar_text)中文字的对齐方式 居右
|
||||
* @return
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
public SnackbarUtils messageRight(){
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
|
||||
TextView message = (TextView) mSnackbar.getView().findViewById(R.id.snackbar_text);
|
||||
//View.setTextAlignment需要SDK>=17
|
||||
message.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY);
|
||||
message.setGravity(Gravity.CENTER_VERTICAL|Gravity.RIGHT);
|
||||
}
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* 向Snackbar布局中添加View(Google不建议,复杂的布局应该使用DialogFragment进行展示)
|
||||
* @param layoutId 要添加的View的布局文件ID
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
public SnackbarUtils addView(int layoutId, int index) {
|
||||
//加载布局文件新建View
|
||||
View addView = LayoutInflater.from(mSnackbar.getView().getContext()).inflate(layoutId,null);
|
||||
return addView(addView,index);
|
||||
}
|
||||
|
||||
/**
|
||||
* 向Snackbar布局中添加View(Google不建议,复杂的布局应该使用DialogFragment进行展示)
|
||||
* @param addView
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
public SnackbarUtils addView(View addView, int index) {
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);//设置新建布局参数
|
||||
//设置新建View在Snackbar内垂直居中显示
|
||||
params.gravity= Gravity.CENTER_VERTICAL;
|
||||
addView.setLayoutParams(params);
|
||||
((Snackbar.SnackbarLayout)mSnackbar.getView()).addView(addView,index);
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Snackbar布局的外边距
|
||||
* 注:经试验发现,调用margins后再调用 gravityFrameLayout,则margins无效.
|
||||
* 为保证margins有效,应该先调用 gravityFrameLayout,在 show() 之前调用 margins
|
||||
* @param margin
|
||||
* @return
|
||||
*/
|
||||
public SnackbarUtils margins(int margin){
|
||||
return margins(margin,margin,margin,margin);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Snackbar布局的外边距
|
||||
* 注:经试验发现,调用margins后再调用 gravityFrameLayout,则margins无效.
|
||||
* 为保证margins有效,应该先调用 gravityFrameLayout,在 show() 之前调用 margins
|
||||
* @param left
|
||||
* @param top
|
||||
* @param right
|
||||
* @param bottom
|
||||
* @return
|
||||
*/
|
||||
public SnackbarUtils margins(int left, int top, int right, int bottom){
|
||||
ViewGroup.LayoutParams params = mSnackbar.getView().getLayoutParams();
|
||||
((ViewGroup.MarginLayoutParams) params).setMargins(left,top,right,bottom);
|
||||
mSnackbar.getView().setLayoutParams(params);
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* 经试验发现:
|
||||
* 执行过{@link SnackbarUtils#backColor(int)}后:background instanceof ColorDrawable
|
||||
* 未执行过{@link SnackbarUtils#backColor(int)}:background instanceof GradientDrawable
|
||||
* @return
|
||||
*/
|
||||
/*
|
||||
public SnackbarUtils radius(){
|
||||
Drawable background = mSnackbar.getView().getBackground();
|
||||
if(background instanceof GradientDrawable){
|
||||
Log.e("Jet","radius():GradientDrawable");
|
||||
}
|
||||
if(background instanceof ColorDrawable){
|
||||
Log.e("Jet","radius():ColorDrawable");
|
||||
}
|
||||
if(background instanceof StateListDrawable){
|
||||
Log.e("Jet","radius():StateListDrawable");
|
||||
}
|
||||
Log.e("Jet","radius()background:"+background.getClass().getSimpleName());
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* 通过SnackBar现在的背景,获取其设置圆角值时候所需的GradientDrawable实例
|
||||
* @param backgroundOri
|
||||
* @return
|
||||
*/
|
||||
private GradientDrawable getRadiusDrawable(Drawable backgroundOri){
|
||||
GradientDrawable background = null;
|
||||
if(backgroundOri instanceof GradientDrawable){
|
||||
background = (GradientDrawable) backgroundOri;
|
||||
}else if(backgroundOri instanceof ColorDrawable){
|
||||
int backgroundColor = ((ColorDrawable)backgroundOri).getColor();
|
||||
background = new GradientDrawable();
|
||||
background.setColor(backgroundColor);
|
||||
}else {
|
||||
}
|
||||
return background;
|
||||
}
|
||||
/**
|
||||
* 设置Snackbar布局的圆角半径值
|
||||
* @param radius 圆角半径
|
||||
* @return
|
||||
*/
|
||||
public SnackbarUtils radius(float radius){
|
||||
//将要设置给mSnackbar的背景
|
||||
GradientDrawable background = getRadiusDrawable(mSnackbar.getView().getBackground());
|
||||
if(background != null){
|
||||
radius = radius<=0?12:radius;
|
||||
background.setCornerRadius(radius);
|
||||
mSnackbar.getView().setBackgroundDrawable(background);
|
||||
}
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Snackbar布局的圆角半径值及边框颜色及边框宽度
|
||||
* @param radius
|
||||
* @param strokeWidth
|
||||
* @param strokeColor
|
||||
* @return
|
||||
*/
|
||||
public SnackbarUtils radius(int radius, int strokeWidth, @ColorInt int strokeColor){
|
||||
//将要设置给mSnackbar的背景
|
||||
GradientDrawable background = getRadiusDrawable(mSnackbar.getView().getBackground());
|
||||
if(background != null){
|
||||
radius = radius<=0?12:radius;
|
||||
strokeWidth = strokeWidth<=0?1:(strokeWidth>=mSnackbar.getView().findViewById(R.id.snackbar_text).getPaddingTop()?2:strokeWidth);
|
||||
background.setCornerRadius(radius);
|
||||
background.setStroke(strokeWidth,strokeColor);
|
||||
mSnackbar.getView().setBackgroundDrawable(background);
|
||||
}
|
||||
return new SnackbarUtils(mSnackbar);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 显示 mSnackbar
|
||||
*/
|
||||
public void show(){
|
||||
if(mSnackbar!=null){
|
||||
mSnackbar.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
117
basicLib/src/main/java/com/azhon/basic/utils/TimeUtil.java
Normal file
117
basicLib/src/main/java/com/azhon/basic/utils/TimeUtil.java
Normal file
@@ -0,0 +1,117 @@
|
||||
package com.azhon.basic.utils;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 创建者:
|
||||
* 创建时间: 2017/6/20 on 15:12
|
||||
* 描述: TODO 时间格式化
|
||||
*/
|
||||
public class TimeUtil {
|
||||
|
||||
/**
|
||||
* 将时间戳转换为时间
|
||||
*
|
||||
* @param time
|
||||
* @return
|
||||
*/
|
||||
public static String yyyyMMdd(long time) {
|
||||
if (time == 0) {
|
||||
return "";
|
||||
}
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
|
||||
Date date = new Date(time);
|
||||
return format.format(date);
|
||||
}
|
||||
|
||||
/***
|
||||
* 时间戳转换为时间
|
||||
*
|
||||
* @param time
|
||||
* @return
|
||||
*/
|
||||
public static String HHmmss(long time) {
|
||||
if (time == 0) {
|
||||
return "";
|
||||
}
|
||||
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
|
||||
Date date = new Date(time);
|
||||
return format.format(date);
|
||||
}
|
||||
|
||||
/***
|
||||
* 时间戳转换为时间
|
||||
*
|
||||
* @param time
|
||||
* @return
|
||||
*/
|
||||
public static String yyyyMMddHHmm(long time) {
|
||||
if (time == 0) {
|
||||
return "";
|
||||
}
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
Date date = new Date(time);
|
||||
return format.format(date);
|
||||
}
|
||||
|
||||
/***
|
||||
* 时间戳转换为时间
|
||||
*
|
||||
* @param time
|
||||
* @return
|
||||
*/
|
||||
public static String yyyyMMddHHmmss(long time) {
|
||||
if (time == 0) {
|
||||
return "";
|
||||
}
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
Date date = new Date(time);
|
||||
return format.format(date);
|
||||
}
|
||||
|
||||
/***
|
||||
* 时间戳转换为时间
|
||||
*
|
||||
* @param time
|
||||
* @return
|
||||
*/
|
||||
public static String MMddHHmm(long time) {
|
||||
if (time == 0) {
|
||||
return "";
|
||||
}
|
||||
SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm");
|
||||
Date date = new Date(time);
|
||||
return format.format(date);
|
||||
}
|
||||
|
||||
/***
|
||||
* 时间戳转换为时间
|
||||
*
|
||||
* @param time
|
||||
* @return
|
||||
*/
|
||||
public static String MMddHHmmss(long time) {
|
||||
if (time == 0) {
|
||||
return "";
|
||||
}
|
||||
SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss");
|
||||
Date date = new Date(time);
|
||||
return format.format(date);
|
||||
}
|
||||
|
||||
/***
|
||||
* 时间戳转换为时间
|
||||
*
|
||||
* @param time
|
||||
* @return
|
||||
*/
|
||||
public static String byPattern(long time, String pattern) {
|
||||
if (time == 0) {
|
||||
return "";
|
||||
}
|
||||
SimpleDateFormat format = new SimpleDateFormat(pattern);
|
||||
Date date = new Date(time);
|
||||
return format.format(date);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.azhon.basic.view;
|
||||
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.databinding.DataBindingUtil;
|
||||
|
||||
import com.azhon.basic.R;
|
||||
import com.azhon.basic.databinding.DialogLoadingBinding;
|
||||
import com.azhon.basic.utils.DensityUtil;
|
||||
|
||||
/**
|
||||
* 项目名: TODO-MVVM
|
||||
* 包名 com.azhon.basic.view
|
||||
* 文件名: LoadingDialog
|
||||
* 创建时间: 2019-03-29 on 11:30
|
||||
* 描述: TODO 等待对话框
|
||||
*
|
||||
* @author
|
||||
*/
|
||||
|
||||
public class LoadingDialog extends Dialog {
|
||||
|
||||
private DialogLoadingBinding binding;
|
||||
|
||||
|
||||
public LoadingDialog(@NonNull Context context) {
|
||||
super(context, R.style.LoadingDialog);
|
||||
setCanceledOnTouchOutside(false);
|
||||
binding = DataBindingUtil.inflate(LayoutInflater.from(context),
|
||||
R.layout.dialog_loading, null, false);
|
||||
setContentView(binding.getRoot());
|
||||
Window window = getWindow();
|
||||
WindowManager.LayoutParams lp = window.getAttributes();
|
||||
lp.width = DensityUtil.dip2px(context, 150);
|
||||
lp.height = DensityUtil.dip2px(context, 110);
|
||||
lp.gravity = Gravity.CENTER;
|
||||
window.setAttributes(lp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置等待提示信息
|
||||
*/
|
||||
public void setLoadingMsg(String msg) {
|
||||
if (TextUtils.isEmpty(msg)) {
|
||||
return;
|
||||
}
|
||||
binding.tvMsg.setText(msg);
|
||||
}
|
||||
}
|
||||
5
basicLib/src/main/res/drawable/dialog_loading_bg.xml
Normal file
5
basicLib/src/main/res/drawable/dialog_loading_bg.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#EEEEEE"/>
|
||||
<corners android:radius="6dp" />
|
||||
</shape>
|
||||
33
basicLib/src/main/res/layout/dialog_loading.xml
Normal file
33
basicLib/src/main/res/layout/dialog_loading.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<data>
|
||||
|
||||
</data>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/dialog_loading_bg"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ProgressBar
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminateTint="#2899FC"
|
||||
android:layout_gravity="center_horizontal" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_msg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:text="加载中..."
|
||||
android:textColor="#333333"
|
||||
android:textSize="16sp" />
|
||||
</LinearLayout>
|
||||
</layout>
|
||||
3
basicLib/src/main/res/values/strings.xml
Normal file
3
basicLib/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="framework_name">basicLib</string>
|
||||
</resources>
|
||||
21
basicLib/src/main/res/values/styles.xml
Normal file
21
basicLib/src/main/res/values/styles.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!--对话框的样式-->
|
||||
<style name="LoadingDialog">
|
||||
<!--对话框背景 -->
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
<!--边框 -->
|
||||
<item name="android:windowFrame">@null</item>
|
||||
<!--没有标题 -->
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<!-- 是否浮现在Activity之上 -->
|
||||
<item name="android:windowIsFloating">true</item>
|
||||
<!--背景透明 -->
|
||||
<item name="android:windowIsTranslucent">false</item>
|
||||
<!-- 是否有覆盖 -->
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
<!--背景变暗-->
|
||||
<item name="android:backgroundDimEnabled">false</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
Reference in New Issue
Block a user