android 自定义TextView

/**
 * 自定textview
 * 显示内容
 * 字体的大小
 * 字体的颜色
 * 控件的宽高
 * 1.自定属性
 * 1.在values文件夹下面创建一个attrs.xml文件
 * 2.定义我们需要的属性
 * 2.wrap_content  hello
 * 3.测量尺寸
 */
1.在values文件夹下面创建一个attrs.xml文件
<?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.在布局文件中调用
<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
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、付费专栏及课程。

余额充值