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()); } });
それは、各長方形のローカル領域に、左、上、右、下の 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() {}
public Rect(int left, int top, int right, int bottom) { this.left = left; this.top = top; this.right = right; this.bottom = 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; } }
@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; }
@Override public int hashCode() { int result = left; result = 31 * result + top; result = 31 * result + right; result = 31 * result + bottom; return result; }
@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(); }
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(); }
public String toShortString() { return toShortString(new StringBuilder(32)); }
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(); }
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))); }
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(']'); }
public final boolean isEmpty() { return left >= right || top >= bottom; }
public final int width() { return right - left; }
public final int height() { return bottom - top; }
public final int centerX() { return (left + right) >> 1; }
public final int centerY() { return (top + bottom) >> 1; }
public final float exactCenterX() { return (left + right) * 0.5f; }
public final float exactCenterY() { return (top + bottom) * 0.5f; }
public void setEmpty() { left = right = top = bottom = 0; }
public void set(int left, int top, int right, int bottom) { this.left = left; this.top = top; this.right = right; this.bottom = bottom; }
public void set(Rect src) { this.left = src.left; this.top = src.top; this.right = src.right; this.bottom = src.bottom; }
public void offset(int dx, int dy) { left += dx; top += dy; right += dx; bottom += dy; }
public void offsetTo(int newLeft, int newTop) { right += newLeft - left; bottom += newTop - top; left = newLeft; top = newTop; }
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、按照指定的值缩放当前矩形区域