您好,欢迎访问一九零五行业门户网

深入理解Android开发RectF和Rect之间的区别

rect中文意思“矩形或长方形”,rect对象持有一个矩形的四个integer坐标值,rectf对象持有一个矩形的四个float坐标值,这是两者最大的区别。从实现的方式上看,rect是一个final类实现parcelable接口,rectf是一个普通类实现parcelable接口,rect和rectf除了记录的坐标数据类型不一样外,两个类提供的方法大体上都是一样的。
1. 联系: 
都是用于表示坐标系中的一块矩形区域,并可以对其做一些简单操作。这块矩形区域,需要用左上和右下两个坐标点表示。 
2. 区别: 
(1).精度不一样。rect是使用int类型作为数值,rectf是使用float类型作为数值。 
(2).两个类型提供的方法也不是完全一致。
3. 代码部分
package com.pansoft.viewdemo.view; import android.content.context; import android.graphics.canvas; import android.graphics.color; import android.graphics.paint; import android.graphics.paint.style; import android.graphics.rect; import android.graphics.rectf; import android.view.view; /** 自定义view **/ public class myview extends view { /** 上下文 */ private context mcontext; /** 画笔 */ private paint mpaint; public myview(context context) { super(context); mcontext = context; } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); mpaint = new paint(); // 设置画笔的颜色 mpaint.setcolor(color.red); // 设置填充颜色 mpaint.setstyle(style.fill); rectf rect = new rectf(10, 10, 100, 100); // rect rect2 = new rect(10, 10, 100, 100); canvas.drawrect(rect, mpaint); } }
rectf和rect基础
final textview textview = new textview(this); textview.settext("显示rect存储坐标数据"); /** * 设置textview的宽度和高度,最后计算textview的左上角和右下角的坐标 */ textview.setlayoutparams(new viewgroup.layoutparams(400, 400)); textview.setbackgroundcolor(color.parsecolor("#00bfff")); textview.setgravity(gravity.center); textview.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { int top = v.gettop(); int left = v.getleft(); int right = v.getright(); int bottom = v.getbottom(); /** * 将textview相对父控件的坐标保存在rect对象 */ mrect.left = left; mrect.right = right; mrect.top = top; mrect.bottom = bottom; textview.settext(mrect.toshortstring()); } });
final button button = new button(this); /** * 设置button的宽度和高度,最后计算矩形局域的宽和高 */ viewgroup.marginlayoutparams params=new viewgroup.marginlayoutparams(800, 300); /** * 设置button的margin属性值 */ params.setmargins(100,densityutil.dip2px(this,100),100,100); button.setlayoutparams(params); button.settext("计算rect坐标"); button.setbackgroundcolor(color.parsecolor("#7fffaa")); button.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { int top = v.gettop(); int left = v.getleft(); int right = v.getright(); int bottom = v.getbottom(); /** * 将textview相对父控件的坐标保存在rect对象 */ mrect.left = left; mrect.right = right; mrect.top = top; mrect.bottom = bottom; button.settext("宽度:"+mrect.width()+"\n"+"高度:"+mrect.height()); } });
final button anim_btn =new button(this); /** * 设置button的宽度和高度 */ params=new viewgroup.marginlayoutparams(800, 300); /** * 设置button的margin属性值,计算矩形局域的中心点坐标 */ params.setmargins(100,densityutil.dip2px(this,100),100,100); anim_btn.setlayoutparams(params); anim_btn.settext("计算rect坐标"); anim_btn.setbackgroundcolor(color.parsecolor("#dda0dd")); anim_btn.setgravity(gravity.right); anim_btn.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { int top = v.gettop(); int left = v.getleft(); int right = v.getright(); int bottom = v.getbottom(); /** * 将textview相对父控件的坐标保存在rect对象 */ mrect.left = left; mrect.right = right; mrect.top = top; mrect.bottom = bottom; anim_btn.settext("水平中心点:"+mrect.centerx()+"\n垂直中心点:"+mrect.centery()); } });
正是因为每一个矩形局域包含着left、top、right和bottom四个顶点坐标,getleft()、gettop()、getright()和getbottom()属于view声明的方法,因此每一个view子类或者控件继承上述方法,rect或rectf类似一个工具类,封装四个顶点坐标的计算关系,使用getleft()、gettop()、getright()和getbottom()需要注意两个问题:
第一个问题:getleft()、gettop()、getright()和getbottom()计算相对其父容器的位置
第二个问题:getleft()、gettop()、getright()和getbottom()计算结果为0,是因为当前view子类或控件没有绘制完成。解决办法,onclick方法点击的时候计算或者使用线程的延时计算
/** * 延时获取控件相对父容器的left、top、right、bottom坐标,否则为0 */ new thread(new runnable() { @override public void run() { try { thread.sleep(1000); } catch (interruptedexception e) { e.printstacktrace(); } savecoordinatetorect(); } }).start();
rectf和rect深入
rect是一个final类,不属于被继承,实现parcelable接口执行序列化,声明public作用域的四个整型属性:left、top、right和bottom,用来记录view矩形局域的四个顶点坐标。
public rect() {}
1、创建一个空的rect对象,left、top、right和bottom的默认值为0
public rect(int left, int top, int right, int bottom) { this.left = left; this.top = top; this.right = right; this.bottom = bottom; }
2、创建一个指定坐标值的rect对象,left、top、right和bottom为指定值
public rect(rect r) { if (r == null) { left = top = right = bottom = 0; } else { left = r.left; top = r.top; right = r.right; bottom = r.bottom; } }
3、使用已知的rect,创建一个新的rect对象,left、top、right和bottom为已知的rect包含的值
@override public boolean equals(object o) { if (this == o) return true; if (o == null || getclass() != o.getclass()) return false; rect r = (rect) o; return left == r.left && top == r.top && right == r.right && bottom == r.bottom; }
4、判断当前rect与指定的o是否同一个,相同的条件:属于同一个对象或者两者left、top、right或bottom属性值一样
@override public int hashcode() { int result = left; result = 31 * result + top; result = 31 * result + right; result = 31 * result + bottom; return result; }
5、计算rect属性值的散列码
@override public string tostring() { stringbuilder sb = new stringbuilder(32); sb.append("rect("); sb.append(left); sb.append(", "); sb.append(top); sb.append(" - "); sb.append(right); sb.append(", "); sb.append(bottom); sb.append(")"); return sb.tostring(); }
6、以rect(left,top-right,bottom)的格式返回矩形四个坐标值
public string toshortstring(stringbuilder sb) { sb.setlength(0); sb.append('['); sb.append(left); sb.append(','); sb.append(top); sb.append("]["); sb.append(right); sb.append(','); sb.append(bottom); sb.append(']'); return sb.tostring(); }
7、以[left,top] [right,bottom]的格式返回矩形四个坐标值,即矩形区域左上角和右下角坐标
public string toshortstring() { return toshortstring(new stringbuilder(32)); }
8、以[left,top] [right,bottom]的格式返回矩形四个坐标值,即矩形区域左上角和右下角坐标,和上述方法一样
public string flattentostring() { stringbuilder sb = new stringbuilder(32); // warning: do not change the format of this string, it must be // preserved because rects are saved in this flattened format. sb.append(left); sb.append(' '); sb.append(top); sb.append(' '); sb.append(right); sb.append(' '); sb.append(bottom); return sb.tostring(); }
9、以left top right bottom的格式返回矩形四个坐标值,即平铺的格式,比如:0 0 400 400或 100 100 800 300
public static rect unflattenfromstring(string str) { matcher matcher = unflattenhelper.getmatcher(str); if (!matcher.matches()) { return null; } return new rect(integer.parseint(matcher.group(1)), integer.parseint(matcher.group(2)), integer.parseint(matcher.group(3)), integer.parseint(matcher.group(4))); }
10、给定一个平铺格式的字符串,比如:0 0 400 400,判断是否合法,然后转换为一个rect对象
public void printshortstring(printwriter pw) { pw.print('['); pw.print(left); pw.print(','); pw.print(top); pw.print("]["); pw.print(right); pw.print(','); pw.print(bottom); pw.print(']'); }
11、将rect包含的属性值以[left,top] [right,bottom]的格式写入给定的printwriter流中
public final boolean isempty() { return left >= right || top >= bottom; }
12、判断rect是否一个空对象,即包含的属性值是否不为0
public final int width() { return right - left; }
13、计算矩形区域的宽度
public final int height() { return bottom - top; }
14、计算矩形区域的高度
public final int centerx() { return (left + right) >> 1; }
15、计算矩形区域的水平中心点,计算结果为分数则返回最接近的整型数,例如:水平中心点400
public final int centery() { return (top + bottom) >> 1; }
16、计算矩形区域的垂直中心点,计算结果为分数则返回最接近的整型数,例如:垂直中心点850
public final float exactcenterx() { return (left + right) * 0.5f; }
17、计算矩形区域的水平中心点,返回结果float类型,例如:水平中心点400.0
public final float exactcentery() { return (top + bottom) * 0.5f; }
18、计算矩形区域的垂直中心点,返回结果float类型,例如:垂直中心点850.0
public void setempty() { left = right = top = bottom = 0; }
19、将rect对象包含的属性值设置为0
public void set(int left, int top, int right, int bottom) { this.left = left; this.top = top; this.right = right; this.bottom = bottom; }
20、将rect的属性值设置为指定的值
public void set(rect src) { this.left = src.left; this.top = src.top; this.right = src.right; this.bottom = src.bottom; }
21、复制指定的rect对象包含的属性值
public void offset(int dx, int dy) { left += dx; top += dy; right += dx; bottom += dy; }
22、在当前矩形区域的水平方向、垂直方向分别增加dx、dy距离,即扩展
public void offsetto(int newleft, int newtop) { right += newleft - left; bottom += newtop - top; left = newleft; top = newtop; }
23、在当前矩形区域的水平方向、垂直方向分别偏移dx、dy距离,即水平平移dx、垂直平移dy
public void inset(int dx, int dy) { left += dx; top += dy; right -= dx; bottom -= dy; }
24、在当前矩形区域的水平方向、垂直方向分别减少dx、dy距离,即缩小
public boolean contains(int x, int y) { return left < right && top < bottom // check for empty first && x >= left && x < right && y >= top && y < bottom; }
25、计算指定的坐标(x,y)是否包含在矩形区域范围内,包含返回true,否则返回false
public boolean contains(int left, int top, int right, int bottom) { // check for empty first return this.left < this.right && this.top < this.bottom // now check for containment && this.left <= left && this.top <= top && this.right >= right && this.bottom >= bottom; }
26、计算指定的left、top、right、bottom顶点是否包含在矩形区域范围内,包含返回true,否则返回false
public boolean contains(rect r) { // check for empty first return this.left < this.right && this.top < this.bottom // now check for containment && left <= r.left && top <= r.top && right >= r.right && bottom >= r.bottom; }
27、计算指定的rect是否包含在矩形区域范围内,包含返回true,否则返回false
public boolean intersect(int left, int top, int right, int bottom) { if (this.left < right && left < this.right && this.top < bottom && top < this.bottom) { if (this.left < left) this.left = left; if (this.top < top) this.top = top; if (this.right > right) this.right = right; if (this.bottom > bottom) this.bottom = bottom; return true; } return false; }
28、计算当前rect与指定的left、top、right、bottom顶点是否存在交集区域,存在返回true并且返回指定坐标,否则返回false
public boolean intersect(rect r) { return intersect(r.left, r.top, r.right, r.bottom); }
29、计算当前rect与指定的rect是否存在交集区域,存在返回true并且返回指定坐标,否则返回false
public boolean setintersect(rect a, rect b) { if (a.left < b.right && b.left < a.right && a.top < b.bottom && b.top < a.bottom) { left = math.max(a.left, b.left); top = math.max(a.top, b.top); right = math.min(a.right, b.right); bottom = math.min(a.bottom, b.bottom); return true; } return false; }
30、计算指定的a、b是否存在交集区域,存在返回true并且返回最大坐标,否则返回false
public boolean intersects(int left, int top, int right, int bottom) { return this.left < right && left < this.right && this.top < bottom && top < this.bottom; }
31、计算当前rect与指定的left、top、right、bottom顶点是否存在交集区域,存在返回true并且不返回指定坐标,否则返回false
public static boolean intersects(rect a, rect b) { return a.left < b.right && b.left < a.right && a.top < b.bottom && b.top < a.bottom; }
32、计算指定的a、b是否存在交集区域,存在返回true并且不返回最大坐标,否则返回false
public void union(int left, int top, int right, int bottom) { if ((left < right) && (top < bottom)) { if ((this.left < this.right) && (this.top < this.bottom)) { if (this.left > left) this.left = left; if (this.top > top) this.top = top; if (this.right < right) this.right = right; if (this.bottom < bottom) this.bottom = bottom; } else { this.left = left; this.top = top; this.right = right; this.bottom = bottom; } } }
33、计算当前rect与指定的left、top、right、bottom顶点是否存在并集区域,存在更新当前矩形区域,否则不更新
public void union(rect r) { union(r.left, r.top, r.right, r.bottom); }
34、计算当前rect与指定的rect是否存在并集区域,存在更新当前矩形区域,否则不更新
public void union(int x, int y) { if (x < left) { left = x; } else if (x > right) { right = x; } if (y < top) { top = y; } else if (y > bottom) { bottom = y; } }
35、计算当前rect与指定的坐标(x,y)是否存在并集区域,存在更新当前矩形区域,否则不更新
public void sort() { if (left > right) { int temp = left; left = right; right = temp; } if (top > bottom) { int temp = top; top = bottom; bottom = temp; } }
36、排序当前矩形区域,符合:left<right,top<bottom< p="" style="box-sizing: border-box;">
public void scale(float scale) { if (scale != 1.0f) { left = (int) (left * scale + 0.5f); top = (int) (top * scale + 0.5f); right = (int) (right * scale + 0.5f); bottom = (int) (bottom * scale + 0.5f); } }
37、按照指定的值缩放当前矩形区域
public void scaleroundin(float scale) { if (scale != 1.0f) { left = (int) math.ceil(left * scale); top = (int) math.ceil(top * scale); right = (int) math.floor(right * scale); bottom = (int) math.floor(bottom * scale); } }
38、按照指定的值缩放当前矩形区域
其它类似信息

推荐信息