自定义组合控件——TopBar

来源:互联网 发布:分班软件 编辑:程序博客网 时间:2024/05/19 09:10

再接再厉,把自定义Topbar记下来。
自定义topbar只是一个自定义模板,把它抽出来作为整体抽出来。我们第一步要做的是在values文件夹下新建attrs.xml文件,并写入如下内容:

<declare-styleable name="TopBar">        <attr name="titleText" format="string"/>        <attr name="titleTextSize" format="dimension"/>        <attr name="titleTextColor" format="color"/>        <attr name="leftText" format="string"/>        <attr name="leftTextSize" format="dimension"/>        <attr name="leftTextColor" format="color"/>        <attr name="leftBackground" format="color|reference"/>        <attr name="rightText" format="string"/>        <attr name="rightTextColor" format="color"/>        <attr name="rightBackground" format="color|reference"/>        <attr name="rightTextSize" format="dimension"/>    </declare-styleable>

这是等下topbar要用的一些属性,写在标签里表示可以在布局文件的xml文件里进行声明。format有很多种类型,根据需要进行设置就行。需要注意的是background属性中是多选的,可以是color,也可是refrence,因为背景可能是颜色也可能是图片。
接下来新建TopBar类继承RelativeLayout。这时候构造方法时会有三个,(其实有四个,第四个还没遇到过用它的情况不清楚)看了网上的介绍大致清楚了他们的作用。

  1. 只有一个参数的:当不需要xml文件声明或者不需要inflate动态加载的时候实现此构造函数即可,如直接在Java代码中new一个topbar。
  2. 两个参数的:当需要在xml文件中声明,并且在topbar中还有自定义属性的时候调用这个构造函数。
  3. 三个参数的:接收一个style资源。

我们三个都实现,并在第一个中调用的二个,在第二个中调用第三个。接着初始化控件。

package com.yang.geoquiz;import android.content.Context;import android.content.res.TypedArray;import android.graphics.drawable.Drawable;import android.os.Build;import android.support.annotation.RequiresApi;import android.util.AttributeSet;import android.view.View;import android.widget.Button;import android.widget.RelativeLayout;import android.widget.TextView;/** * Created by yang on 2017/4/27. */public class TopBar extends RelativeLayout {    private int mLeftTextColor,mRightTextColor,mTitleTextColor;    private float mLeftTextSize,mRightTextSize,mTitleTextSize;    private String mTitleText,mLeftText,mRightText;    private Drawable mRightBacground,mLeftBackground;    private Button mLeftButton,mRightButton;    private TextView titleTextView;    private LayoutParams leftParams,rightParams,titleParams;    public interface TopBarClickListener{        void leftClick();        void rightClick();    }    private TopBarClickListener mListener;    public void setOnTopBarListener(TopBarClickListener listener){        this.mListener = listener;    }    public TopBar(Context context) {        this(context,null);    }    public TopBar(Context context, AttributeSet attrs) {        this(context, attrs,0);        initData(context,attrs);    }    public TopBar(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)    public TopBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);    }    private void initData(Context context, AttributeSet attrs) {        //通过这个方法将attrs.xml中定义的<declare-styleable>里面的属性值存储到TypedArray中        TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.TopBar);        //从typedArray中取出对应的值来为将要设置的属性赋值        mLeftText = a.getString(R.styleable.TopBar_leftText);        mLeftBackground = a.getDrawable(R.styleable.TopBar_leftBackground);        mLeftTextColor = a.getColor(R.styleable.TopBar_leftTextColor,0);        mLeftTextSize = a.getDimension(R.styleable.TopBar_leftTextSize,10);        mRightText = a.getString(R.styleable.TopBar_rightText);        mRightBacground = a.getDrawable(R.styleable.TopBar_rightBackground);        mRightTextColor = a.getColor(R.styleable.TopBar_rightTextColor,0);        mRightTextSize = a.getDimension(R.styleable.TopBar_rightTextSize,10);        mTitleText = a.getString(R.styleable.TopBar_titleText);        mTitleTextColor = a.getColor(R.styleable.TopBar_titleTextColor,0);        mTitleTextSize = a.getDimension(R.styleable.TopBar_titleTextSize,20);        a.recycle();        mLeftButton = new Button(context);        mLeftButton.setTextColor(mLeftTextColor);        mLeftButton.setText(mLeftText);        mLeftButton.setTextSize(mLeftTextSize);        mLeftButton.setBackground(mLeftBackground);        leftParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);        leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);        addView(mLeftButton,leftParams);        mRightButton = new Button(context);        mRightButton.setTextColor(mRightTextColor);        mRightButton.setText(mRightText);        mRightButton.setTextSize(mRightTextSize);        mRightButton.setBackground(mRightBacground);        rightParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);        rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);        addView(mRightButton,rightParams);        titleTextView = new TextView(context);        titleTextView.setTextColor(mTitleTextColor);        titleTextView.setText(mTitleText);        titleTextView.setTextSize(mTitleTextSize);        titleParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);        titleParams.addRule(RelativeLayout.CENTER_HORIZONTAL);        addView(titleTextView,titleParams);        mLeftButton.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                mListener.leftClick();            }        });        mRightButton.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                mListener.rightClick();            }        });    }}

上面初始化中TypedArray可以获取自定义的属性值数组,并通过a.get×××(TopBar_××)来获取自己设置的属性。自定义控件名称加下划线加自定义属性名称是规定格式。其还通过接口回调实现了对左右按钮的点击事件监听。
可以到布局xml中验证:

<?xml version="1.0" encoding="utf-8"?><LinearLayout android:orientation="vertical" 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"    tools:context="com.yang.geoquiz.MainActivity"    >    <com.yang.geoquiz.TopBar        android:layout_gravity="top|center_horizontal"        android:id="@+id/myTopBar"        android:layout_width="match_parent"        android:layout_height="wrap_content"        app:leftBackground="#f40400"        app:leftText="back"        app:leftTextColor="@color/colorPrimary"        app:leftTextSize="5sp"        app:titleText="自定义标题"        app:titleTextColor="#d1c412"        app:titleTextSize="8sp"        app:rightBackground="#f40400"        app:rightText="more"        app:rightTextColor="@color/colorPrimary"        app:rightTextSize="5sp">    </com.yang.geoquiz.TopBar></LinearLayout>

看以前的教程都郑重声明 一定要引入命名空间,但我发现现在你输入自定义属性AndroidStudio已经帮你把命名空间自动引入了。就是这一条:
xmlns:app=”http://schemas.android.com/apk/res-auto”
最后看效果:
这里写图片描述
又完了。都放假了,呀就只有我一个人。
2017.4.29早

0 0
原创粉丝点击