自定义View/ViewGroup的步骤和实现

Posted 岑忠满

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义View/ViewGroup的步骤和实现相关的知识,希望对你有一定的参考价值。

1.设置属性(供XML调用)

在res目录新建attrs.xml文件

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyTopBar">
        <attr name="title" format="string"/>
        <attr name="titleSize" format="dimension"/>
        <attr name="titleColor" format="color"/>

        <attr name="leftButtonText" format="string"/>
        <attr name="leftButtonTextSize" format="dimension"/>
        <attr name="leftButtonTextColor" format="color"/>
        <attr name="leftButtonTextBackGround" format="reference|color"/>

        <attr name="rightButtonText" format="string"/>
        <attr name="rightButtonTextSize" format="dimension"/>
        <attr name="rightButtonTextColor" format="color"/>
        <attr name="rightButtonTextBackGround" format="reference|color"/>

        <attr name="rightButtonText2" format="string"/>
        <attr name="rightButtonTextSize2" format="dimension"/>
        <attr name="rightButtonTextColor2" format="color"/>
        <attr name="rightButtonTextBackGround2" format="reference|color"/>
    </declare-styleable>
</resources>

2.创建自定义继承于(view/viewGroup/各种组件)

public class MyTopBar extends RelativeLayout {
    //TopBar容器包含的组件
    private Button mLeftButton, mRightButton, mRightButton2;
    private TextView mTitleTextView;

    // 布局属性,用来控制组件元素在ViewGroup中的位置
    private LayoutParams mLeftParams, mTitleParams, mRightParams, mRightParams2;

    //定义title属性
    private String mTitle;
    private int mTitleColor;
    private float mTitleSize;
    //定义leftButton属性
    private String mLeftButtonText;
    private float mLeftButtonTextSize;
    private int mLeftButtonTextColor;
    private Drawable mLeftButtonTextBackGround;
    //定义最右边的RightButton属性
    private String mRightButtonText;
    private float mRightButtonTextSize;
    private int mRightButtonTextColor;
    private Drawable mRightButtonTextBackGround;
    //定义倒数第二个rightButton的属性
    private String mRightButtonText2;
    private float mRightButtonTextSize2;
    private int mRightButtonTextColor2;
    private Drawable mRightButtonTextBackGround2;

    // 映射传入的接口对象
    private topBarClickListener mListener;

    public MyTopBar(Context context) {
        super(context);
    }

    //这个构造函数是包含attrs的,XML在加载时候会调用这个构造函数
    public MyTopBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        /*
         1.把所有的attrs的值添加到TypeArray中
        */
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyTopBar);
        //把TypeArray中的值取出来
        mTitle = typedArray.getString(R.styleable.MyTopBar_title);
        mTitleColor = typedArray.getColor(R.styleable.MyTopBar_titleColor, 0);
        mTitleSize = typedArray.getDimension(R.styleable.MyTopBar_titleSize, 10);

        mLeftButtonText = typedArray.getString(R.styleable.MyTopBar_leftButtonText);
        mLeftButtonTextColor = typedArray.getColor(R.styleable.MyTopBar_leftButtonTextColor, 0);
        mLeftButtonTextSize = typedArray.getDimension(R.styleable.MyTopBar_leftButtonTextSize, 10);
        mLeftButtonTextBackGround = typedArray.getDrawable(R.styleable.MyTopBar_leftButtonTextBackGround);

        mRightButtonText = typedArray.getString(R.styleable.MyTopBar_rightButtonText);
        mRightButtonTextColor = typedArray.getColor(R.styleable.MyTopBar_rightButtonTextColor, 0);
        mRightButtonTextSize = typedArray.getDimension(R.styleable.MyTopBar_rightButtonTextSize, 10);
        mRightButtonTextBackGround = typedArray.getDrawable(R.styleable.MyTopBar_rightButtonTextBackGround);

        mRightButtonText2 = typedArray.getString(R.styleable.MyTopBar_rightButtonText2);
        mRightButtonTextColor2 = typedArray.getColor(R.styleable.MyTopBar_rightButtonTextColor2, 0);
        mRightButtonTextSize2 = typedArray.getDimension(R.styleable.MyTopBar_rightButtonTextSize2, 10);
        mRightButtonTextBackGround2 = typedArray.getDrawable(R.styleable.MyTopBar_rightButtonTextBackGround2);
        //取完不要忘记recycle,防止下次调用失败
        typedArray.recycle();

        /*
        2.组合控件
        */
        mTitleTextView = new TextView(context);
        mLeftButton = new Button(context);
        mRightButton = new Button(context);
        mRightButton2 = new Button(context);

        //为元素添加设置属性,来自XML的值会自动在这里进行设置
        mTitleTextView.setText(mTitle);
        mTitleTextView.setTextColor(mTitleColor);
        mTitleTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP,mTitleSize);

        mLeftButton.setText(mLeftButtonText);
        mLeftButton.setTextSize(TypedValue.COMPLEX_UNIT_SP,mLeftButtonTextSize);
        mLeftButton.setTextColor(mLeftButtonTextColor);
        mLeftButton.setBackground(mLeftButtonTextBackGround);
        mLeftButton.setId(R.id.topBar_left_button);

        mRightButton.setText(mRightButtonText);
        mRightButton.setTextColor(mRightButtonTextColor);
        mRightButton.setTextSize(TypedValue.COMPLEX_UNIT_SP,mRightButtonTextSize);
        mRightButton.setBackground(mRightButtonTextBackGround);
        mRightButton.setId(R.id.topBar_right_button);//这个id需要在res文件中添加ids.xml文件

        mRightButton2.setText(mRightButtonText2);
        mRightButton2.setTextColor(mRightButtonTextColor2);
        mRightButton2.setTextSize(TypedValue.COMPLEX_UNIT_SP,mRightButtonTextSize2);
        mRightButton2.setBackground(mRightButtonTextBackGround2);
        //为组件设置布局
        mLeftParams = new LayoutParams(
                200,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        mLeftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT,TRUE);//居于父布局左侧
        addView(mLeftButton,mLeftParams);//添加到ViewGroup

        mRightParams = new LayoutParams(
                200,
                ViewGroup.LayoutParams.MATCH_PARENT);
        mRightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT,TRUE);//居于父布局右侧
        addView(mRightButton,mRightParams);

        mRightParams2 = new LayoutParams(
                //px = dp*(dpi/160)这里是像素
                80,
                80);
        mRightParams2.addRule(RelativeLayout.LEFT_OF,R.id.topBar_right_button);//居于最右侧按键左侧
        mRightParams2.addRule(RelativeLayout.CENTER_VERTICAL,TRUE);
        addView(mRightButton2,mRightParams2);

        mTitleParams = new LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        mTitleParams.addRule(RelativeLayout.CENTER_IN_PARENT,TRUE);
        mTitleParams.addRule(RelativeLayout.RIGHT_OF,R.id.topBar_left_button);//居于最左侧按键右侧
        addView(mTitleTextView,mTitleParams);

        //定义事件监听
        mLeftButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mListener.leftButtonClick();
            }
        });

        mRightButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mListener.RightButtonClick();
            }
        });

        mRightButton2.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mListener.RightButtonClick2();
            }
        });
    }

    /*
    3.定义接口,留给调用者实现
     */
    public interface topBarClickListener {
        //左按键
        void leftButtonClick();
        //右按键
        void RightButtonClick();
        //右按键2
        void RightButtonClick2();
    }

    // 暴露一个方法给调用者来注册接口回调
    // 通过接口来获得回调者对接口方法的实现
    public void setOnTopBarClickListener(topBarClickListener mListener) {
        this.mListener = mListener;
    }
}

3.可见性设置

   /*
    4.高度自定义
    */
    public void setButtonVisible(int id, boolean flag) {
        if (flag) {
            if (id == 0) {
                mLeftButton.setVisibility(View.VISIBLE);
            } else if (id == 1) {
                mRightButton.setVisibility(View.VISIBLE);
            } else {
                mRightButton2.setVisibility(View.VISIBLE);
            }
        } else {
            if (id == 0) {
                mLeftButton.setVisibility(View.GONE);
            } else if (id == 1) {
                mRightButton.setVisibility(View.GONE);
            } else {
                mRightButton2.setVisibility(View.GONE);
            }
        }
    }

 

QQ图片20170407232545

以上是关于自定义View/ViewGroup的步骤和实现的主要内容,如果未能解决你的问题,请参考以下文章

自定义ViewGroup获取子View参数

自定义ViewGroup获取子View参数

Android View和ViewGroup

[GitHub开源]Android自定义View实现微信打飞机游戏

Android 自定义View之Draw过程(上)

Android - 进阶之自定义视图浅析