zoukankan      html  css  js  c++  java
  • android 开发进阶自定义控件 类似 TextView

    开发自定义控件的步骤:

    1. 继承View;

    2.重写构造函数并构造方法中获得我们自定义的属性、

    3. 重写onDraw,

    4.重写onMeasure 等函数


    一、自定义View的属性,首先在res/values/  下建立一个attrs.xml , 在里面定义我们的属性和声明我们的整个样式。
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <declare-styleable name="ComstomView">
             <attr name="textContent" format="string" />
            <attr name="textColor" format="color" />
            <attr name="textSize" format="dimension" />
        </declare-styleable>
    
    </resources>



    二、View类的构造方法

    创建自定义控件的3种主要实现方式:
    1)继承已有的控件来实现自定义控件: 主要是当要实现的控件和已有的控件在很多方面比较类似, 通过对已有控件的扩展来满足要求。
    2)通过继承一个布局文件实现自定义控件,一般来说做组合控件时可以通过这个方式来实现。
        注意此时不用onDraw方法,在构造广告中通过inflater加载自定义控件的布局文件,再addView(view),自定义控件的图形界面就加载进来了。
    3)通过继承view类来实现自定义控件,使用GDI绘制出组件界面,一般无法通过上述两种方式来实现时用该方式。

    View(Context context)
    Simple constructor to use when creating a view from code.
    View(Context context, AttributeSet attrs)
    Constructor that is called when inflating a view from XML.
    View(Context context, AttributeSet attrs, int defStyle)
    Perform inflation from XML and apply a class-specific base style.
    三、自定义View增加属性的两种方法:
    1)在View类中定义。通过构造函数中引入的AttributeSet 去查找XML布局的属性名称,然后找到它对应引用的资源ID去找值。
    案例:实现一个带文字的图片(图片、文字是onDraw方法重绘实现)
    
    package com.example.mycomstomview;

    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Paint.Style;
    import android.graphics.Rect;
    import android.util.AttributeSet;
    import android.util.TypedValue;
    import android.view.View;

    public class CustomView extends View {

        private Paint mPaint; // 画笔,包含了画几何图形、文本等的样式和颜色信息
        private String textContent;
        private int textColor;
        private int textSize;
        // 绘制时控制文本绘制的范围
        private Rect mBound;

        public CustomView(Context context) {
            this(context,null);

        }
        
        public CustomView(Context context, AttributeSet attrs) {
            //R.style.AppTheme,设置此处,保证layout view 的属性生效,传递到
            //CustomView(Context context, AttributeSet attrs, int defStyleAttr)
            this(context, attrs,R.style.AppTheme);
        }

        public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            mPaint = new Paint();
            //mPaint.setColor(defStyleAttr);
            getConfig(context, attrs);
            mBound = new Rect();
            mPaint.getTextBounds(textContent, 0, textContent.length(), mBound);
        }
        
        private void getConfig(Context context, AttributeSet attrs) {
            // TypedArray是一个用来存放由context.obtainStyledAttributes获得的属性的数组
            TypedArray ta = context.obtainStyledAttributes(attrs,
                    R.styleable.ComstomView);
            // 属性的名称是styleable中的名称+“_”+属性名称
            int n = ta.getIndexCount();
            for (int i = 0; i < n; i++) {
                int attr = ta.getIndex(i);
                switch (attr) {
                case R.styleable.ComstomView_textColor:
                    textColor = ta.getColor(attr, Color.BLACK); // 提供默认值,放置未指定
                    
                    break;
                case R.styleable.ComstomView_textContent:
                    textContent = ta.getString(attr);

                    break;
                case R.styleable.ComstomView_textSize:
                    // 默认设置为15sp,TypeValue也可以把sp转化为px
                    textSize = ta.getDimensionPixelSize(attr,
                            (int) TypedValue.applyDimension(
                                    TypedValue.COMPLEX_UNIT_SP, 15, getResources()
                                            .getDisplayMetrics()));
                    mPaint.setTextSize(textSize);
                    break;

                }

            }

            // 用完务必回收容器
            ta.recycle();
        }

        public void onDraw(Canvas canvas) {
            super.onDraw(canvas);

            mPaint.setColor(textColor);
            canvas.drawText(textContent, getWidth() / 2 - mBound.width() / 2,
                    getHeight() / 2 + mBound.height() / 2, mPaint);
        }

    }

     在布局文件:中声明我们的自定义View

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:customview="http://schemas.android.com/apk/res/com.example.mycomstomview"  
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity" >
        
        <com.example.mycomstomview.CustomView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/holo_orange_light"
            android:padding="10dp"
            customview:textContent="我是自定义View"
            customview:textSize = "30sp"
            customview:textColor="@android:color/white"
              />

    </RelativeLayout>

    让我们再来看看布局xml中需要注意的事项。

    首先得声明一下:xmlns:customview=http://schemas.android.com/apk/res/com.example.mycomstomview
    注意,“customview”可以换成其他的任何名字,后面的url地址必须最后一部分必须用上自定义组件的包名。自定义属性了,在属性名前加上“customview”即可。


    最后看一下自定义View中方法的作用:

    自定义View的方法

    onFinishInflate() 回调方法,当应用从XML加载该组件并用它构建界面之后调用的方法
    onMeasure() 检测View组件及其子组件的大小
    onLayout() 当该组件需要分配其子组件的位置、大小时
    onSizeChange() 当该组件的大小被改变时
    onDraw() 当组件将要绘制它的内容时
    onKeyDown 当按下某个键盘时
    onKeyUp  当松开某个键盘时
    onTrackballEvent 当发生轨迹球事件时
    onTouchEvent 当发生触屏事件时
    onWindowFocusChanged(boolean)  当该组件得到、失去焦点时
    onAtrrachedToWindow() 当把该组件放入到某个窗口时
    onDetachedFromWindow() 当把该组件从某个窗口上分离时触发的方法
    onWindowVisibilityChanged(int): 当包含该组件的窗口的可见性发生改变时触发的方法

    Demo下载路径

  • 相关阅读:
    onmousewheel
    Zepto 使用中的一些注意点(转)
    oninput onpropertychange 监听输入框值变化
    try catch
    center的用法
    [转]你的编程语言可以这样做吗?(map/reduce的js示范) (转)
    vue中 $event 的用法--获取当前父元素,子元素,兄弟元素
    chrome的vue插件——vue.js devtools的安装
    说明与比较:new Vue() 和 export default {}
    Vue反转字符串及join(),reverse()与 split()函数用法解析
  • 原文地址:https://www.cnblogs.com/sharecenter/p/5621028.html
Copyright © 2011-2022 走看看