/** * 自定textview * 显示内容 * 字体的大小 * 字体的颜色 * 控件的宽高 * 1.自定属性 * 1.在values文件夹下面创建一个attrs.xml文件 * 2.定义我们需要的属性 * 2.wrap_content hello * 3.测量尺寸 */1.在values文件夹下面创建一个attrs.xml文件
2.在布局文件中调用<?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>
3.自定义类继承view<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>
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; } }
android 自定义TextView
最新推荐文章于 2023-12-26 23:29:04 发布