ホームページ > Java > &#&チュートリアル > Android 開発における RectF と Rect の違いを深く理解する

Android 開発における RectF と Rect の違いを深く理解する

伊谢尔伦
リリース: 2017-01-16 13:12:56
オリジナル
5467 人が閲覧しました

Rect は中国語で「長方形または長方形」を意味します。 Rect オブジェクトは長方形の 4 つの整数座標値を保持します。RectF オブジェクトは長方形の 4 つの浮動小数点座標値を保持します。これが最大の違いです。二つ。実装の観点から見ると、Rect は Parcelable インターフェイスを実装する最終クラスであり、RectF は Parcelable インターフェイスを実装する通常のクラスです。記録される座標データ型が異なることを除けば、Rect と RectF は一般に同じメソッドを提供します。

1. 接続:
は座標系の長方形の領域を表すために使用され、それに対していくつかの簡単な操作を実行できます。この長方形の領域は、左上と右下の 2 つの座標点で表す必要があります。
2. 違い:
(1) 精度が異なります。 Rectは数値としてint型を使用し、RectFは数値としてfloat型を使用します。
(2). 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());  
    }  
});
ログイン後にコピー
rree

それは、各長方形のローカル領域に、左、上、右、下の 4 つの頂点座標、getLeft()、getTop()、getRight が含まれているためです。 () と getBottom() は View によって宣言されたメソッドであるため、各 View サブクラスまたはコントロールは上記のメソッドを継承し、getLeft()、getTop() を使用して 4 つの頂点座標の計算関係をカプセル化するツール クラスに似ています。 getRight() と getBottom() は 2 つの問題に注意する必要があります:

最初の問題: getLeft()、getTop()、getRight() および getBottom() は親コンテナに対する相対的な位置を計算します

2 つ目の問題: 現在の View サブクラスまたはコントロールが描画されていないため、getLeft()、getTop()、getRight()、getBottom() の計算結果は 0 になります。解決策は、onClick メソッドがクリックされたときに遅延計算を計算するか、スレッドの遅延計算を使用することです

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());  
    }  
});
ログイン後にコピー

RectF と Rect を詳細に使用することです

Rect は最終クラスであり、実行する Parcelable インターフェイスを実装しています。シリアル化してパブリック スコープを宣言します。left、top、right、bottom の 4 つの整数属性は、ビューの長方形領域の 4 つの頂点座標を記録するために使用されます。

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

1. 空の Rect オブジェクトを作成します。 left、top、right、bottom のデフォルト値は 0 です。

public Rect() {}
ログイン後にコピー

2. 指定された座標値で Rect オブジェクトを作成します。は、指定された値です。 3. 既知の Rect を使用して、新しい Rect オブジェクトを作成します。 left、top、right、bottom は、現在の Rect と、条件:同じオブジェクトに属する、または両方の左、上、右、下の属性値が同じ

public Rect(int left, int top, int right, int bottom) {  
    this.left = left;  
    this.top = top;  
    this.right = right;  
    this.bottom = bottom;  
}
ログイン後にコピー

5. Rect属性値のハッシュコードを計算する

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;  
    }  
}
ログイン後にコピー

6. Rect(left,top-right,bottom)を使用し、四角形の4つの座標値を返します

@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;  
}
ログイン後にコピー

7。 四角形の4つの座標値を[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;  
}
ログイン後にコピー

8の形式で、[左、上]、[右、下]の4つの座標値を返します。長方形、つまり長方形領域の左上隅と右下隅の座標。上記のメソッド

@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();  
}
ログイン後にコピー

9と同様に、長方形の4つの座標値を左上右下の形式で返します。 、つまり、0 0 400 400 または 100 100 800 300

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();  
}
ログイン後にコピー

10 などのタイル形式です。 0 0 400 400 などのタイル形式の文字列を指定して、それが正当であるかどうかを判断し、それをRect オブジェクト

public String toShortString() {  
    return toShortString(new StringBuilder(32));  
}
ログイン後にコピー

11. Rect に含まれる属性値を [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();  
}
ログイン後にコピー

12. Rect が空のオブジェクトかどうかを判断します。含まれる属性値が 0 ではない

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)));  
}
ログイン後にコピー

13. 長方形領域の幅を計算します

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(']');  
}
ログイン後にコピー

15. 計算結果が長方形領域の水平方向の中心点を計算します。が分数の場合は、最も近い整数を返します。例: 水平方向の中心点 400

public final boolean isEmpty() {  
    return left >= right || top >= bottom;  
}
ログイン後にコピー

16。 計算結果が分数の場合、最も近い整数を返します。例: 垂直方向の中心点。 point 850

public final int width() {  
    return right - left;  
}
ログイン後にコピー

17. 長方形領域の水平方向の中心点を計算し、結果を返します。例: 水平方向の中心点 400.0

public final int height() {  
    return bottom - top;  
}
ログイン後にコピー

18. 長方形領域の垂直方向の中心点を計算し、結果を返します。例: 垂直中心点 850.0

public final int centerX() {  
    return (left + right) >> 1;  
}
ログイン後にコピー

19。Rect オブジェクトに含まれる属性値を 0

public final int centerY() {  
    return (top + bottom) >> 1;  
}
ログイン後にコピー

20 に設定します。Rect の属性値を指定された値

public final float exactCenterX() {  
    return (left + right) * 0.5f;  
}
ログイン後にコピー

21 に設定します。指定された Rect オブジェクト内で

public final float exactCenterY() {  
    return (top + bottom) * 0.5f;  
}
ログイン後にコピー

22. 現在の長方形領域の水平方向と垂直方向の dx 距離と dy 距離を増加します。つまり、領域の水平方向と垂直方向の dx 距離と dy 距離をオフセットします。現在の長方形領域、つまり dx を水平方向に移動し、垂直方向に移動します dy

public void setEmpty() {  
    left = right = top = bottom = 0;  
}
ログイン後にコピー

24。現在の長方形領域の水平方向と垂直方向にそれぞれ dx を減らし、つまり

public void set(int left, int top, int right, int bottom) {  
    this.left = left;  
    this.top = top;  
    this.right = right;  
    this.bottom = bottom;  
}
ログイン後にコピー

25 を計算します。指定された座標(x,y)が長方形領域に含まれる場合はtrueを返し、そうでない場合はfalseを返す

public void set(Rect src) {  
    this.left = src.left;  
    this.top = src.top;  
    this.right = src.right;  
    this.bottom = src.bottom;  
}
ログイン後にコピー

26. 指定された頂点が長方形領域に含まれるかどうかを計算し、含まれる場合はtrueを返します。含まれている場合は false を返します

public void offset(int dx, int dy) {  
    left += dx;  
    top += dy;  
    right += dx;  
    bottom += dy;  
}
ログイン後にコピー

27。 指定された Rect が長方形領域に含まれるかどうかを計算し、含まれている場合は true を返し、そうでない場合は false を返します

public void offsetTo(int newLeft, int newTop) {  
    right += newLeft - left;  
    bottom += newTop - top;  
    left = newLeft;  
    top = newTop;  
}
ログイン後にコピー

28。左、上、右、下の頂点は 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

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、按照指定的值缩放当前矩形区域


関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート