Android系统给我们提供了丰富的UI效果,而传统的系统控件不能满足自己的需求。自定义View可以设计出好看的Ui.

一般有以下几种方法:1 对现有控件进行拓展  2.创建组合控件 3重写View 绘画出新的View

一:自定义修改TextView(对现有控件进行拓展)

首先我们先看一下效果

Android 自定义控件defStyleRes android自定义控件 进度条_xml

修改原来的控件需要继承原控件,并且对onDraw()方法进行修改

首先初始化画笔

private void initView() {
        mPaint1 = new Paint();
        mPaint1.setColor(getResources().getColor(
                android.R.color.holo_blue_light));
        mPaint1.setStyle(Paint.Style.FILL);
        mPaint2 = new Paint();
        mPaint2.setColor(Color.YELLOW);
        mPaint2.setStyle(Paint.Style.FILL);
    }

绘制TextView边框

@Override
    protected void onDraw(Canvas canvas) {
        // 绘制外层矩形
        canvas.drawRect(
                0,
                0,
                getMeasuredWidth(),
                getMeasuredHeight(),
                mPaint1);
        // 绘制内层矩形
        canvas.drawRect(
                10,
                10,
                getMeasuredWidth() - 10,
                getMeasuredHeight() - 10,
                mPaint2);
        canvas.save();
        // 绘制文字前平移10像素
        canvas.translate(10, 0);
        // 父类完成的方法,即绘制文本
        super.onDraw(canvas);
        canvas.restore();
    }



在这里复习一下绘制图形的一些

矩形canvas.drawRect(left, top, right, bottom, paint) :这里的left、top、right、bottom的值是:
left:是矩形距离左边的X轴
top:是矩形距离上边的Y轴
right:是矩形距离右边的X轴
bottom:是矩形距离下边的Y轴

      椭圆 Rect  re = new Rect(left, top, right, bottom);//外接矩形    
canvas.drawOval(re,paint);

二:自定义可复用的TitleBar(组合控件)

创建复合控件,可以重用功能。通常是继承一个ViewGroup,在里面添加控件,并对外提供访问的接口。

这里要创建一个TitleBar  按照惯例先上图

Android 自定义控件defStyleRes android自定义控件 进度条_控件_02


首先创建该控件继承RelaytiveLayout,然后添加三个控件。为了让该控件有更大的灵活性,让开发者在xml文件中 属性配置。我们创建attrs文件。


<declare-styleable name="TitleBar">

        <attr name="mtitletext" format="string" />
        <attr name="mtitleTextSize" format="dimension" />
        <attr name="mtitleTextColor" format="color" />

        <attr name="leftTextColor" format="color" />
        <attr name="leftBackground" format="reference|color" />
        <attr name="leftText" format="string" />

        <attr name="rightTextColor" format="color" />
        <attr name="rightBackground" format="reference|color" />
        <attr name="rightText" format="string" />



    </declare-styleable>


分别配置了三个控件的属性  

在TitleBar中需要将这些属性取出。

TypedArray ta = context.obtainStyledAttributes(attrs,
                R.styleable.TitleBar);

        mLeftTextColor = ta.getColor(
                R.styleable.TitleBar_leftTextColor, 0);
        mLeftBackground = ta.getDrawable(
                R.styleable.TitleBar_leftBackground);
        mLeftText = ta.getString(R.styleable.TitleBar_leftText);

        mRightTextColor = ta.getColor(
                R.styleable.TitleBar_rightTextColor, 0);
        mRightBackground = ta.getDrawable(
                R.styleable.TitleBar_rightBackground);
        mRightText = ta.getString(R.styleable.TitleBar_rightText);

        mTitleTextSize = ta.getDimension(
                R.styleable.TitleBar_mtitleTextSize, 10);
        mTitleTextColor = ta.getColor(
                R.styleable.TitleBar_mtitleTextColor, 0);
        mTitle = ta.getString(R.styleable.TitleBar_mtitletext);

        // 获取完TypedArray的值后,一般要调用
        // recyle方法来避免重新创建的时候的错误
        ta.recycle();



 然后设置三个子控制的属性

leftButton = new Button(context);
       rightButton = new Button(context);
        titleTextView = new TextView(context);

        leftButton.setTextColor(mLeftTextColor);
        leftButton.setBackground(mLeftBackground);
        leftButton.setText(mLeftText);

        rightButton.setTextColor(mRightTextColor);
        rightButton.setBackground(mRightBackground);
        rightButton.setText(mRightText);

        titleTextView.setText(mTitle);
        titleTextView.setTextColor(mTitleTextColor);
        titleTextView.setTextSize(mTitleTextSize);
        titleTextView.setGravity(Gravity.CENTER);



最后设置三个控件的位置布局

mrlayoutparams = new LayoutParams(
                LayoutParams.WRAP_CONTENT,
                LayoutParams.MATCH_PARENT);
        mrlayoutparams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE);
        addView(rightButton, mrlayoutparams);

        mlblayoutParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT,
                LayoutParams.MATCH_PARENT);
        mlblayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE);
        // 添加到ViewGroup
        addView(leftButton, mlblayoutParams);

        mtlayoutparams=new LayoutParams(LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
        mtlayoutparams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);
        addView(titleTextView, mtlayoutparams);



这样三个子控件就组合好,添加到TitleBar中了。但是还不能处理点击信息。对外提供接口,让开发者实现该方法,这样便于复用和功能的灵活

在xml文件中配置 这样就能够复用TitleBar.xml


<com.xys.mytopbar.Topbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:id="@+id/topBar"
    android:layout_width="match_parent"
    android:layout_height="40dp"

    custom:leftBackground="@drawable/blue_button"
    custom:leftText="Back"
    custom:leftTextColor="#FFFFFF"

    custom:rightBackground="@drawable/blue_button"
    custom:rightText="More"
    custom:rightTextColor="#FFFFFF"

    custom:mtitletext="dfas"
    custom:mtitleTextColor="#123412"
    custom:mtitleTextSize="15sp">

</com.xys.mytopbar.Topbar>

这样配置就好了,接下来就是如何使用。  在需要使用的Activity内

mTopbar = (TopBar) findViewById(R.id.topBar);
        // 为topbar注册监听事件,传入定义的接口
        // 并以匿名类的方式实现接口内的方法
        mTopbar.setOnTopbarClickListener(
                new TopBar.topbarClickListener() {

                    @Override
                    public void rightClick() {
                        Toast.makeText(TopBarTest.this,
                                "right", Toast.LENGTH_SHORT)
                                .show();
                    }

                    @Override
                    public void leftClick() {
                        Toast.makeText(TopBarTest.this,
                                "left", Toast.LENGTH_SHORT)
                                .show();
                    }
                });
        // 控制topbar上组件的状态
        mTopbar.setButtonVisable(0, true);
        mTopbar.setButtonVisable(1, false);



下载请访问我的GIThub   

点击打开链接