Home > Java > javaTutorial > body text

In-depth understanding of the differences between RectF and Rect in Android development

伊谢尔伦
Release: 2017-01-16 13:12:56
Original
5431 people have browsed it

Rect means "rectangle or rectangle" in Chinese. The Rect object holds four integer coordinate values ​​​​of a rectangle, and the RectF object holds four float coordinate values ​​​​of a rectangle. This is the biggest difference between the two. From the perspective of implementation, Rect is a final class that implements the Parcelable interface, and RectF is an ordinary class that implements the Parcelable interface. Except for the different coordinate data types recorded, Rect and RectF provide generally the same methods. .

1. Contact:
are used to represent a rectangular area in the coordinate system, and some simple operations can be performed on it. This rectangular area needs to be represented by two coordinate points, the upper left and the lower right.
2. Difference:
(1). The accuracy is different. Rect uses int type as numerical value, and RectF uses float type as numerical value.
(2). The methods provided by the two types are not exactly the same.

3. Code part

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);
    }
}
Copy after login

RectF and Rect basics

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());  
    }  
});
Copy after login
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());  
    }  
});
Copy after login
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());  
    }  
});
Copy after login

It is precisely because each rectangular local area contains The four vertex coordinates of left, top, right and bottom, getLeft(), getTop(), getRight() and getBottom() belong to the methods declared by View, so each View subclass or control inherits the above methods, Rect or RectF is similar to one Tool class, encapsulates the calculation relationship of four vertex coordinates. When using getLeft(), getTop(), getRight() and getBottom(), you need to pay attention to two issues:

The first issue: getLeft(), getTop (), getRight() and getBottom() calculate the position relative to its parent container

Second question: getLeft(), getTop(), getRight() and getBottom() calculate the result to 0 because The current View subclass or control has not been drawn. The solution is to calculate when the onClick method is clicked or use the delay calculation of the thread

/** 
 * 延时获取控件相对父容器的left、top、right、bottom坐标,否则为0 
 */  
new Thread(new Runnable() {  
    @Override  
    public void run() {  
    try {  
        Thread.sleep(1000);  
    } catch (InterruptedException e) {  
        e.printStackTrace();  
    }  
    saveCoordinateToRect();  
    }  
}).start();
Copy after login

RectF and Rect in-depth

Rect is a final class and does not belong to Inherited, implements the Parcelable interface to perform serialization, and declares four integer attributes in the public scope: left, top, right, and bottom, which are used to record the four vertex coordinates of the View rectangular local area.

public Rect() {}
Copy after login

1. Create an empty Rect object. The default values ​​of left, top, right and bottom are 0

public Rect(int left, int top, int right, int bottom) {  
    this.left = left;  
    this.top = top;  
    this.right = right;  
    this.bottom = bottom;  
}
Copy after login

2. Create a Rect with specified coordinate values. Object, left, top, right and bottom are the specified values

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;  
    }  
}
Copy after login

3. Use the known Rect to create a new Rect object, left, top, right and bottom are the values ​​contained in the known 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;  
}
Copy after login

4. Determine whether the current Rect and the specified o are the same, the same conditions: belong to the same object or the left, top, right or bottom attribute values ​​of both are the same

@Override  
public int hashCode() {  
    int result = left;  
    result = 31 * result + top;  
    result = 31 * result + right;  
    result = 31 * result + bottom;  
    return result;  
}
Copy after login

5. Calculation The hash code of the Rect attribute value

@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();  
}
Copy after login

6. Return the four coordinate values ​​of the rectangle in the format of 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();  
}
Copy after login

7.With [left,top] The format of [right,bottom] returns the four coordinates of the rectangle, that is, the coordinates of the upper left corner and the lower right corner of the rectangular area

public String toShortString() {  
    return toShortString(new StringBuilder(32));  
}
Copy after login

8. The format of [left,top] [right,bottom] returns the four coordinates of the rectangle. Value, that is, the coordinates of the upper left corner and lower right corner of the rectangular area, the same as the above method

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();  
}
Copy after login

9. Return the four coordinate values ​​of the rectangle in the format of left top right bottom, that is, the tiled format, for example: 0 0 400 400 or 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)));  
}
Copy after login

10. Given a string in flat format, such as: 0 0 400 400, determine whether it is legal, and then convert it to a Rect object

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(']');  
}
Copy after login

11 . Write the attribute values ​​contained in Rect into the given PrintWriter stream in the format of [left, top] [right, bottom]

public final boolean isEmpty() {  
    return left >= right || top >= bottom;  
}
Copy after login

12. Determine whether Rect is an empty object, that is, whether the included attribute values ​​are Not 0

public final int width() {  
    return right - left;  
}
Copy after login

13. Calculate the width of the rectangular area

public final int height() {  
    return bottom - top;  
}
Copy after login

14. Calculate the height of the rectangular area

public final int centerX() {  
    return (left + right) >> 1;  
}
Copy after login

15. Calculate the horizontal center point of the rectangular area and calculate the result If it is a fraction, the nearest integer is returned, for example: the horizontal center point 400

public final int centerY() {  
    return (top + bottom) >> 1;  
}
Copy after login

16. Calculate the vertical center point of the rectangular area. If the calculation result is a fraction, the nearest integer is returned, for example: vertical Center point 850

public final float exactCenterX() {  
    return (left + right) * 0.5f;  
}
Copy after login

17. Calculate the horizontal center point of the rectangular area and return the result float type, for example: horizontal center point 400.0

public final float exactCenterY() {  
    return (top + bottom) * 0.5f;  
}
Copy after login

18. Calculate the vertical center point of the rectangular area and return the result float type, for example: vertical center point 850.0

public void setEmpty() {  
    left = right = top = bottom = 0;  
}
Copy after login

19. Set the attribute value contained in the Rect object to 0

public void set(int left, int top, int right, int bottom) {  
    this.left = left;  
    this.top = top;  
    this.right = right;  
    this.bottom = bottom;  
}
Copy after login

20. Set the attribute value of Rect to the specified value

public void set(Rect src) {  
    this.left = src.left;  
    this.top = src.top;  
    this.right = src.right;  
    this.bottom = src.bottom;  
}
Copy after login

21. Copy the attribute value contained in the specified Rect object

public void offset(int dx, int dy) {  
    left += dx;  
    top += dy;  
    right += dx;  
    bottom += dy;  
}
Copy after login

22. Increase the dx and dy distances in the horizontal and vertical directions of the current rectangular area, that is, expand

public void offsetTo(int newLeft, int newTop) {  
    right += newLeft - left;  
    bottom += newTop - top;  
    left = newLeft;  
    top = newTop;  
}
Copy after login

23. Offset dx and dy distances in the horizontal and vertical directions of the current rectangular area, that is, horizontal translation dx and vertical translation dy

public void inset(int dx, int dy) {  
    left += dx;  
    top += dy;  
    right -= dx;  
    bottom -= dy;  
}
Copy after login

24. Reduce dx in the horizontal and vertical directions of the current rectangular area respectively. , dy distance, that is, reducing

public boolean contains(int x, int y) {  
    return left < right && top < bottom  // check for empty first  
           && x >= left && x < right && y >= top && y < bottom;  
}
Copy after login

25. Calculate whether the specified coordinates (x, y) are included in the rectangular area, return true if included, otherwise return 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;  
}
Copy after login

26. Calculate the specified Whether the left, top, right, and bottom vertices are included in the rectangular area, return true if included, otherwise return 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;  
}
Copy after login

27. Calculate whether the specified Rect is included in the rectangular area, return true if included, otherwise Return 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;  
}
Copy after login

28. Calculate whether there is an intersection area between the current Rect and the specified left, top, right, and bottom vertices. Return true and return the specified coordinates, otherwise return false

public boolean intersect(Rect r) {  
    return intersect(r.left, r.top, r.right, r.bottom);  
}
Copy after login

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;  
}
Copy after login

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;  
}
Copy after login

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;  
}
Copy after login

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;  
        }  
    }  
}
Copy after login

33、计算当前Rect与指定的left、top、right、bottom顶点是否存在并集区域,存在更新当前矩形区域,否则不更新

public void union(Rect r) {  
    union(r.left, r.top, r.right, r.bottom);  
}
Copy after login

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;  
    }  
}
Copy after login

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;  
    }  
}
Copy after login

36、排序当前矩形区域,符合:left

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);  
    }  
}
Copy after login

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);  
    }  
}
Copy after login

38、按照指定的值缩放当前矩形区域


Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template