public abstract class BaseActivity extends AppCompatActivity {
private static final String TAG = BaseActivity.class.getSimpleName();
/**
* Activity或Fragment的引用
*/
private Activity mUi;
private ConstraintLayout mRootLayout;
private View statusView;
private FrameLayout mContentContainer;
protected TopBarHolder mTopBarHolder;
private final List<ILifecycle> mLifecycleList = new ArrayList<>();
public static final String STRING_EXTRA = "STRING_EXTRA";
public static final String STRING_ARRAY_EXTRA = "STRING_ARRAY_EXTRA";
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(MyLanguageUtils.updateLanguage(newBase));
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
MyLanguageUtils.onActivityConfigurationChanged(this, newConfig);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
beforeSetContentView(savedInstanceState);
setContentView(R.layout.activity_base);
afterSetContentView(savedInstanceState);
{
mRootLayout = findViewById(R.id.rootLayout);
mContentContainer = findViewById(R.id.contentContainer);
LayoutInflater layoutInflater = getLayoutInflater();
layoutInflater.inflate(getLayoutResId(), mContentContainer, true);
{
statusView = findViewById(R.id.statusView);
ViewGroup.LayoutParams layoutParams = statusView.getLayoutParams();
layoutParams.height = StatusBarUtil.getStatusBarHeight(this);
statusView.setLayoutParams(layoutParams);
if (ScreenUtils.isFullScreen(this)) {
statusView.setVisibility(View.GONE);
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
statusView.setVisibility(View.VISIBLE);
} else {
statusView.setVisibility(View.GONE);
}
}
}
mTopBarHolder = TopBarHolder.init(this);
}
ButterKnife.bind(this, this);
attachUi(this);
//设置状态栏
setStatusBar(true, R.color.colorWhiteFFFFFF);
initViews();
mLoadingView = new LoadingView(this);
initData();
for (ILifecycle lifecycle : mLifecycleList) {
lifecycle.onCreate();
}
}
protected void beforeSetContentView(Bundle savedInstanceState) {
}
protected void afterSetContentView(Bundle savedInstanceState) {
}
protected abstract int getLayoutResId();
protected int getTitleLayoutRes() {
return R.layout.layout_title_bar;
}
public abstract void initViews();
public abstract void initData();
private final void attachUi(Activity ui) {
mUi = ui;
}
private final void detachUi() {
mUi = null;
}
/**
* 异步刷新UI界面时一定要调用此方法判断界面是否还在
*
* @return
*/
public final boolean isUiAttached() {
return mUi != null;
}
@Override
public void startActivityForResult(Intent intent, int requestCode) {
super.startActivityForResult(intent, requestCode);
overridePendingTransition(R.anim.in_from_right, R.anim.anim_no);
}
@Override
public void startActivity(Intent intent) {
super.startActivity(intent);
overridePendingTransition(R.anim.in_from_right, R.anim.anim_no);
}
@Override
public void finish() {
super.finish();
overridePendingTransition(R.anim.anim_no, R.anim.out_to_right);
}
@Override
protected void onResume() {
super.onResume();
for (ILifecycle lifecycle : mLifecycleList) {
lifecycle.onResume();
}
if (this instanceof WelcomeActivity) {
return;
}
if (!LocationBroadcastUtils.isLocationEnabled()) {
LocationBroadcastUtils.openLocation(this);
}
}
@Override
protected void onPause() {
super.onPause();
for (ILifecycle lifecycle : mLifecycleList) {
lifecycle.onPause();
}
}
@Override
protected void onStop() {
super.onStop();
for (ILifecycle lifecycle : mLifecycleList) {
lifecycle.onStop();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
for (ILifecycle lifecycle : mLifecycleList) {
lifecycle.onDestroy();
}
mLifecycleList.clear();
detachUi();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return new HideInput().dispatchTouchEvent(ev);
}
protected void setBackgroundResource(int backgroundRes) {
mRootLayout.setBackgroundResource(backgroundRes);
}
/**
* 设置Android M 以上系统状态栏的颜色
*
* @param statusBarBgRes
*/
public void setStatusBar(boolean textColorIsBlack, int statusBarBgRes) {
ImmersiveStatusBarUtils.setImmersiveStatus(getWindow(), textColorIsBlack);
setBackgroundResource(statusBarBgRes);
}
/**
* 去除状态栏全屏,一般在app的第一个界面中调用,要在{@link #setContentView(int)}方法之前调用
*/
public void setFullscreen() {
//去除状态栏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
public void changeStatusView(boolean isShow) {
if (statusView != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
statusView.setVisibility(isShow ? View.VISIBLE : View.GONE);
} else {
statusView.setVisibility(View.GONE);
}
}
}
protected final void hideTopBar() {
mTopBarHolder.mTopBarContainer.setVisibility(View.GONE);
}
protected final void hideTopBarBackButton() {
mTopBarHolder.mImageViewBack.setVisibility(View.GONE);
}
protected final void setTopBarTitle(int stringTitle) {
mTopBarHolder.mTextViewTitle.setText(stringTitle);
}
protected final void setTopBarTitle(String stringTitle) {
mTopBarHolder.mTextViewTitle.setText(stringTitle);
}
protected final TopBarHolder getTopBarHolder() {
return mTopBarHolder;
}
/**
* 点击空白地方,输入法隐藏
*/
private class HideInput {
private boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
View v = getCurrentFocus();
if (isShouldHideInput(v, ev)) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
onHideSoftInputFromWindow();
}
return BaseActivity.super.dispatchTouchEvent(ev);
}
// 必不可少,否则所有的组件都不会有TouchEvent了
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}
private void onHideSoftInputFromWindow() {
//键盘隐藏后,界面上的edittext的光标要隐藏
}
private boolean isShouldHideInput(View v, MotionEvent event) {
if (v instanceof EditText) {
int[] leftTop = {0, 0};
//获取输入框当前的location位置
v.getLocationInWindow(leftTop);
int left = leftTop[0];
int top = leftTop[1];
int bottom = top + v.getHeight();
int right = left + v.getWidth();
if (event.getX() > left && event.getX() < right
&& event.getY() > top && event.getY() < bottom) {
// 点击的是输入框区域,保留点击EditText的事件
// ((EditText) v).setCursorVisible(true);
return false;
} else {
return true;
}
}
return false;
}
/*************点击空白地方,输入法隐藏******************/
}
public void addLifecycle(ILifecycle lifecycle) {
mLifecycleList.add(lifecycle);
}
public void removeLifecycle(ILifecycle lifecycle) {
mLifecycleList.remove(lifecycle);
}
public final void showLoading(String label) {
showLoading(label, true);
}
public final void showLoading(String label, boolean cancelable) {
MyThreadUtils.doMainWork(new Runnable() {
@Override
public void run() {
if (isUiAttached()) {
if (!mLoadingView.mLoading.isShowing()) {
mLoadingView.mLoading.show(cancelable);
}
if (TextUtils.isEmpty(label)) {
mLoadingView.mLoading.label.setVisibility(View.GONE);
return;
}
mLoadingView.mLoading.label.setText(label);
mLoadingView.mLoading.label.setVisibility(View.VISIBLE);
}
}
});
}
public final void dismissLoading() {
MyThreadUtils.doMainWork(new Runnable() {
@Override
public void run() {
if (isUiAttached()) {
if (!mLoadingView.mLoading.isShowing()) {
return;
}
mLoadingView.mLoading.dismiss();
}
}
});
}
private LoadingView mLoadingView;
private static class LoadingView {
private LoadingDialog mLoading;
private LoadingView(Activity activity) {
mLoading = new LoadingDialog(activity);
}
}
@NotNull
private Intent getIntent(Class<? extends Activity> activityClass) {
return new Intent(BaseActivity.this, activityClass);
}
public final void go2NextActivityForResult(Class<? extends Activity> activityClass, Integer requestCode, String stringExtra, String[] stringArrayExtra) {
MyThreadUtils.doMainWork(new Runnable() {
@Override
public void run() {
if (isUiAttached()) {
Intent intent = getIntent(activityClass);
if (!TextUtils.isEmpty(stringExtra)) {
intent.putExtra(STRING_EXTRA, stringExtra);
}
if (stringArrayExtra != null) {
intent.putExtra(STRING_ARRAY_EXTRA, stringArrayExtra);
}
if (requestCode == null) {
startActivity(intent);
} else {
startActivityForResult(intent, requestCode);
}
}
}
});
}
public final void setNoAnim() {
overridePendingTransition(R.anim.anim_no, R.anim.anim_no);
}
public final void go2NextActivity(Class<? extends Activity> activityClass, String stringExtra) {
go2NextActivityForResult(activityClass, null, stringExtra, null);
}
public final void go2NextActivity(Class<? extends Activity> activityClass) {
go2NextActivity(activityClass, "");
}
public final void go2NextActivity(Class<? extends Activity> activityClass, String[] stringArrayExtra) {
go2NextActivityForResult(activityClass, null, null, stringArrayExtra);
}
public final void go2NextActivityForResult(Class<? extends Activity> activityClass, int requestCode) {
go2NextActivityForResult(activityClass, requestCode, null, null);
}
public final String getStringExtra() {
return getIntent().getStringExtra(STRING_EXTRA);
}
public final String[] getStringArrayExtra() {
return getIntent().getStringArrayExtra(STRING_ARRAY_EXTRA);
}
}
public abstract class BaseDialog extends Dialog {
protected ConstraintLayout mRootView;
protected View mContentView;
private boolean mMyCancelable = true;
private View.OnClickListener mMyOnClickOutsideListener;
public BaseDialog(@NonNull Context context) {
super(context, R.style.BaseDialog);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}
protected void init() {
mRootView = (ConstraintLayout) LayoutInflater.from(getContext()).inflate(getContentLayoutRes(), new ConstraintLayout(getContext()), true);
mRootView.setFitsSystemWindows(true);
mContentView = mRootView.getChildAt(0);
setContentView(mRootView);
{
setMaskColor(R.color.colorBlack9913131A);
}
{
//设置空白区域的颜色,显示内容部分不会被遮住
setMaskColor(R.color.colorBlack9913131A);
}
{
ButterKnife.bind(this, mRootView);
}
{
final Window dialogWindow = getWindow();
// 获取对话框当前的参数值
if (dialogWindow != null) {
{
WindowManager.LayoutParams layoutParams = dialogWindow.getAttributes();
layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT;
dialogWindow.setAttributes(layoutParams);
}
{
dialogWindow.setBackgroundDrawableResource(android.R.color.transparent);
}
{
//核心代码 解决了无法去除遮罩问题
dialogWindow.setDimAmount(0f);
}
}
}
ImmersiveStatusBarUtils.setImmersiveStatus(getWindow(), false);
{
mContentView.setClickable(true);
mRootView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mMyCancelable) {
dismiss();
}
if (mMyOnClickOutsideListener != null) {
mMyOnClickOutsideListener.onClick(view);
}
}
});
}
//继承类不用调用此方法
setCancelable(false);
initDialog(mRootView);
SoftKeyBoardListener softKeyBoardListener = new SoftKeyBoardListener(getWindow());
//软键盘状态监听
softKeyBoardListener.setListener(new SoftKeyBoardListener.OnSoftKeyBoardChangeListener() {
@Override
public void keyBoardShow(int height) {
//软键盘已经显示,做逻辑
if ((ScreenUtils.getScreenHeight() - mContentView.getBottom()) >= height) {
return;
}
ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) mContentView.getLayoutParams();
layoutParams.topToTop = ConstraintLayout.LayoutParams.UNSET;
layoutParams.bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID;
layoutParams.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
layoutParams.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
layoutParams.bottomMargin = height;
mContentView.setLayoutParams(layoutParams);
}
@Override
public void keyBoardHide(int height) {
//软键盘已经隐藏,做逻辑
ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) mContentView.getLayoutParams();
layoutParams.topToTop = ConstraintLayout.LayoutParams.PARENT_ID;
layoutParams.bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID;
layoutParams.startToStart = ConstraintLayout.LayoutParams.PARENT_ID;
layoutParams.endToEnd = ConstraintLayout.LayoutParams.PARENT_ID;
layoutParams.bottomMargin = 0;
mContentView.setLayoutParams(layoutParams);
}
});
}
/**
* 可以看到这里定义了一个抽象方法,这个将交由子类去实现
*
* @return
*/
public abstract int getContentLayoutRes();
protected abstract void initDialog(View view);
/**
* 设置遮罩颜色
*
* @param colorRes
*/
public void setMaskColor(int colorRes) {
mRootView.setBackgroundResource(colorRes);
}
public void setMyOnClickOutsideListener(View.OnClickListener myOnClickOutsideListener) {
mMyOnClickOutsideListener = myOnClickOutsideListener;
}
/*************点击空白地方,输入法隐藏******************/
private InputMethodManager mInputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
@Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (getCurrentFocus() != null && getCurrentFocus().getWindowToken() != null) {
mInputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
return super.onTouchEvent(event);
}
/*************点击空白地方,输入法隐藏******************/
public void show(boolean cancelable) {
mMyCancelable = cancelable;
show();
}
}
public class ImmersiveStatusBarUtils {
/**
* 沉浸式状态栏,并设置文字颜色
*
* @param window
*/
public static void setImmersiveStatus(Window window, boolean textColorIsBlack) {
if (window == null) {
return;
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return;
}
int option;
if (textColorIsBlack) {
option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
} else {
option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
}
window.getDecorView().setSystemUiVisibility(option);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.TRANSPARENT);
fitsNotchScreen(window);
}
/**
* 适配刘海屏
* Fits notch screen.
*/
private static void fitsNotchScreen(Window window) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
WindowManager.LayoutParams lp = window.getAttributes();
lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
window.setAttributes(lp);
}
}
}