代理模式
什么是代理模式?
代理模式就是我懒,有工作我不想做,我找别人帮我做。但是我怎么知道他能帮我做呢?所以我们要彼此了解对方,我们要实现共同的接口。
上类图
随着科技的发达,机器人越来越先进,终于有一天,机器人做的跟我们一摸一样,然后他们负责替我们做工作,我们吃喝玩乐,来我们就用代码创建两个机器人。
以下是代码:
首先是定义共同的接口,我们能做的事情,机器人也能要能做。
/**
* Created by 29028 on 2017/6/19.
*
* 自己的接口
*/
public interface ISlef {
//我能干什么
//吃
public void eat();
//工作
public void doWork();
}
接着定义两个机器人替身。
替身1号
/**
* Created by 29028 on 2017/6/19.
* 机器人替身1号 我会的他也会
*/
public class ProxyRobot1 implements ISlef {
public void eat() {
Log.d("AAA","机器人替身1号吃电");
}
public void doWork() {
Log.d("AAA","机器人替身1号帮我做工作");
}
}
替身1号
/**
* Created by 29028 on 2017/6/19.
* 机器人替身2号 我会的他也会
*/
public class ProxyRobot2 implements ISlef {
public void eat() {
Log.d("AAA","机器人替身2号吃电");
}
public void doWork() {
Log.d("AAA","机器人替身2号帮我做工作");
}
}
再接着创建我们自己
/**
* Created by 29028 on 2017/6/19.
* 真的自己
*/
public class TrueSelf implements ISlef {
private ISlef slef;
//默认让一号来
public TrueSelf(){
slef =new ProxyRobot1();
}
//设置替身 我想谁几号替我就让几号来
public void setProxy(ISlef slef){
this.slef = slef;
}
//吃东西这事还是我们自己来比较好
public void eat() {
Log.d("AAA","我悠哉悠哉的吃肉");
}
public void doWork() {
slef.doWork();
}
}
终于弄好了两个替身,下面我们看看替身的威力吧
老板去让我做事,我照着做了,老板其实不知道是谁在做。
private void doThings() {
TrueSelf self=new TrueSelf();
self.doWork();
self.eat();
}
打印结果
机器人替身1号帮我做工作
我悠哉悠哉的吃肉
老让1号替身怕他太累了
private void doThings() {
TrueSelf self=new TrueSelf();
self.setProxy(new ProxyRobot2());
self.doWork();
self.eat();
}
打印结果
机器人替身2号帮我做工作
我悠哉悠哉的吃肉
是不是美滋滋,我们总结一下,代理模式主要是使用了Java的多态,干活的是被代理类,而作为代理的我们只负责悠哉悠哉的吃肉就行了。
下面是再Android开发中的实践
我们以上篇app中的沉浸式为例,使用代理模式重构一下我们的代码。
首先定义一个公共的抽象类
abstract class Immersion {
protected final Activity activity;
protected final boolean isShowUi;
public Immersion(Activity activity, boolean isShowUi){
this.activity = activity;
this.isShowUi = isShowUi;
if(isShowUi) {
toggleHideyBar(activity);
}
}
public abstract void setStatusColor(View titleBar, @ColorRes int resId);
public abstract void setStatusPicture(View titleBar, @DrawableRes int drawableId);
public abstract void setStatusAndNaviagtion(View titleBar, View botoomBar, @ColorRes int resId );
/**
* dip 转 px
*/
protected static int dp2px(int dp,Activity activity) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dp,activity.getResources().getDisplayMetrics());
}
/**
* 开关
*/
protected static void toggleHideyBar(Activity activity) {
int newUiOptions = activity.getWindow().getDecorView().getSystemUiVisibility();
if (Build.VERSION.SDK_INT >= 14) {
newUiOptions ^= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
}
if (Build.VERSION.SDK_INT >= 16) {
newUiOptions ^= View.SYSTEM_UI_FLAG_FULLSCREEN;
}
if (Build.VERSION.SDK_INT >= 18) {
newUiOptions ^= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
}
activity.getWindow().getDecorView().setSystemUiVisibility(newUiOptions);
}
/**
* 获取状态栏的高度
*/
protected static int getStatusHeight(Activity activity){
int stastusHeight=-1;
int statusId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
if(statusId>0){
stastusHeight = activity.getResources().getDimensionPixelSize(statusId);
}
return stastusHeight==-1?dp2px(24,activity):stastusHeight;
}
/**
* 获取底部导航栏的高度
*/
protected static int getNavigationHeight(Activity activity){
int navigationHeight=-1;
int navigationId = activity.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
if(navigationId>0){
navigationHeight=activity.getResources().getDimensionPixelSize(navigationId);
}
return navigationHeight==-1?dp2px(48,activity):navigationHeight;
}
}
在定义一个适配4.4的被代理类。
class ImmersionApi19 extends Immersion {
public ImmersionApi19(Activity activity, boolean isShowUi) {
super(activity, isShowUi);
}
public void setStatusColor(View titleBar, @ColorRes int resId) {
int color;
if(resId > 0) {
color = activity.getResources().getColor(resId);
} else {
color = Color.parseColor("#FF4081");
}
int statusHeight = getStatusHeight(activity);
if(titleBar!=null){
ViewGroup.LayoutParams params = titleBar.getLayoutParams();
params.height+=statusHeight;
titleBar.setLayoutParams(params);
titleBar.setPadding(titleBar.getPaddingLeft(),
titleBar.getPaddingTop()+statusHeight,
titleBar.getPaddingRight(),
titleBar.getPaddingBottom());
titleBar.setBackgroundColor(color);
}
}
public void setStatusPicture(View titleBar, @DrawableRes int drawableId) {
Drawable drawableBg;
if(drawableId > 0) {
drawableBg = activity.getResources().getDrawable(drawableId);
} else {
drawableBg = activity.getResources().getDrawable(livesun.translucent.R.drawable.ic_launcher);
}
int statusHeight = getStatusHeight(activity);
if(titleBar != null) {
ViewGroup.LayoutParams decorView1 = titleBar.getLayoutParams();
decorView1.height += statusHeight;
titleBar.setLayoutParams(decorView1);
titleBar.setPadding(titleBar.getPaddingLeft(),
titleBar.getPaddingTop() + statusHeight,
titleBar.getPaddingRight(),
titleBar.getPaddingBottom());
titleBar.setBackground(drawableBg);
}
}
public void setStatusAndNaviagtion(View titleBar, View botoomBar, @ColorRes int resId) {
//时间原因 暂不实现
}
以及一个适配5.0的被代理类。
class ImmersionApi21 extends Immersion {
public ImmersionApi21(Activity activity, boolean isShowUi) {
super(activity, isShowUi);
}
public void setStatusColor(View titleBar, @ColorRes int resId) {
int color;
if(resId > 0) {
color = activity.getResources().getColor(resId);
} else {
color = Color.parseColor("#FF4081");
}
activity.getWindow().setStatusBarColor(color);
titleBar.setBackgroundColor(color);
}
public void setStatusPicture(View titleBar, @DrawableRes int drawableId) {
// new ImmersionApi19(activity,isShowUi).setStatusPicture(titleBar, drawableId);
View decorView = activity.getWindow().getDecorView();
int option = View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(option);
titleBar.setBackground(activity.getResources().getDrawable(drawableId));
}
public void setStatusAndNaviagtion(View titleBar, View botoomBar, @ColorRes int resId) {
//暂时不实现
}
}
接下来就是我们的代理类
public class ImmersionProxy extends Immersion {
private Immersion immersion;
public ImmersionProxy(Activity activity, boolean isShowUi) {
super(activity, isShowUi);
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.KITKAT
&&Build.VERSION.SDK_INT<Build.VERSION_CODES.LOLLIPOP
){
immersion = new ImmersionApi19(activity,isShowUi);
}
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP){
immersion=new ImmersionApi21(activity,isShowUi);
}
}
public void setStatusColor(View titleBar, @ColorRes int resId) {
immersion.setStatusColor(titleBar,resId);
}
public void setStatusPicture(View titleBar, @DrawableRes int drawableId) {
immersion.setStatusPicture(titleBar,drawableId);
}
public void setStatusAndNaviagtion(View titleBar, View botoomBar, @ColorRes int resId) {
immersion.setStatusAndNaviagtion(titleBar,botoomBar,resId);
}
}
然后,我们就可以很开心的调用了,我们不必关心是调用API19还是API21,只管在Activity中的OnCreat方法调用
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
setContentView(R.layout.activity_main);
Toolbar toolbar= (Toolbar) findViewById(R.id.toolbar);
ImmersionProxy proxy = new ImmersionProxy(this, false);
proxy.setStatusColor(toolbar,R.color.colorAccent);
}