Rect bedeutet auf Chinesisch „Rechteck oder Rechteck“. Das Rect-Objekt enthält vier ganzzahlige Koordinatenwerte eines Rechtecks, und das RectF-Objekt enthält vier Float-Koordinatenwerte eines Rechtecks Unterschied zwischen den beiden. Aus Sicht der Implementierung ist Rect eine endgültige Klasse, die die Parcelable-Schnittstelle implementiert, und RectF ist eine gewöhnliche Klasse, die die Parcelable-Schnittstelle implementiert. Mit Ausnahme der unterschiedlichen aufgezeichneten Koordinatendatentypen stellen Rect und RectF im Allgemeinen dieselben Methoden bereit.
1. Kontakt:
werden verwendet, um einen rechteckigen Bereich im Koordinatensystem darzustellen, und einige einfache Operationen können darauf ausgeführt werden. Dieser rechteckige Bereich muss durch zwei Koordinatenpunkte dargestellt werden: oben links und unten rechts.
2. Unterschied:
(1) Die Genauigkeit ist unterschiedlich. Rect verwendet den Typ „int“ als numerischen Wert und RectF verwendet den Typ „float“ als numerischen Wert.
(2). Die von den beiden Typen bereitgestellten Methoden sind nicht vollständig konsistent.
3. Codeteil
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- und Rect-Grundlagen
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()); } });
Gerade weil jeder rechteckige lokale Bereich vier Scheitelpunktkoordinaten links, oben, rechts und unten enthält, gehören getLeft (), getTop (), getRight () und getBottom () zu den von View deklarierten Methoden, sodass jede View-Unterklasse oder The Die Steuerung erbt die obige Methode. Rect oder RectF ähneln einer Werkzeugklasse und kapseln die Berechnungsbeziehung von vier Scheitelpunktkoordinaten. Bei der Verwendung von getLeft(), getTop(), getRight() und getBottom() sind zwei Probleme zu beachten. :
Die erste Frage: getLeft(), getTop(), getRight() und getBottom() berechnen die Position relativ zu seinem übergeordneten Container
Die zweite Frage: getLeft(), getTop( ), getRight() und Das Berechnungsergebnis von getBottom() ist 0, da die aktuelle View-Unterklasse oder das aktuelle View-Steuerelement nicht gezeichnet wurde. Die Lösung besteht darin, zu berechnen, wann die onClick-Methode angeklickt wird, oder die Verzögerungsberechnung des Threads zu verwenden
/** * 延时获取控件相对父容器的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 und Rect gehen tief
Rect ist Eine endgültige Klasse. Sie implementiert die Parcelable-Schnittstelle zur Durchführung der Serialisierung und deklariert vier ganzzahlige Attribute im öffentlichen Bereich: links, oben, rechts und unten, die zum Aufzeichnen der vier Scheitelpunktkoordinaten des rechteckigen lokalen Bereichs verwendet werden .
public Rect() {}
1. Erstellen Sie ein leeres Rect-Objekt. Die Standardwerte für links, oben, rechts und unten sind 0
public Rect(int left, int top, int right, int bottom) { this.left = left; this.top = top; this.right = right; this.bottom = bottom; }
2 ein angegebenes Rect-Objekt mit Koordinatenwert, links, oben, rechts und unten sind angegebene Werte
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. Verwenden Sie das bekannte Rect, um ein neues Rect-Objekt zu erstellen, links, oben, rechts und unten sind bekannt Der in Rect enthaltene Wert
@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. Bestimmen Sie, ob das aktuelle Rect und das angegebene o gleich sind und dieselben Bedingungen erfüllen: zum selben Objekt oder zu den linken, oberen, rechten oder unteren Attributwerten gehören von beiden sind gleich
@Override public int hashCode() { int result = left; result = 31 * result + top; result = 31 * result + right; result = 31 * result + bottom; return result; }
Berechnen Sie den Hash-Code des Rect-Attributwerts
@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. Geben Sie die vier Koordinatenwerte des Rechtecks zurück Format von Rect (links, oben rechts, unten)
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 Gibt die vier Koordinatenwerte des Rechtecks im Format [links, oben] [rechts, unten] zurück , die Koordinaten der oberen linken Ecke und der unteren rechten Ecke des rechteckigen Bereichs
public String toShortString() { return toShortString(new StringBuilder(32)); }
8. Im Format von [links, oben] [rechts, unten] Das Format von links, oben] [rechts ,bottom] gibt die vier Koordinatenwerte des Rechtecks zurück, dh die Koordinaten der oberen linken Ecke und der unteren rechten Ecke des rechteckigen Bereichs, genau wie bei der obigen Methode
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. Im Format von links oben rechts unten werden die vier Koordinatenwerte des Rechtecks zurückgegeben, d B.: 0 0 400 400, bestimmen Sie, ob sie zulässig ist, und konvertieren Sie sie dann in ein Rect-Objekt
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))); }
11. Schreiben Sie die in Rect enthaltenen Attributwerte in der angegebene PrintWriter-Stream im Format [links, oben] [rechts, unten]
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(']'); }
12. Bestimmen Sie, ob Rect ein leeres Objekt ist, d. h. ob der darin enthaltene Attributwert nicht 0 ist
public final boolean isEmpty() { return left >= right || top >= bottom; }
13. Berechnen Sie die Breite des rechteckigen Bereichs
public final int width() { return right - left; }
14. Berechnen Sie die Höhe des rechteckigen Bereichs
public final int height() { return bottom - top; }
15 Wenn das Berechnungsergebnis ein Bruch ist, wird die nächste ganze Zahl zurückgegeben, zum Beispiel: horizontaler Mittelpunkt 400
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 void inset(int dx, int dy) { left += dx; top += dy; right -= dx; bottom -= 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; }
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; }
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、按照指定的值缩放当前矩形区域