自定义组件(四)
来源:互联网 发布:js url encode 解码 编辑:程序博客网 时间:2024/06/11 14:57
重写onMeasure(int widthMeasureSpec, int heightMeasureSpec) 和
onDraw(Canvas canvas)方法生成自定义view
效果图
在values文件夹下新建textview_attr.xml文件
定义自定义布局的属性
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="MyTextView"> <attr name="textSize" format="integer"></attr> <attr name="text" format="string|reference"></attr> <attr name="textColor" format="color|reference"></attr> <attr name="underLine" format="boolean"></attr> </declare-styleable></resources>
创建MyTextView继承View
实现前三个构造方法
public MyTextView(Context context) { super(context); init(); } public MyTextView(Context context, AttributeSet attrs) { super(context, attrs); getAttr(attrs); init(); } public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); getAttr(attrs); init(); }
初始化属性值
//初始化属性值 private int textSize =36; private int textColor = Color.BLACK; private String text ="Hello World"; private boolean underLine =false;
初始化画笔和定位距离的变量
//初始化画笔属性 private Paint textpaint; private int left,top;
给定义的变量设置set方法
public void setTextSize(int textSize) { this.textSize = textSize; } public void setTextColor(int textColor) { this.textColor = textColor; } public void setText(String text) { this.text = text; } public void setUnderLine(boolean underLine) { this.underLine = underLine; }
获取属性值
//获取属性值 public void getAttr (AttributeSet attrs){ TypedArray type=getContext().obtainStyledAttributes(attrs,R.styleable.MyTextView); textSize=type.getInt(R.styleable.MyTextView_textSize,textSize); textColor=type.getColor(R.styleable.MyTextView_textColor,textColor); text=type.getString(R.styleable.MyTextView_text); underLine=type.getBoolean(R.styleable.MyTextView_underLine,underLine); type.recycle(); }
给画笔设置初始值
public void init(){ textpaint=new Paint(); textpaint.setTextSize(textSize); textpaint.setColor(textColor); textpaint.setUnderlineText(underLine); }
重写onMeasure方法,计算并且设置宽高
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width=calWidth(widthMeasureSpec); int height=calHeight(heightMeasureSpec); setMeasuredDimension(width,height); }
计算宽
private int calWidth(int widthMeasureSpec) { int widthMode=MeasureSpec.getMode(widthMeasureSpec); int widthSize=MeasureSpec.getSize(widthMeasureSpec); int widthText= (int) textpaint.measureText(text); int width=widthText; left=getPaddingLeft(); if(widthMode==MeasureSpec.EXACTLY){ width=widthSize; } if(widthMode==MeasureSpec.AT_MOST){ width=Math.min(widthSize,widthText); } return width+getPaddingLeft()+getPaddingRight(); }
计算高
private int calHeight(int heightMeasureSpec) { int heightMode=MeasureSpec.getMode(heightMeasureSpec); int heightSize=MeasureSpec.getSize(heightMeasureSpec); int heightText= (int) (-textpaint.getFontMetrics().top+textpaint.getFontMetrics().bottom); int height=heightText; top= (int) (-textpaint.getFontMetrics().top+getPaddingLeft()); if(heightMode==MeasureSpec.EXACTLY){ height=heightSize; } if(heightMode==MeasureSpec.AT_MOST){ height=Math.min(heightSize,heightText); } return height+getPaddingTop()+getPaddingBottom(); }
重写onDraw方法,在画布上用画笔绘制
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.LTGRAY); canvas.drawText(text,left,top,textpaint); }
在set方法下添加刷新方法
public void setText(String text) { this.text = text; //从新绘制布局 requestLayout(); //刷新界面 invalidate(); }
在布局中添加自定义View
<com.axnet.temp0728.MyTextView android:id="@+id/main_tv" android:padding="20dp" android:layout_width="wrap_content" android:layout_height="wrap_content" app:underLine="true" app:textSize="72" app:text="hello world" app:textColor="#00cacb" />
在布局中添加自定义属性的定义空间
xmlns:app="http://schemas.android.com/apk/res-auto"
自定义布局中就可以使用,我们定义的属性
app:textSize="72" app:text="hello world" app:textColor="#00cacb"
mainActivity的代码,改变自己定义的View的变化
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { main_tv.setText("666"); main_tv.setUnderLine(false); } });
全部代码
mainActivity
public class MainActivity extends AppCompatActivity { Button button; MyTextView main_tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button=(Button)findViewById(R.id.button); main_tv=(MyTextView)findViewById(R.id.main_tv); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { main_tv.setText("666"); main_tv.setUnderLine(false); } }); }}
mainActivity的布局
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/activity_main" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.axnet.temp0728.MainActivity"> <Button android:text="点击更换文字" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/button"/> <com.axnet.temp0728.MyTextView android:id="@+id/main_tv" android:padding="20dp" android:layout_width="wrap_content" android:layout_height="wrap_content" app:underLine="true" app:textSize="72" app:text="hello world" app:textColor="#00cacb" /></LinearLayout>
MyTextView
public class MyTextView extends View{ //初始化属性值 private int textSize =36; private int textColor = Color.BLACK; private String text ="Hello World"; private boolean underLine =false; //初始化画笔属性 private Paint textpaint; private int left,top; public void setTextSize(int textSize) { this.textSize = textSize; } public void setTextColor(int textColor) { this.textColor = textColor; } public void setText(String text) { this.text = text; //从新绘制布局 requestLayout(); //刷新界面 invalidate(); } public void setUnderLine(boolean underLine) { this.underLine = underLine; //从新绘制布局 requestLayout(); //刷新界面 invalidate(); } public MyTextView(Context context) { super(context); init(); } public MyTextView(Context context, AttributeSet attrs) { super(context, attrs); getAttr(attrs); init(); } public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); getAttr(attrs); init(); } //获取属性值 public void getAttr (AttributeSet attrs){ TypedArray type=getContext().obtainStyledAttributes(attrs,R.styleable.MyTextView); textSize=type.getInt(R.styleable.MyTextView_textSize,textSize); textColor=type.getColor(R.styleable.MyTextView_textColor,textColor); text=type.getString(R.styleable.MyTextView_text); underLine=type.getBoolean(R.styleable.MyTextView_underLine,underLine); type.recycle(); } public void init(){ textpaint=new Paint(); textpaint.setTextSize(textSize); textpaint.setColor(textColor); textpaint.setUnderlineText(underLine); } //计算并设置宽高// widthMeasureSpec heightMeasureSpec 宽高规则 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width=calWidth(widthMeasureSpec); int height=calHeight(heightMeasureSpec); setMeasuredDimension(width,height); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.LTGRAY); canvas.drawText(text,left,top,textpaint); } private int calHeight(int heightMeasureSpec) { int heightMode=MeasureSpec.getMode(heightMeasureSpec); int heightSize=MeasureSpec.getSize(heightMeasureSpec); int heightText= (int) (-textpaint.getFontMetrics().top+textpaint.getFontMetrics().bottom); int height=heightText; top= (int) (-textpaint.getFontMetrics().top+getPaddingLeft()); if(heightMode==MeasureSpec.EXACTLY){ height=heightSize; } if(heightMode==MeasureSpec.AT_MOST){ height=Math.min(heightSize,heightText); } return height+getPaddingTop()+getPaddingBottom(); } private int calWidth(int widthMeasureSpec) { int widthMode=MeasureSpec.getMode(widthMeasureSpec); int widthSize=MeasureSpec.getSize(widthMeasureSpec); int widthText= (int) textpaint.measureText(text); int width=widthText; left=getPaddingLeft(); if(widthMode==MeasureSpec.EXACTLY){ width=widthSize; } if(widthMode==MeasureSpec.AT_MOST){ width=Math.min(widthSize,widthText); } return width+getPaddingLeft()+getPaddingRight(); }}
自定义属性的textview_attr 在 values目录下
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="MyTextView"> <attr name="textSize" format="integer"></attr> <attr name="text" format="string|reference"></attr> <attr name="textColor" format="color|reference"></attr> <attr name="underLine" format="boolean"></attr> </declare-styleable></resources>
自定义布局感觉还是不是掌握的很好,最近吧课程学完了,准备学一下
HenCoder的自定义View
http://hencoder.com/
不会使用的东西还有很多,会使用但是不知道实现原理的东西更多
加油
阅读全文
0 0
- 自定义组件(四)
- 自定义组件研究<四>
- 自定义组件(第一)
- 自定义组件(二)
- 自定义组件(一)
- 自定义组件(1)
- 自定义组件(二)
- 自定义组件(三)
- 自定义组件之属性(Property)的性质(Attribute)介绍(四)
- 自定义组件之属性(Property)的性质(Attribute)介绍(四)
- React study(四)Mixin编写使用、函数复用、自定义表单组件
- JSF自定义组件之四 JSF实现-Component
- Unity自定义UI组件(四)双击按钮、长按按钮
- Unity自定义UI组件(四)双击按钮、长按按钮
- 核心Swing组件(四)
- Android应用程序组件(四)
- 四大组件复习(四)
- React学习(四)组件
- Android:禁止viewpager左右滑动,去除viewpager切换时动画,解决viewpager与百度地图滑动冲突
- 极角排序/凸包
- TZImagePickerController 快速接入
- git命令大全
- maven国内镜像(maven下载慢的解决方法)
- 自定义组件(四)
- 你只是看起来很忙碌,其实却每天被别人收割
- iOS UIPickView和UIDatePicker的基本使用
- 欢迎使用CSDN-markdown编辑器
- #6 记录入库
- 深入理解JVM(一)——JVM内存模型
- Hbuilder 打包IOS的应用的大体步骤
- spring boot配置mybatis和事务管理
- VUE.js的简单使用及路径