android 自定义TextView

/**
 * 自定textview
 * 显示内容
 * 字体的大小
 * 字体的颜色
 * 控件的宽高
 * 1.自定属性
 * 1.在values文件夹下面创建一个attrs.xml文件
 * 2.定义我们需要的属性
 * 2.wrap_content  hello
 * 3.测量尺寸
 */
1.在values文件夹下面创建一个attrs.xml文件
[java] view plain copy
<?xml version="1.0" encoding="utf-8"?>  
<resources>  
    <!--  
        attr  
            attribute 属性  
            name  属性名  
            format 属性的属性类型  
    -->  
    <attr name="content" format="string"></attr>  
    <attr name="Mycolor" format="color"></attr>  
    <attr name="Mysize" format="dimension"></attr>  
    <!--  
        将定义好的属性放入属性列表  
        name要等于自定义控件的类名  
    -->  
    <declare-styleable name="MyTextView">  
        <attr name="content"></attr>  
        <attr name="mycolor"></attr>  
        <attr name="Mysize"></attr>  
    </declare-styleable>  
</resources>  
2.在布局文件中调用
[java] view plain copy
<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"  
    xmlns:myattr="http://schemas.android.com/apk/res-auto"//设置调用属性名称  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:orientation="vertical"  
    tools:context="com.bwie.zidingyitextview.MainActivity">  

    <com.bwie.zidingyitextview.MyTextView  
        myattr:content="Hello"  
        myattr:Mycolor="#bb0"  
        myattr:Mysize="30px"  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"/>  

</LinearLayout>  
3.自定义类继承view
[java] view plain copy
public class MyTextView extends View {  
    String TAG="aa";  
    private String content;  
    private Paint paint;  
    private int rawX;  
    private int rawY;  
    private int h;  
    private int w;  
    int statusBarHeight1 = -1;  
    private int statusBarHeight;  

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

    public MyTextView(Context context, @Nullable AttributeSet attrs) {  
        this(context, attrs,0);  
    }  

    public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {  
        super(context, attrs, defStyleAttr);  
        //在这里获取在布局文件里面的属性,然后将属性绘制到控件里面  
        //attrs 就是在xml布局文件里面设置的属性  
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyTextView, defStyleAttr, 0);//获取样式属性的  
        //取出属性  
        //获取字符串  
        content = ta.getString(R.styleable.MyTextView_content);  
        int color = ta.getColor(R.styleable.MyTextView_mycolor, Color.GREEN);  
        float size = ta.getDimension(R.styleable.MyTextView_Mysize, 40);  

        //初始化画笔  
        //描边  
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);  
        paint.setColor(color);  
        paint.setTextSize(size);  

        //获取屏幕高度和宽度  
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();  
        h = displayMetrics.heightPixels;  
        w = displayMetrics.widthPixels;  

        Rect rect = new Rect();  
        statusBarHeight = rect.top;  

        //获取status_bar_height资源的ID  获取状态栏的高度  
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");  
        if (resourceId > 0) {  
            //根据资源ID获取响应的尺寸值  
            statusBarHeight1 = getResources().getDimensionPixelSize(resourceId);  
        }  
    }  
    //绘制  

    @Override  
    protected void onDraw(Canvas canvas) {  
        super.onDraw(canvas);  
        //绘制文本  
        //参数1.要绘制的内容  
        //参数2.开始的x轴坐标  
        //参数3.开始的y轴坐标  
        //参数4.paint:用来做画的画笔  
        //画笔  
        Rect rect = new Rect();  
        paint.getTextBounds(content,0,content.length(),rect);  
        canvas.drawText(content,0,rect.height(),paint);  
    }  

    //测量的方法  
    //测量宽高的  
    //测量模式  和 测量尺寸  
    @Override  
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
        //用于改变控件真正的尺寸 android:layout_width="wrap_content"  
        //获取测量模式和测量的尺寸  
        int widthmode = MeasureSpec.getMode(widthMeasureSpec);  
        int heightmode = MeasureSpec.getMode(heightMeasureSpec);  
        int widthsize = MeasureSpec.getSize(widthMeasureSpec);  
        int heightsize = MeasureSpec.getSize(heightMeasureSpec);  
        //如果测量模式是EXACTLY 就直接显示测量尺寸就行  
        int width;  
        int height;  
        //将文字用矩形括起来,那么矩形的尺寸就是文字的尺寸  
        Rect bound =new Rect();  
        paint.getTextBounds(content,0,content.length(),bound);  
        if(widthmode==MeasureSpec.EXACTLY){  
            width=widthsize+10;  
        }else{  
            //控件的宽度需要测量,  
            //控件的宽度 = 文字的宽度+左边距+右边距  
            int wi = bound.width();  
            width=wi+getPaddingLeft()+getPaddingRight()+5;  
        }  

        //处理高度  
        if(heightmode==MeasureSpec.EXACTLY){  
            height=heightsize;  
        }else{  
            int h1 = bound.height();  
            height=h1+getPaddingTop()+getPaddingBottom();  
        }  
        //将宽高重新赋值  
        setMeasuredDimension(width,height);  
    }  

    //移动  
    @Override  
    public boolean onTouchEvent(MotionEvent event) {  
        super.onTouchEvent(event);  
        switch (event.getAction()){  
            case MotionEvent.ACTION_DOWN:  
                //获取开始的坐标  
                rawX = (int) event.getRawX();  
                rawY = (int) event.getRawY();  
                break;  
            case MotionEvent.ACTION_MOVE:  
                //获取移动时候的坐标  
                int yX = (int) event.getRawX();  
                int yY = (int) event.getRawY();  
                //减去手指按下时候的原来坐标  
                //得到移动的间距  
                int jjX=yX-rawX;  
                int jjY=yY-rawY;  
                //将间距,加到原来的坐标(上下左右)  
                int l = getLeft() + jjX;  
                int r = getRight() + jjX;  
                int t = getTop() + jjY;  
                int b = getBottom() + jjY;  

                if(l<0){  
                    l=0;  
                    r=getWidth();  
                }  

                if(t<0){  
                    t=0;  
                    b=getHeight();  
                }  

                if(r>w){  
                    r=w;  
                    l=w-getWidth();  
                }  
                if(b>h-statusBarHeight1){  
                    b=h-statusBarHeight1;  
                    t=b-getHeight();  
                    Toast.makeText(getContext(),""+statusBarHeight1,Toast.LENGTH_LONG).show();  
                }  
                //重新赋值给布局  
                layout(l,t,r,b);  
                //将lastX,lastY重新赋值  
                rawX=yX;  
                rawY=yY;  
                break;  
        }  
        return true;  
    }  
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值