红橙Darren视频笔记 builder设计模式 navigationbar 导航栏第二版

1.builder设计模式简介

builder的实际应用的典型案例有AlertDialog和OKHttp

例如

    // AlertDialog
	AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this)
        .setTitle("标题")
        .setNegativeButton("取消", (dialog, which) -> {
            dialog.dismiss();
            Toast.makeText(MainActivity.this, "点击了取消", Toast.LENGTH_SHORT).show();
        })
        .setPositiveButton("确定", (dialog, which) -> Toast.makeText(MainActivity.this, "点击了确定", Toast.LENGTH_SHORT).show())
        .setCancelable(false)
        .setIcon(R.drawable.ic_launcher_background)
        .setMessage("这是消息这是消息这是消息这是消息")
        .setView(button)
        .create();
    alertDialog.show();

	// OKhttp
    private void doOKHttpGet() {
        Runnable runnable = () -> {
            String response = "";
            try {
                response = getRequest("https://raw.github.com/square/okhttp/master/README.md");
            } catch (IOException e) {
                Log.d(TAG, e.getMessage());
                e.printStackTrace();
            }
            Log.d(TAG, "doOKHttpGet: " + response);
        };
        Thread thread = new Thread(runnable);
        thread.start();
    }

    String getRequest(String url) throws IOException {
        Request request = new Request.Builder()
                .url(url)
                .build();
        try (Response response = client.newCall(request).execute()) {
            return response.body().string();
        }
    }

建造者模式通常用于创建较复杂对象,例如上面两种情况 都是参数有很多 且有参数是可有可无的情况

之前写过一些类似的文章

下面这篇是利用builder设计模式模仿Android AlertDialog写的自己自定义的Dialog

https://blog.csdn.net/u011109881/article/details/114336196 

下面这篇是利用builder设计模式 进一步写导航条

https://blog.csdn.net/u011109881/article/details/114548479 

上面的两篇类结构比较简单 还有稍微复杂的建造者demo

https://blog.csdn.net/u011109881/article/details/57182402

2.导航栏升级版 

利用builder设计模式写导航栏

2.1 接口类INavigation

public interface INavigation {
    void createNavigationBar();

    void attachNavigationParams();

    //TextView findViewById(int viewId);

    void attachParent(View navigationBar, ViewGroup parent);

    //AbsNavigationBar.Builder getBuilder();
}

2.2 抽象类AbsNavigationBar

public abstract class AbsNavigationBar <B extends AbsNavigationBar.Builder> implements INavigation {
    private final B mBuilder;
    private View mNavigationBar;

    protected AbsNavigationBar(B builder) {
        this.mBuilder = builder;
        createNavigationBar();
    }

    @Override
    public void createNavigationBar() {
        mNavigationBar = LayoutInflater.from(mBuilder.mContext)
                .inflate(mBuilder.mLayoutId, mBuilder.mParent, false);// 实际上false改成true可以不用调用下面attachParent的方法
        // 将布局添加到父容器
        attachParent(mNavigationBar, mBuilder.mParent);
        // 绑定参数到Builder内部
        attachNavigationParams();
    }

    // 利用AbsNavigationBar引用绑定参数到AbsNavigationBar内部类Builder
    @Override
    public void attachNavigationParams() {
        // 设置文本
        Map<Integer, CharSequence> textMaps = mBuilder.mTextMaps;
        for (Map.Entry<Integer, CharSequence> entry : textMaps.entrySet()) {
            TextView textView = findViewById(entry.getKey());
            if (textView == null) {
                throw new IllegalArgumentException("TextView should not be null");
            }
            textView.setText(entry.getValue());
        }
        // 设置点击事件
        Map<Integer, View.OnClickListener> clickListenerMaps = mBuilder.mClickListenerMaps;
        for (Map.Entry<Integer, View.OnClickListener> entry : clickListenerMaps.entrySet()) {
            View view = findViewById(entry.getKey());
            if (view == null) {
                throw new IllegalArgumentException("view should not be null");
            }
            view.setOnClickListener(entry.getValue());
        }
    }

    @Override
    public void attachParent(View navigationBar, ViewGroup parent) {
        parent.addView(navigationBar, 0);
    }

    // 返回泛型类型 前面的T是泛型声明 后面的T是返回类型
    protected  <T extends View> T findViewById(int viewId) {
        return mNavigationBar.findViewById(viewId);
    }

    protected B getBuilder() {
        return mBuilder;
    }


    /**
     * 构建类 主要任务是存储参数
     */
    public static abstract class Builder<B extends Builder> {// 类泛型 里面用到泛型B 继承自当前的内部类builder
        public Context mContext;
        public int mLayoutId;
        public ViewGroup mParent;
        public Map<Integer, CharSequence> mTextMaps;
        public Map<Integer, View.OnClickListener> mClickListenerMaps;

        public Builder(Context context, int layoutId, ViewGroup parent) {
            this.mContext = context;
            this.mLayoutId = layoutId;
            this.mParent = parent;
            this.mTextMaps = new HashMap<>();
            this.mClickListenerMaps = new HashMap<>();
        }

        // 创建NavigationBar
        public abstract AbsNavigationBar create();

        // 利用builder设置文本
        public B setText(int viewId, String text) {
            mTextMaps.put(viewId, text);
            return (B) this;
        }

        // 利用builder设置点击事件
        public B setOnClickListener(int viewId, View.OnClickListener clickListener) {
            mClickListenerMaps.put(viewId, clickListener);
            return (B) this;
        }
    }
}

2.3 具体实现类1 NavigationBar

public class NavigationBar extends AbsNavigationBar{
    protected NavigationBar(Builder builder) {
        super(builder);
    }

    public static class Builder extends AbsNavigationBar.Builder<NavigationBar.Builder> {// 这里的泛型覆盖父类中的泛型(父类中泛化 子类中具现) 使得setText setOnClickListener返回的B为NavigationBar.Builder
        public Builder(Context context, int layoutId, ViewGroup parent) {
            super(context, layoutId, parent);
        }

        @Override
        public NavigationBar create() {
            return new NavigationBar(this);
        }
    }
}

2.4 具体实现类2 DefaultNavigationBar

public class DefaultNavigationBar extends AbsNavigationBar<DefaultNavigationBar.Builder>{

    protected DefaultNavigationBar(Builder builder) {
        super(builder);
    }

    @Override
    public void attachNavigationParams() {
        super.attachNavigationParams();
        TextView leftView = findViewById(R.id.back_tv);
        leftView.setVisibility(getBuilder().mLeftVisible);
        // 这里能够访问到mLeftVisible 因为getBuilder返回的是泛型类型
        // DefaultNavigationBar extends AbsNavigationBar<DefaultNavigationBar.Builder> 具现化了B为DefaultNavigationBar.Builder
        // 因此 getBuilder()返回的是DefaultNavigationBar.Builder 能够调用mLeftVisible变量
    }

    public static class Builder extends AbsNavigationBar.Builder<DefaultNavigationBar.Builder>{
        public int mLeftVisible = View.VISIBLE;

        public Builder(Context context, ViewGroup parent) {
            super(context, R.layout.defualt_navigation_bar, parent);
        }

        public Builder setLeftText(String text){
            setText(R.id.back_tv,text);
            return this;
        }

        public Builder setLeftClickListener(View.OnClickListener clickListener){
            setOnClickListener(R.id.back_tv,clickListener);
            return this;
        }

        public Builder hideLeftText() {
            mLeftVisible = View.INVISIBLE;
            return this;
        }

        @Override
        public DefaultNavigationBar create() {
            return new DefaultNavigationBar(this);
        }
    }
}

2.5 使用到的布局

//activity_main

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/view_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"/>

</RelativeLayout>


//defualt_navigation_bar
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:id="@+id/view_root"
    android:background="#ccc"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/back_tv"
        android:textColor="@android:color/white"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="default bar" />

</androidx.appcompat.widget.Toolbar>


//navigationbar
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/design_default_color_secondary"
    android:paddingTop="10dp"
    android:paddingBottom="10dp"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/left_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:textColor="@color/white" />

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="Hello World!"
        android:textColor="@color/white" />

    <ImageView
        android:id="@+id/right_icon"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_alignParentEnd="true"
        android:src="@drawable/ic_launcher_background" />
</RelativeLayout>

另外注意需要将application的主题设置为android:theme="@style/Theme.Design.Light.NoActionBar"

课程里面说是导航栏的升级版,但个人感觉不出哪里升级了- -! 要说有变化的化 主要是用到了一些泛型在继承上面的一些高级用法,需要多花时间琢磨琢磨

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值