android 使用Builder设计模式,设计ToolBar

来源:互联网 发布:方舟生存进化最终优化 编辑:程序博客网 时间:2024/06/05 14:25

  • 使用Builder设计模式设计ToolBar
    • Builder设计模式解析
      • 最典型的代码示例
        • NotificationCompatBuilder
        • AlertDialogBuilder
      • Builder设计模式的特点
        • 参数化
        • 可维护性强
    • ToolBar的设计抽象化
      • 接口抽象toolbar的规范public interface INavigation
      • 抽象并实现INavigationpublic abstract class AbsNavigation
      • 搭建toolbar布局框架abstract class DefaultNavigation多个子类功能继承此父类功能需求就可以多变
      • 主页toolbar的实现HomeNavigation
      • HomeNavigation的调用即实例化
      • 主页toolbar实现效果
    • 布局代码就不给了

使用Builder设计模式,设计ToolBar

Builder设计模式解析

android也有不地方采用了Builder设计模式的,比如NotificationCompat.Builder和AlertDialog.Builder就采用了Builder的设计模式

最典型的代码示例

NotificationCompat.Builder

NotificationCompat.Builder mBuilder =        new NotificationCompat.Builder(this)        .setSmallIcon(R.drawable.notification_icon)        .setContentTitle("My notification")        .setContentText("Hello World!");// Creates an explicit intent for an Activity in your appIntent resultIntent = new Intent(this, ResultActivity.class);// The stack builder object will contain an artificial back stack for the// started Activity.// This ensures that navigating backward from the Activity leads out of// your application to the Home screen.TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);// Adds the back stack for the Intent (but not the Intent itself)stackBuilder.addParentStack(ResultActivity.class);// Adds the Intent that starts the Activity to the top of the stackstackBuilder.addNextIntent(resultIntent);PendingIntent resultPendingIntent =        stackBuilder.getPendingIntent(            0,            PendingIntent.FLAG_UPDATE_CURRENT        );mBuilder.setContentIntent(resultPendingIntent);NotificationManager mNotificationManager =    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);// mId allows you to update the notification later on.mNotificationManager.notify(mId, mBuilder.build());

AlertDialog.Builder

AlertDialog.Builder builder2=new AlertDialog.Builder(getActivity(),R.style.AppTheme_NoActionBar);        builder2.setTitle("警告")        .setMessage("你确定删除吗")        new DialogInterface.OnClickListener() {            @Override            public void onClick(DialogInterface dialog,             int which) {                ToastUtil.showToast(getActivity(),"你点击了取消");            }        })         .setPositiveButton("确定",          new DialogInterface.OnClickListener() {                    @Override                    public void onClick(DialogInterface dialog,                     int which) {                        ToastUtil.showToast(getActivity(),                        "你点击了确定");                    }          }) .create().show();

Builder设计模式的特点

参数化

AlertDialog.Builder里面会实例一个AlertController.AlertParams,里面包含大部分,创建AlertDialog的参数,实现功能的参数化

public Builder(Context context, int themeResId) { P = new AlertController.AlertParams(new ContextThemeWrapper(context, resolveDialogTheme(context, themeResId)));        }

可维护性强

由于Builder设计模式的参数,达到功能的多变,可维护性就变得很强
例如:可以 调用setMessage(“你确定删除吗”),也可以去掉

ToolBar的设计,抽象化

接口抽象toolbar的规范public interface INavigation

/** * 所有Toolbar的规范 * 抽象一个Toolbar *  * Created by 辉神 on 2016/8/10. */public interface INavigation {    /**     * 定义布局(返回布局id)     * @return     */    public int bindLayoutId();    /**     * 创建和绑定布局     */    public void build();}

抽象并实现INavigation——public abstract class AbsNavigation

/** * 再次抽象Toolbar * -只要是app的开发,都会有布局的创建和绑定 * -再次抽象,是为了,下次使用时,不用再次创建布局和绑定 * Created by 辉神 on 2016/8/10. */public abstract class AbsNavigation<P extends AbsNavigation.NavigationParams> implements INavigation {    /**     *     设置一个默认LayoutId,默认为0     */    private static final  int DEFAULT_LAYOUT_ID=0;    private P params;    private View contentView;    public AbsNavigation(P params) {        this.params = params;    }    public P getParams() {        return  params;    }    @Override    public int bindLayoutId() {        return DEFAULT_LAYOUT_ID;    }    @Override    public void build() {        //创建和绑定布局        if (contentView==null)        contentView = bindParent(bindLayoutId(), ((NavigationParams)getParams()).parent);    }    /**     * 方便子类使用     * @param id     * @return     */    public View findLayoutById(int id){        return contentView!=null?contentView.findViewById(id):null;    }    public String getString(int id){        return contentView.getContext().getResources().getString(id);    }    public View bindParent(int id, ViewGroup parent) {        //先要判断这个id是否为0        if (id==DEFAULT_LAYOUT_ID){            return null;        }        View childView = ((NavigationParams)getParams()).inflater.inflate(id, parent,false);        return bindParent(childView,parent);    }    public View bindParent(View childView, ViewGroup parent) {        ViewGroup viewParent= (ViewGroup) childView.getParent();        //如果他原来有一个爸爸了,就先把它爸爸干掉        if(viewParent!=null){            viewParent.removeView(childView);        }        //添加我们的爸爸给这个视图,因为一个视图不可能有两个爸爸        parent.addView(childView,0);        //将爸爸返回        return parent;    }    /**     * Builder设计模式,所有Toolbar都必须有的参数----------参数集(参数类)     */    public static class NavigationParams{        private Context context;//上下文对象,用于加载布局视图        private ViewGroup parent;//每一个布局视图都有一个爸爸        private LayoutInflater inflater;        public NavigationParams(Context context, ViewGroup parent) {            this.context = context;            this.parent = parent;            inflater=inflater.from(context);        }    }    /**     * 创建Toolbar     */    public abstract static class Builder{        public Builder(Context context,ViewGroup parent) {        }        /**         * 创建Toolbar         * @return         */        public abstract INavigation create();    }}

搭建toolbar布局框架——abstract class DefaultNavigation(多个子类(功能)继承此父类,功能需求就可以多变)

/** * 左中右场场景, * 也就是先设置左中右的布局,子类可以实现更多内容 * Created by 辉神 on 2016/8/11. */public abstract class DefaultNavigation<P extends AbsNavigation.NavigationParams> extends AbsNavigation<P> {    public DefaultNavigation(P params) {        super(params);    }    @Override    public int bindLayoutId() {        return R.layout.navigation_default;    }    @Override    public void build() {        super.build();//一定要super,因为要绑定左中右的父容器        //初始化父容器,布局框架        LinearLayout ll_left= (LinearLayout) findLayoutById(R.id.ll_left);        LinearLayout ll_center= (LinearLayout) findLayoutById(R.id.ll_center);        LinearLayout ll_right= (LinearLayout) findLayoutById(R.id.ll_right);        //以下方法都是抽象,显然,子类可以任意定义布局,达到动态改变,方便维护        //绑定布局也就是,将子布局添加到当前这个“左中右场景”中来        bindParent(bindLeftLayoutId(),ll_left);        bindParent(bindCenterLayoutId(),ll_center);        bindParent(bindRightLayoutId(),ll_right);        //初始化子布局        initLeftLayout(ll_left);        initCenterLayout(ll_center);        initRightLayout(ll_right);    }    /**     *返回左边布局ID—— 用于子布局(待子类实现)     * @return ID     */    public abstract int bindLeftLayoutId();    /**     * 返回中间布局ID—— 用于子布局(待子类实现)     * @return ID     */    public abstract int bindCenterLayoutId();    /**     * 返回右边布局ID—— 用于子布局(待子类实现)     * @return ID     */    public abstract int bindRightLayoutId();    /**     * 初始化左边的布局—— 用于子布局(待子类实现)     * @param view     * @return     */    public abstract void initLeftLayout(View view);    /**     * 初始化中间的布局—— 用于子布局(待子类实现)     * @param view     * @return     */    public abstract void initCenterLayout(View view);    /**     * 初始化右边的布局—— 用于子布局(待子类实现)     * @param view     * @return     */    public abstract void initRightLayout(View view);}

主页toolbar的实现——HomeNavigation

/** * 默认的主页toolbar实现 * Created by 辉神 on 2016/8/11. */public class HomeNavigation extends DefaultNavigation<HomeNavigation.HomeNavigationParams> {    public HomeNavigation(HomeNavigationParams params) {        super(params);    }    /**     * 设置默认主页的参数     */    public static class HomeNavigationParams extends AbsNavigation.NavigationParams{        public int leftImageRes;        public int centerTitleRes;        public int rightImageRes;        public int rightTextRes;        public View.OnClickListener leftOnclickListener;        public View.OnClickListener rightOnClickListener;        public HomeNavigationParams(Context context, ViewGroup parent) {            super(context, parent);        }    }    /**     * 构建我们的Toolbar     * @return     */    public static class Builder extends AbsNavigation.Builder{        private HomeNavigationParams p;        public Builder(Context context, ViewGroup parent) {            super(context, parent);            this.p=new HomeNavigationParams(context,parent);        }        /**         *  设置左边的图片         */        public Builder setLeftImageRes(int leftImageRes){            this.p.leftImageRes=leftImageRes;            return this;        }        /**         * 设置中间标题         * @param centerTitleRes         * @return         */        public Builder setCenterTitleRes(int centerTitleRes){            this.p.centerTitleRes=centerTitleRes;            return this;        }        /**         * 设置右边图片         * @param rightImageRes         * @return         */        public Builder setRightImageRes(int rightImageRes){            this.p.rightImageRes=rightImageRes;            return this;        }        /**         * 设置右边文字         * @param rightTextRes         * @return         */        public Builder setRightTextRes(int rightTextRes){            this.p.rightTextRes=rightTextRes;            return this;        }        /**         * 设置左边监听事件         * @param leftOnclickListener         * @return         */        public Builder setLeftOnclickListener(View.OnClickListener leftOnclickListener){            this.p.leftOnclickListener=leftOnclickListener;            return this;        }        /**         * 设置右边监听事件         * @param rightOnClickListener         * @return         */        public Builder setRightOnClickListener(View.OnClickListener rightOnClickListener){            this.p.rightOnClickListener=rightOnClickListener;            return this;        }        /**         * <p>这个方法被调用了之后,还没有结束,还需要调用接口中的build()方法</p>         * <p>HomeNavigation的是上层父类,是INavigation的实现类,</p>         * <p>所以当前INavigation的build()方法被调用时,也就相当于接口回调了,builder设计模式也就完成</p>         * <p>用户还需要再调用最高层接口,已经设计好的方法build()方法</p>         * <p>这个builder设计模式简直屌炸天</p>         * @return         */        @Override        public INavigation create() {            return new HomeNavigation(p);        }    }    @Override    public int bindLayoutId() {        return super.bindLayoutId();    }    @Override    public int bindLeftLayoutId() {        return R.layout.navigation_default_left;    }    @Override    public int bindCenterLayoutId() {        return R.layout.navigation_default_center;    }    @Override    public int bindRightLayoutId() {        return R.layout.navigation_home_right;    }    @Override    public void initLeftLayout(View view) {        ImageView iv_default_left = (ImageView) view.findViewById(R.id.iv_default_left);        iv_default_left.setImageResource(getParams().leftImageRes);        iv_default_left.setOnClickListener(getParams().leftOnclickListener);    }    @Override    public void initCenterLayout(View view) {        TextView tv_default_center = (TextView) view.findViewById(R.id.tv_default_center);        tv_default_center.setText(getString(getParams().centerTitleRes));    }    @Override    public void initRightLayout(View view) {        TextView tv_home_right = (TextView) view.findViewById(R.id.tv_home_right);        tv_home_right.setText(getString(getParams().rightTextRes));        tv_home_right.setOnClickListener(getParams().rightOnClickListener);        ImageView iv_home_right= (ImageView) view.findViewById(R.id.iv_home_right);        iv_home_right.setImageResource(getParams().rightImageRes);        //启动金币动画        AnimationDrawable animationDrawable= (AnimationDrawable) iv_home_right.getBackground();        animationDrawable.start();    }}

HomeNavigation的调用,即实例化

private void initNavigation(View contentView) {HomeNavigation.Builder builder=new HomeNavigation.Builder(getActivity(), (ViewGroup) contentView);        builder.setLeftImageRes(R.mipmap.apk_all_top_nav)                .setCenterTitleRes(R.string.tabbar_home_text)                .setRightTextRes(R.string.nav_sign_in)                .setRightImageRes(R.drawable.anim_sign_coin)                .setLeftOnclickListener(                new View.OnClickListener() {                    @Override                    public void onClick(View v) {                     ToastUtil .showToast(getActivity(),                     "点击了菜单");                    }                })                .setRightOnClickListener                (new View.OnClickListener() {                    @Override                    public void onClick(View v) {                        ToastUtil.showToast(getActivity(),                        "点击了签到");                    }                })                .create().build();    }

主页toolbar实现效果

这里写图片描述

布局代码就不给了

0 0
原创粉丝点击