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

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

Jan 16, 2017 pm 01:12 PM

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);
    }
}
Salin selepas log masuk

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());  
    }  
});
Salin selepas log masuk
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());  
    }  
});
Salin selepas log masuk
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());  
    }  
});
Salin selepas log masuk

正是因为每一个矩形局域包含着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();
Salin selepas log masuk

RectF和Rect深入

Rect是一个final类,不属于被继承,实现Parcelable接口执行序列化,声明public作用域的四个整型属性:left、top、right和bottom,用来记录View矩形局域的四个顶点坐标。

public Rect() {}
Salin selepas log masuk

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;  
}
Salin selepas log masuk

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;  
    }  
}
Salin selepas log masuk

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;  
}
Salin selepas log masuk

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;  
}
Salin selepas log masuk

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();  
}
Salin selepas log masuk

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();  
}
Salin selepas log masuk

7、以[left,top] [right,bottom]的格式返回矩形四个坐标值,即矩形区域左上角和右下角坐标

public String toShortString() {  
    return toShortString(new StringBuilder(32));  
}
Salin selepas log masuk

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();  
}
Salin selepas log masuk

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)));  
}
Salin selepas log masuk

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(']');  
}
Salin selepas log masuk

11、将Rect包含的属性值以[left,top] [right,bottom]的格式写入给定的PrintWriter流中

public final boolean isEmpty() {  
    return left >= right || top >= bottom;  
}
Salin selepas log masuk

12、判断Rect是否一个空对象,即包含的属性值是否不为0

public final int width() {  
    return right - left;  
}
Salin selepas log masuk

13、计算矩形区域的宽度

public final int height() {  
    return bottom - top;  
}
Salin selepas log masuk

14、计算矩形区域的高度

public final int centerX() {  
    return (left + right) >> 1;  
}
Salin selepas log masuk

15、计算矩形区域的水平中心点,计算结果为分数则返回最接近的整型数,例如:水平中心点400

public final int centerY() {  
    return (top + bottom) >> 1;  
}
Salin selepas log masuk

16、计算矩形区域的垂直中心点,计算结果为分数则返回最接近的整型数,例如:垂直中心点850

public final float exactCenterX() {  
    return (left + right) * 0.5f;  
}
Salin selepas log masuk

17、计算矩形区域的水平中心点,返回结果float类型,例如:水平中心点400.0

public final float exactCenterY() {  
    return (top + bottom) * 0.5f;  
}
Salin selepas log masuk

18、计算矩形区域的垂直中心点,返回结果float类型,例如:垂直中心点850.0

public void setEmpty() {  
    left = right = top = bottom = 0;  
}
Salin selepas log masuk

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;  
}
Salin selepas log masuk

20、将Rect的属性值设置为指定的值

public void set(Rect src) {  
    this.left = src.left;  
    this.top = src.top;  
    this.right = src.right;  
    this.bottom = src.bottom;  
}
Salin selepas log masuk

21、复制指定的Rect对象包含的属性值

public void offset(int dx, int dy) {  
    left += dx;  
    top += dy;  
    right += dx;  
    bottom += dy;  
}
Salin selepas log masuk

22、在当前矩形区域的水平方向、垂直方向分别增加dx、dy距离,即扩展

public void offsetTo(int newLeft, int newTop) {  
    right += newLeft - left;  
    bottom += newTop - top;  
    left = newLeft;  
    top = newTop;  
}
Salin selepas log masuk

23、在当前矩形区域的水平方向、垂直方向分别偏移dx、dy距离,即水平平移dx、垂直平移dy

public void inset(int dx, int dy) {  
    left += dx;  
    top += dy;  
    right -= dx;  
    bottom -= dy;  
}
Salin selepas log masuk

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;  
}
Salin selepas log masuk

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;  
}
Salin selepas log masuk

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;  
}
Salin selepas log masuk

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;  
}
Salin selepas log masuk

28、计算当前Rect与指定的left、top、right、bottom顶点是否存在交集区域,存在返回true并且返回指定坐标,否则返回false

public boolean intersect(Rect r) {  
    return intersect(r.left, r.top, r.right, r.bottom);  
}
Salin selepas log masuk

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;  
}
Salin selepas log masuk

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;  
}
Salin selepas log masuk

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;  
}
Salin selepas log masuk

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;  
        }  
    }  
}
Salin selepas log masuk

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

public void union(Rect r) {  
    union(r.left, r.top, r.right, r.bottom);  
}
Salin selepas log masuk

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;  
    }  
}
Salin selepas log masuk

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;  
    }  
}
Salin selepas log masuk

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);  
    }  
}
Salin selepas log masuk

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);  
    }  
}
Salin selepas log masuk

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


Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Arahan sembang dan cara menggunakannya
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Bagaimanakah mekanisme kelas muatan Java berfungsi, termasuk kelas yang berbeza dan model delegasi mereka? Bagaimanakah mekanisme kelas muatan Java berfungsi, termasuk kelas yang berbeza dan model delegasi mereka? Mar 17, 2025 pm 05:35 PM

Kelas kelas Java melibatkan pemuatan, menghubungkan, dan memulakan kelas menggunakan sistem hierarki dengan bootstrap, lanjutan, dan pemuat kelas aplikasi. Model delegasi induk memastikan kelas teras dimuatkan dahulu, yang mempengaruhi LOA kelas tersuai

Bagaimanakah saya melaksanakan caching pelbagai peringkat dalam aplikasi java menggunakan perpustakaan seperti kafein atau cache jambu? Bagaimanakah saya melaksanakan caching pelbagai peringkat dalam aplikasi java menggunakan perpustakaan seperti kafein atau cache jambu? Mar 17, 2025 pm 05:44 PM

Artikel ini membincangkan pelaksanaan caching pelbagai peringkat di Java menggunakan kafein dan cache jambu untuk meningkatkan prestasi aplikasi. Ia meliputi persediaan, integrasi, dan faedah prestasi, bersama -sama dengan Pengurusan Dasar Konfigurasi dan Pengusiran PRA Terbaik

Bagaimanakah saya boleh menggunakan JPA (Java Constence API) untuk pemetaan objek-objek dengan ciri-ciri canggih seperti caching dan malas malas? Bagaimanakah saya boleh menggunakan JPA (Java Constence API) untuk pemetaan objek-objek dengan ciri-ciri canggih seperti caching dan malas malas? Mar 17, 2025 pm 05:43 PM

Artikel ini membincangkan menggunakan JPA untuk pemetaan objek-relasi dengan ciri-ciri canggih seperti caching dan pemuatan malas. Ia meliputi persediaan, pemetaan entiti, dan amalan terbaik untuk mengoptimumkan prestasi sambil menonjolkan potensi perangkap. [159 aksara]

Bagaimanakah saya menggunakan Maven atau Gradle untuk Pengurusan Projek Java Lanjutan, Membina Automasi, dan Resolusi Ketergantungan? Bagaimanakah saya menggunakan Maven atau Gradle untuk Pengurusan Projek Java Lanjutan, Membina Automasi, dan Resolusi Ketergantungan? Mar 17, 2025 pm 05:46 PM

Artikel ini membincangkan menggunakan Maven dan Gradle untuk Pengurusan Projek Java, membina automasi, dan resolusi pergantungan, membandingkan pendekatan dan strategi pengoptimuman mereka.

Bagaimanakah saya membuat dan menggunakan perpustakaan Java Custom (fail JAR) dengan pengurusan versi dan pergantungan yang betul? Bagaimanakah saya membuat dan menggunakan perpustakaan Java Custom (fail JAR) dengan pengurusan versi dan pergantungan yang betul? Mar 17, 2025 pm 05:45 PM

Artikel ini membincangkan membuat dan menggunakan perpustakaan Java tersuai (fail balang) dengan pengurusan versi dan pergantungan yang betul, menggunakan alat seperti Maven dan Gradle.

See all articles