Android 封装统一样式的标题栏(二)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40543575/article/details/80042183

这里写图片描述
首先,是不是很丑,哈哈,图片忘了放在哪里了,而且,我又加上了设置字体透明度和大小的方法,所以,性能足够用了!

小编还是法子肺腑的感慨啊,自定义View真的是个好东西啊,太牛掰了!

废话不多说,用代码代替我说话吧!

一.自定义View布局

既然是自定义view,少不了自定义布局

<?xml version = "1.0" encoding = "utf-8" ?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">

    <ImageView
        android:id="@+id/left_image"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_centerVertical="true"
        android:layout_marginLeft="10dp"
        android:minHeight="20dp"
        android:minWidth="20dp" />

    <TextView
        android:id="@+id/left_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginLeft="5dp"
        android:layout_toRightOf="@+id/left_image"
        android:gravity="center"
        android:minHeight="45dp"
        android:text="left" />

    <TextView
        android:id="@+id/mid_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:gravity="center"
        android:minHeight="45dp"
        android:text="mid"
        android:textSize="17sp" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:gravity="center"
        android:minHeight="45dp"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/right_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="5dp"
            android:layout_toLeftOf="@+id/right_image"
            android:gravity="center"
            android:minHeight="45dp"
            android:text="right" />

        <ImageView
            android:id="@+id/right_image"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:minHeight="20dp"
            android:minWidth="20dp" />
    </LinearLayout>
</merge>

这里,运行就出来了,你可以直接在布局中设置默认的图标哈

二.attrs.xml

<?xml version="1.0" encoding="utf-8" ?>
<resources>
    <declare-styleable name="CircleImageView">
        <attr name="radius" format="dimension|reference" />
        <attr name="boder_width" format="dimension|reference" />
        <attr name="border_height" format="dimension|reference" />
        <attr name="image_resource" format="reference" />
    </declare-styleable>

    <declare-styleable name="CustomNavigatorBar">
        <attr name="titleBarBackground" format="reference|color" />
        <attr name="leftImage" format="reference" />
        <attr name="leftImageVisiable" format="boolean" />
        <attr name="leftText" format="string|reference" />
        <attr name="leftTextVisibale" format="boolean" />
        <attr name="leftTextFontSize" format="dimension|reference" />
        <attr name="leftTextColor" format="color|reference" />
        <attr name="midText" format="string|reference" />
        <attr name="midTextVisiable" format="boolean" />
        <attr name="midTextFontSize" format="dimension|reference" />
        <attr name="midTextFontColor" format="color|reference" />
        <attr name="rightText" format="string|reference" />
        <attr name="rightTextVisible" format="boolean" />
        <attr name="rightTextFontSize" format="dimension|reference" />
        <attr name="rightTextColor" format="color|reference" />
        <attr name="rightImage" format="reference" />
        <attr name="rightImageVisible" format="boolean" />
    </declare-styleable>
</resources>

主要是对一些属性的定义和设置

三.重磅来袭

public class TitleNavigatorBar extends RelativeLayout implements View.OnClickListener {

    private ImageView leftImage;
    private TextView leftText;
    private TextView midText;
    private ImageView rightImage;
    private TextView rightText;
    private OnCustomClickListener customClickListener;

    public TitleNavigatorBar(Context context) {
        this(context, null);
    }

    public TitleNavigatorBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TitleNavigatorBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        iniView(context);
        /**
         * 两种初始化的不同,请看下面注释讲解
         */
        initOneType(context, attrs);//第一种初始化
        //initTwoType(context, attrs);//第二种初始化
    }

    private void iniView(Context context) {
        View view = LayoutInflater.from(context).inflate(R.layout.custom_title_bar, this, true);
        leftImage = (ImageView) view.findViewById(R.id.left_image);
        leftText = (TextView) view.findViewById(R.id.left_text);
        midText = (TextView) view.findViewById(R.id.mid_text);
        rightText = (TextView) view.findViewById(R.id.right_text);
        rightImage = (ImageView) view.findViewById(R.id.right_image);
    }

    /**
     * 有兴趣的请参考鸿洋大神的自定义讲解
     * <p>
     * 初始化属性值:这种写法,不管你在布局中有没有使用该属性,都会执行getXXX方法赋值
     * 假设一个场景:
     * private int attr_mode = 1;//默认为1
     * //然后你在写getXXX方法的时候,是这么写的:
     * attr_mode = array.getInt(i, 0);
     * <p>
     * 可能你的自定义属性有个默认的值,然后你在写赋值的时候,一看是整形,就默默的第二个参数就给了个0,
     * 然而用户根本没有在布局文件里面设置这个属性,你却在运行时将其变为了0(而不是默认值),而第二种就不存在这个问题。
     * 当然这个场景可以由规范的书写代码的方式来避免,(把默认值提取出来,都设置对就好了)。
     * <p>
     * 场景二:
     * <p>
     * 其实还有个场景,假设你是继承自某个View,父类的View已经对该成员变量进行赋值了,然后你这边需要根据用户的设置情况,
     * 去更新这个值,第一种写法,如果用户根本没有设置,你可能就将父类的赋值给覆盖了。
     *
     * @param context
     * @param attrs
     */
    private void initTwoType(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomNavigatorBar);
        if (null != typedArray) {
            Drawable leftDrawable = typedArray.getDrawable(R.styleable.CustomNavigatorBar_leftImage);
            leftImage.setImageDrawable(leftDrawable);

            boolean leftImageVisible = typedArray.getBoolean(R.styleable.CustomNavigatorBar_leftImageVisiable, false);
            if (leftImageVisible) {
                leftImage.setVisibility(View.VISIBLE);
            } else {
                leftImage.setVisibility(View.GONE);
            }
            typedArray.recycle();
        }
    }

    /**
     * 注:如果switch报错,请改为if-else
     * 初始化属性值:这种写法,只有在布局中设置了该属性值后,才会调用getXXX()方法赋值
     *
     * @param context
     * @param attrs
     */
    private void initOneType(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomNavigatorBar);
        int totalAttributes = typedArray.getIndexCount();
        for (int i = 0; i < totalAttributes; i++) {
            int index = typedArray.getIndex(i);
            switch (index) {
                case R.styleable.CustomNavigatorBar_leftImage:
                    leftImage.setImageDrawable(typedArray.getDrawable(index));
                    break;
                case R.styleable.CustomNavigatorBar_leftImageVisiable:
                    getVisible(typedArray, leftImage, index);
                    break;
                case R.styleable.CustomNavigatorBar_leftText:
                    leftText.setText(typedArray.getString(index));
                    break;
                case R.styleable.CustomNavigatorBar_leftTextFontSize:
                    leftText.setTextSize(typedArray.getDimensionPixelSize(index, (int) sp2px(context, 16)));
                    break;
                case R.styleable.CustomNavigatorBar_leftTextColor:
                    leftText.setTextColor(typedArray.getColor(index, Color.WHITE));
                    break;
                case R.styleable.CustomNavigatorBar_leftTextVisibale:
                    getVisible(typedArray, leftText, index);
                    break;
                case R.styleable.CustomNavigatorBar_midText:
                    midText.setText(typedArray.getString(index));
                    break;
                case R.styleable.CustomNavigatorBar_midTextVisiable:
                    getVisible(typedArray, midText, index);
                    break;
                case R.styleable.CustomNavigatorBar_midTextFontSize:
                    midText.setTextSize(typedArray.getDimensionPixelSize(index, (int) sp2px(context, 18)));
                    break;
                case R.styleable.CustomNavigatorBar_midTextFontColor:
                    midText.setTextColor(typedArray.getColor(index, Color.WHITE));
                case R.styleable.CustomNavigatorBar_rightImage:
                    rightImage.setImageDrawable(typedArray.getDrawable(index));
                    break;
                case R.styleable.CustomNavigatorBar_rightImageVisible:
                    getVisible(typedArray, rightImage, index);
                    break;
                case R.styleable.CustomNavigatorBar_rightText:
                    rightText.setText(typedArray.getString(index));
                    break;
                case R.styleable.CustomNavigatorBar_rightTextFontSize:
                    rightText.setTextSize(typedArray.getDimensionPixelSize(index, (int) sp2px(context, 16)));
                    break;
                case R.styleable.CustomNavigatorBar_rightTextColor:
                    rightText.setTextColor(typedArray.getColor(index, Color.WHITE));
                    break;
                case R.styleable.CustomNavigatorBar_rightTextVisible:
                    getVisible(typedArray, rightText, index);
                    break;
                case R.styleable.CustomNavigatorBar_titleBarBackground:
                    int titleBarBackgroundColor = typedArray.getColor(index, Color.GREEN);
                    setBackgroundColor(titleBarBackgroundColor);
                    break;
            }
        }
        typedArray.recycle();
    }

    /**
     * 用来隐藏显示View,只有gone 和 visible两种情况,因为inVisible感到在这里用不到,就没有封装
     *
     * @param typedArray
     * @param view
     * @param index
     */
    private void getVisible(TypedArray typedArray, View view, int index) {
        boolean visible = typedArray.getBoolean(index, false);
        if (visible) {
            view.setVisibility(View.VISIBLE);
        } else {
            view.setVisibility(View.GONE);
        }
    }

    private void setVisible(View view, boolean visible) {
        if (visible) {
            view.setVisibility(View.VISIBLE);
        } else {
            view.setVisibility(View.GONE);
        }
    }

    /**
     * 两种监听只能使用其中一种,不能同时使用
     * <p>
     * ----------------------------第一种点击监听开始处----------------------------------------
     *
     * @param clickListener
     */
    public void setLeftImageOnClickListener(OnClickListener clickListener) {
        if (null != clickListener) {
            leftImage.setOnClickListener(clickListener);
        }
    }

    public void setLeftTextOnClickListener(OnClickListener clickListener) {
        if (null != clickListener) {
            leftText.setOnClickListener(clickListener);
        }
    }

    public void setRightImageOnClickListener(OnClickListener clickListener) {
        if (null != clickListener) {
            rightImage.setOnClickListener(clickListener);
        }
    }

    public void setRightTextOnClickListener(OnClickListener clickListener) {
        if (null != clickListener) {
            rightText.setOnClickListener(clickListener);
        }
    }

    /**
     * ----------------------------第二种点击监听开始处----------------------------------------
     *
     * @return
     */
    public void addViewClickListener(OnCustomClickListener listener) {
        leftText.setOnClickListener(this);
        leftImage.setOnClickListener(this);
        rightImage.setOnClickListener(this);
        rightText.setOnClickListener(this);
        this.customClickListener = listener;
    }

    public interface OnCustomClickListener {
        void onClickListener(View rootView);
    }

    @Override
    public void onClick(View view) {
        customClickListener.onClickListener(view);
    }

    /**
     * ----------------------------第二种点击监听结束处----------------------------------------
     *
     * @return
     */

    public ImageView getLeftImageView() {
        return leftImage;
    }

    public ImageView getRightImage() {
        return rightImage;
    }

    public TextView getLeftText() {
        return leftText;
    }

    public TextView getRightText() {
        return rightText;
    }

    public TextView getMidText() {
        return midText;
    }

    /**
     * 设置textView的标题内容
     *
     * @param textDescribe
     */
    public void setLeftText(String textDescribe) {
        if (null != textDescribe) {
            leftText.setText(textDescribe);
        }
    }

    public void setTitleText(String textDescribe) {
        if (null != textDescribe) {
            midText.setText(textDescribe);
        }
    }

    public void setRightText(String textDescribe) {
        if (null != textDescribe) {
            rightText.setText(textDescribe);
        }
    }

    /**
     * 设置textView的字体颜色
     *
     * @param textColor
     */
    public void setLeftTextColor(int textColor, @FloatRange(from = 0.0, to = 1.0) float alpha) {
        int i = mixtureColor(textColor, alpha);
        leftText.setTextColor(i);
    }

    public void setMidTextColor(int textColor, @FloatRange(from = 0.0, to = 1.0) float alpha) {
        int i = mixtureColor(textColor, alpha);
        midText.setTextColor(i);
    }

    public void setRightTextColor(int textColor, @FloatRange(from = 0.0, to = 1.0) float alpha) {
        int i = mixtureColor(textColor, alpha);
        rightText.setTextColor(i);
    }

    /**
     * 设置title栏背景色
     *
     * @param color
     */
    public void setTitleBarBackground(int color) {
        setBackgroundColor(color);
    }

    /**
     * 设置左图标
     *
     * @param res
     */
    public void setLeftDrawable(int res) {
        if (leftImage != null) {
            leftImage.setImageResource(res);
        }
    }

    /**
     * 设置右图标
     *
     * @param res
     */
    public void setRightDrawable(int res) {
        if (rightImage != null) {
            rightImage.setImageResource(res);
        }
    }

    //设置右标题大小
    public void setRightTextSize(int size) {
        if (rightText != null) {
            rightText.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
        }
    }

    //设置左标题大小
    public void setLeftTextSize(int size) {
        if (leftText != null) {
            leftText.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
        }
    }

    //设置标题大小
    public void setTitleTextSize(int size) {
        if (midText != null) {
            midText.setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
        }
    }

    /**
     * 左右控件的隐藏显示
     *
     * @param visible
     */
    public void setLeftImageVisible(boolean visible) {
        setVisible(leftImage, visible);
    }

    public void setLeftTextVisible(boolean visible) {
        setVisible(leftText, visible);
    }

    public void setRightImageVisible(boolean visible) {
        setVisible(rightImage, visible);
    }

    public void setRightTextVisible(boolean visible) {
        setVisible(rightText, visible);
    }


    private float sp2px(Context context, float defaultVal) {
        float applyDimension = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, defaultVal, context.getResources().getDisplayMetrics());
        return applyDimension;
    }

    private float dp2px(Context context, float defaultVal) {
        float applyDimension = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, defaultVal, context.getResources().getDisplayMetrics());
        return applyDimension;
    }

    private float dp2px(Context context, int defultVal) {
        float scale = context.getResources().getDisplayMetrics().density;
        return (float) (defultVal * scale + 0.5);
    }

    public int mixtureColor(int color, @FloatRange(from = 0.0, to = 1.0) float alpha) {
        int a = (color & 0xff000000) == 0 ? 0xff : color >>> 24;
        return (color & 0x00ffffff) | (((int) (a * alpha)) << 24);
    }
}

这里就是全部代码的核心了,其实就是自定义一个titlebar而已,然后设置一些常用属性啦

四.引用并使用

首先,如果你真的不想在代码中写那么多的代码,那就直接在布局中把这些设置好就行了

 <com.example.android.mytestapplication.customvView.CustomNavigatorBar
        android:id="@+id/customView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:leftImage="@drawable/leftarrow"
        app:leftImageVisiable="true"
        app:leftText="左边"
        app:leftTextColor="#ffffff"
        app:leftTextFontSize="16px"
        app:leftTextVisibale="true"
        app:midText="标题"
        app:midTextFontColor="#ffffff"
        app:midTextFontSize="18px"
        app:rightImage="@drawable/rightarrow"
        app:rightImageVisible="true"
        app:rightText="右边"
        app:rightTextColor="@color/colorAccent"
        app:rightTextFontSize="16px"
        app:rightTextVisible="true"
        app:titleBarBackground="@color/colorPrimary" />

就像这样,直接把标题的背景,标题内容,标题大小,标题颜色等等都设置好了,然后就是直接在输代码中使用

   CustomNavigatorBar customNavigatorBar = (CustomNavigatorBar) getView(R.id.customView);


        /**
         * 第一种监听的具体实现
         */
        customNavigatorBar.setLeftImageOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(getActivity(),"left",Toast.LENGTH_SHORT).show();
            }
        });

        /**
         * 第二种监听的具体实现
         */
        customNavigatorBar.addViewClickListener(new CustomNavigatorBar.OnCustomClickListener() {
            @Override
            public void onClickListener(View rootView) {
                switch (rootView.getId()) {
                    case R.id.right_image:
                        Toast.makeText(getActivity(),"right_image is clicked",Toast.LENGTH_SHORT).show();
                        break ;
                    case R.id.left_image:
                        Toast.makeText(getActivity(),"left_image is clicked",Toast.LENGTH_SHORT).show();
                        break ;
                }
            }
        });

小编觉得,这样是很方便,可是,实际用处不太大

还是用我最喜欢的方式吧,顺便把这个自定义view的一些主要方法都用一下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.example.administrator.titlebar.custom.TitleNavigatorBar
        android:id="@+id/titlebar1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:leftTextFontSize="18px"
        app:rightTextFontSize="18px"></com.example.administrator.titlebar.custom.TitleNavigatorBar>

</LinearLayout>

布局是不是很简单
哈哈,这才是核心

public class MainActivity extends AppCompatActivity {

    private TitleNavigatorBar mTitlebar1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        mTitlebar1.setTitleText("申请书");//正中间标题
        mTitlebar1.setTitleBarBackground(Color.parseColor("#FF4081"));//标题栏颜色
        mTitlebar1.setMidTextColor(Color.parseColor("#FFFFFF"), 0.6f);//标题颜色和透明度
        mTitlebar1.setLeftTextColor(0xffffff, 0.5f);//左侧文字颜色和透明度
        mTitlebar1.setRightTextColor(0xffffff, 0.6f);//右侧颜色和透明度
        mTitlebar1.setLeftText("返回");//左侧标题
        mTitlebar1.setRightText("提交");//右侧标题
        mTitlebar1.setLeftDrawable(R.mipmap.ic_launcher);//左侧图标
        mTitlebar1.setRightDrawable(R.mipmap.ic_launcher);//右侧图标
        mTitlebar1.setRightTextSize(30);//右侧文字大小
        mTitlebar1.setLeftTextSize(30);//左侧文字大小
        mTitlebar1.setTitleTextSize(30);//标题文字大小
        mTitlebar1.setLeftImageVisible(false);//左侧图标不可见
        mTitlebar1.setRightImageVisible(false);//左侧图标不可见

        mTitlebar1.setLeftTextOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "左边文字", Toast.LENGTH_SHORT).show();
            }
        });
        mTitlebar1.setLeftImageOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, "左边图片", Toast.LENGTH_SHORT).show();
            }
        });


    }

    private void initView() {
        mTitlebar1 = (TitleNavigatorBar) findViewById(R.id.titlebar1);
    }
}

诺,这些主要的常用方法全部都用上了

小编语,还是多学学自定义view吧,不然,会被时代淘汰的,哈哈

猜你喜欢

转载自blog.csdn.net/qq_40543575/article/details/80042183