zoukankan      html  css  js  c++  java
  • android 使用Builder设计模式,设计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 app
    Intent 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 stack
    stackBuilder.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实现效果

    这里写图片描述

    布局代码就不给了

    关注我
  • 相关阅读:
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    别傻傻不知道 == 和 equals 的区别【面试系列】
    Spring Boot(九):定时任务
  • 原文地址:https://www.cnblogs.com/zengmianhui/p/12634087.html
Copyright © 2011-2022 走看看