1.取得手机屏幕大小DisplayMetrics
// 取得手机屏幕大小
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
mScreenDensity = displayMetrics.density;
mScreenHeight = displayMetrics.heightPixels;
mScreenWidth = displayMetrics.widthPixels;
package com.huading.myvolley.widget;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.view.ViewGroup;
import com.huading.myvolley.R;
/**
* Translucent Bars Utils
*
* @author LHZ
* @date 16/8/8.
*/
public class StatusBarCompat {
private static final int INVALID_VAL = -1;
//Get alpha color
static int calculateStatusBarColor(int color, int alpha) {
float a = 1 - alpha / 255f;
int red = color >> 16 & 0xff;
int green = color >> 8 & 0xff;
int blue = color & 0xff;
red = (int) (red * a + 0.5);
green = (int) (green * a + 0.5);
blue = (int) (blue * a + 0.5);
return 0xff << 24 | red << 16 | green << 8 | blue;
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public static View compat(Activity activity, int statusColor) {
int color = ContextCompat.getColor(activity, R.color.colorPrimaryDark);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (statusColor != INVALID_VAL) {
color = statusColor;
}
activity.getWindow().setStatusBarColor(color);
return null;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
&& Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
if (statusColor != INVALID_VAL) {
color = statusColor;
}
View statusBarView = contentView.getChildAt(0);
if (statusBarView != null && statusBarView.getMeasuredHeight() == getStatusBarHeight(activity)) {
statusBarView.setBackgroundColor(color);
return statusBarView;
}
statusBarView = new View(activity);
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
getStatusBarHeight(activity));
statusBarView.setBackgroundColor(color);
contentView.addView(statusBarView, lp);
return statusBarView;
}
return null;
}
public static void compat(Activity activity) {
compat(activity, INVALID_VAL);
}
// 获取状态栏高度
public static int getStatusBarHeight(Context context) {
int result = 0;
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = context.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
}
3.全透明状态栏
// 全透明状态栏
protected void transparent19and20() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//透明状态栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//透明底部导航栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
}
4.兼容4.4
新建values-v19
<resources>
<style name="AppTheme" parent="AppTheme.Base">
<item name="android:windowTranslucentStatus">true</item>
</style>
</resources>
5.颜色值
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#FF03A9F4</color>
<color name="colorPrimaryDark">#FF0288D1</color>
<color name="colorAccent">#FF4081</color>
<color name="transparent">#00000000</color> <!--透明 -->
<color name="white">#FFFFFF</color> <!--白色 -->
<color name="black">#000000</color> <!--黑色 -->
<color name="background">#F2F2F2</color> <!--背景色 -->
<color name="navigationColor">#F8F8F8</color> <!--状态导航栏背景色-->
<color name="dividerColor">#EEEEEE</color> <!--二级分割线-->
<color name="divider">#DDDDDD</color> <!--分割线-->
<color name="titleColor">#999999</color> <!--导航文字-->
<color name="textColor">#333333</color> <!--文字颜色-->
<color name="text">#666666</color> <!--次文字-->
<color name="blueColor">#00AAFF</color> <!--标准蓝-->
<color name="orangeColor">#FFAB19</color> <!--标准橙-->
<color name="orange">#FB7E00</color> <!--标准深橙-->
<color name="greenColor">#5ED125</color> <!--标准绿-->
<color name="redColor">#FF4343</color> <!--标准红-->
<color name="pinkColor">#DE1E7C</color> <!--标准粉红-->
</resources>
6.标题栏
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2015 [1076559197@qq.com | tchen0707@gmail.com]
~
~ 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.
-->
<merge 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="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/common_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
</merge>
7.加载进度条
工具类LoadingDialog
package com.huading.myvolley.widget;
import android.app.Dialog;
import android.content.Context;
import android.view.Gravity;
import android.view.animation.Animation;
import android.widget.TextView;
import com.huading.myvolley.R;
public class LoadingDialog extends Dialog {
private static LoadingDialog loadingDialog = null;
public Animation animation;
public LoadingDialog(Context context) {
super(context);
}
public LoadingDialog(Context context, int theme) {
super(context, theme);
}
public static LoadingDialog createDialog(Context context) {
loadingDialog = new LoadingDialog(context, R.style.CustomProgressDialog);
loadingDialog.setContentView(R.layout.loading_dialog);
loadingDialog.getWindow().getAttributes().gravity = Gravity.CENTER;
return loadingDialog;
}
/**
* [Summary] setMessage 提示内容
*
* @param strMessage
* @return
*/
public LoadingDialog setMessage(String strMessage) {
TextView tvMsg = (TextView) loadingDialog.findViewById(R.id.progressBar_text);
if (tvMsg != null) {
tvMsg.setText(strMessage);
}
return loadingDialog;
}
}
进度条主题样式R.style.CustomProgressDialog
<resources>
<style name="AppTheme" parent="AppTheme.Base"></style>
<!-- Base application theme. -->
<style name="AppTheme.Base" parent="Theme.AppCompat.Light">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item> <!--标题栏-->
<item name="colorPrimaryDark">@color/colorPrimaryDark</item><!--状态栏-->
<item name="colorAccent">@color/colorAccent</item>
<!--隐藏ActionBar-->
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<!--进度条样式-->
<style name="CustomProgressDialog" parent="@android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowIsTranslucent">false</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
</resources>
进度条布局R.layout.loading_dialog
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="120dp"
android:layout_height="120dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:alpha="0.8"
android:background="@android:color/transparent"
android:gravity="center"
android:orientation="vertical">
<com.huading.baselhz.widget.load.CircleLoadingView
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:progress_color="@color/pinkColor" />
<TextView
android:id="@+id/progressBar_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textColor="@color/pinkColor"
android:text="正在加载..." />
</LinearLayout>
BaseProgressController
/**
* Created by LHZ on 2016/4/29.
*/
public abstract class BaseProgressController {
private View mTarget;
private List<Animator> mAnimators;
public void setTarget(View target) {
this.mTarget = target;
}
public View getTarget() {
return mTarget;
}
public int getWidth() {
return mTarget.getWidth();
}
public int getHeight() {
return mTarget.getHeight();
}
public void postInvalidate() {
mTarget.postInvalidate();
}
/**
* draw
*
* @param canvas canvas
* @param paint paint
*/
public abstract void draw(Canvas canvas, Paint paint);
public abstract List<Animator> createAnimation();
public void initAnimation() {
mAnimators = createAnimation();
}
public void setAnimationStatus(AnimStatus animStatus) {
if (mAnimators == null) {
return;
}
int count = mAnimators.size();
for (int i = 0; i < count; i++) {
Animator animator = mAnimators.get(i);
boolean isRunning = animator.isRunning();
switch (animStatus) {
case START:
if (!isRunning) {
animator.start();
}
break;
case END:
if (isRunning) {
animator.end();
}
break;
case CANCEL:
if (isRunning) {
animator.cancel();
}
break;
}
}
}
public enum AnimStatus {
START, END, CANCEL
}
}
CircleProgress
/**
*Created by LHZ on 2016/4/29.
*/
public class CircleProgress extends BaseProgressController {
public static final float SCALE=1.0f;
public static final int ALPHA=255;
float[] scaleFloats=new float[]{SCALE,
SCALE,
SCALE,
SCALE,
SCALE,
SCALE,
SCALE,
SCALE};
int[] alphas=new int[]{ALPHA,
ALPHA,
ALPHA,
ALPHA,
ALPHA,
ALPHA,
ALPHA,
ALPHA};
@Override
public void draw(Canvas canvas, Paint paint) {
float radius=getWidth()/10;
for (int i = 0; i < 8; i++) {
canvas.save();
Point point=circleAt(getWidth(),getHeight(),getWidth()/2-radius,i*(Math.PI/4));
canvas.translate(point.x,point.y);
canvas.scale(scaleFloats[i],scaleFloats[i]);
paint.setAlpha(alphas[i]);
canvas.drawCircle(0,0,radius,paint);
canvas.restore();
}
}
/**
* 圆O的圆心为(a,b),半径为R,点A与到X轴的为角α.
*则点A的坐标为(a+R*cosα,b+R*sinα)
* @param width
* @param height
* @param radius
* @param angle
* @return
*/
Point circleAt(int width,int height,float radius,double angle){
float x= (float) (width/2+radius*(Math.cos(angle)));
float y= (float) (height/2+radius*(Math.sin(angle)));
return new Point(x,y);
}
@Override
public List<Animator> createAnimation() {
List<Animator> animators=new ArrayList<>();
int[] delays= {0, 120, 240, 360, 480, 600, 720, 780, 840};
for (int i = 0; i < 8; i++) {
final int index=i;
ValueAnimator scaleAnim=ValueAnimator.ofFloat(1,0.4f,1);
scaleAnim.setDuration(1000);
scaleAnim.setRepeatCount(-1);
scaleAnim.setStartDelay(delays[i]);
scaleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
scaleFloats[index] = (float) animation.getAnimatedValue();
postInvalidate();
}
});
scaleAnim.start();
ValueAnimator alphaAnim=ValueAnimator.ofInt(255, 77, 255);
alphaAnim.setDuration(1000);
alphaAnim.setRepeatCount(-1);
alphaAnim.setStartDelay(delays[i]);
alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
alphas[index] = (int) animation.getAnimatedValue();
postInvalidate();
}
});
alphaAnim.start();
animators.add(scaleAnim);
animators.add(alphaAnim);
}
return animators;
}
final class Point{
public float x;
public float y;
public Point(float x, float y){
this.x=x;
this.y=y;
}
}
}
新建attrs
<!--进度条样式-->
<declare-styleable name="CircleLoadingView">
<attr name="progress_color" format="color" />
</declare-styleable>
8.activity管理栈
package com.huading.myvolley.utils;
import android.app.Activity;
import java.util.Stack;
/**
* Created by LHZ on 2017/3/1.
* Activity管理栈
*/
public class AppManager {
private static Stack<Activity> activityStack;
public volatile static AppManager instance = new AppManager();
private AppManager() {
activityStack = new Stack<>();
}
/**
* 添加Activity到堆栈
*/
public void addActivity(Activity activity) {
activityStack.add(activity);
}
/**
* 获取当前Activity(堆栈中最后一个压入的)
*/
public Activity currentActivity() {
try {
Activity activity = activityStack.lastElement();
return activity;
} catch (Exception e) {
return null;
}
}
/**
* 返回到指定类名的activity
*
* @param cls
*/
public void returnToActivity(Class<?> cls) {
while (activityStack.size() != 0)
if (activityStack.peek().getClass() == cls) {
break;
} else {
finishActivity(activityStack.peek());
}
}
/**
* 结束当前Activity(堆栈中最后一个压入的)
*/
public void finishActivity() {
Activity activity = activityStack.lastElement();
finishActivity(activity);
}
/**
* 结束指定的Activity
*/
public void finishActivity(Activity activity) {
if (activity != null) {
activityStack.remove(activity);
activity.finish();
}
}
/**
* 移除指定的Activity
*/
public void removeActivity(Activity activity) {
if (activity != null) {
activityStack.remove(activity);
}
}
/**
* 结束指定类名的Activity
*/
public void finishActivity(Class<?> cls) {
try {
for (Activity activity : activityStack) {
if (activity.getClass().equals(cls)) {
finishActivity(activity);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 结束所有Activity
*/
public void finishAllActivity() {
for (int i = 0, size = activityStack.size(); i < size; i++) {
if (null != activityStack.get(i)) {
activityStack.get(i).finish();
}
}
activityStack.clear();
}
/**
* 是否已经打开指定的activity
*
* @param cls
* @return
*/
public boolean isOpenActivity(Class<?> cls) {
if (activityStack != null) {
for (int i = 0, size = activityStack.size(); i < size; i++) {
if (cls == activityStack.peek().getClass()) {
return true;
}
}
}
return false;
}
}