


Compréhension approfondie des différences entre RectF et Rect dans le développement Android
Rect signifie "rectangle ou rectangle" en chinois. L'objet Rect contient quatre valeurs de coordonnées entières d'un rectangle, et l'objet RectF contient quatre valeurs de coordonnées flottantes d'un rectangle. différence entre les deux. Du point de vue de l'implémentation, Rect est une classe finale qui implémente l'interface Parcelable, et RectF est une classe ordinaire qui implémente l'interface Parcelable, à l'exception des différents types de données de coordonnées enregistrées, Rect et RectF fournissent généralement les mêmes méthodes.
1. Contact :
sont utilisés pour représenter une zone rectangulaire dans le système de coordonnées, et certaines opérations simples peuvent être effectuées dessus. Cette zone rectangulaire doit être représentée par deux points de coordonnées, le coin supérieur gauche et le coin inférieur droit.
2. Différence :
(1). Rect utilise le type int comme valeur numérique et RectF utilise le type float comme valeur numérique.
(2). Les méthodes fournies par les deux types ne sont pas complètement cohérentes.
3. Partie code
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); } }
Bases de RectF et 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()); } });
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()); } });
C'est précisément parce que chaque zone locale rectangulaire contient quatre coordonnées de sommet de gauche, haut, droite et bas, getLeft(), getTop(), getRight() et getBottom() appartiennent aux méthodes déclarées par View, donc chaque sous-classe View ou The Le contrôle hérite de la méthode ci-dessus. Rect ou RectF est similaire à une classe d'outils, encapsulant la relation de calcul de quatre coordonnées de sommet. Il y a deux problèmes à prendre en compte lors de l'utilisation de getLeft(), getTop(), getRight() et getBottom(). :
La première question : getLeft(), getTop(), getRight() et getBottom() calculent la position par rapport à son conteneur parent
La deuxième question : getLeft(), getTop( ), getRight() et Le résultat du calcul de getBottom() est 0 car la sous-classe ou le contrôle View actuel n'a pas été dessiné. La solution est de calculer le moment où l'on clique sur la méthode onClick ou d'utiliser le calcul du délai du 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();
RectF et Rect vont en profondeur
Rect est une classe finale. Elle n'est pas héritée. Elle implémente l'interface Parcelable pour effectuer la sérialisation et déclare quatre attributs entiers dans la portée publique : left, top, right et bottom, qui sont utilisés pour enregistrer les quatre coordonnées de sommet de la zone locale rectangulaire View. .
public Rect() {}
1. Créez un objet Rect vide. Les valeurs par défaut de gauche, haut, droite et bas sont 0
public Rect(int left, int top, int right, int bottom) { this.left = left; this.top = top; this.right = right; this.bottom = bottom; }
2. un objet Rect spécifié de valeur de coordonnée, gauche, haut, droite et bas sont des valeurs spécifiées
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. Utilisez le Rect connu pour créer un nouvel objet Rect, gauche, haut, droite et bas sont connu La valeur contenue dans 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; }
4. Déterminez si le Rect actuel et le o spécifié sont identiques, les mêmes conditions : appartiennent au même objet ou aux valeurs d'attribut gauche, haut, droite ou bas. des deux sont identiques
@Override public int hashCode() { int result = left; result = 31 * result + top; result = 31 * result + right; result = 31 * result + bottom; return result; }
5. Calculez le code de hachage de la valeur de l'attribut 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(); }
6. Renvoyez les quatre valeurs de coordonnées du rectangle dans le format de Rect (gauche, haut-droit, bas)
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. Renvoie les quatre valeurs de coordonnées du rectangle au format [gauche, haut] [droite, bas], c'est-à-dire , les coordonnées du coin supérieur gauche et du coin inférieur droit de la zone rectangulaire
public String toShortString() { return toShortString(new StringBuilder(32)); }
8 Au format [gauche, haut] [droite, bas] Le format gauche, haut] [droite. ,bottom] renvoie les quatre valeurs de coordonnées du rectangle, c'est-à-dire les coordonnées du coin supérieur gauche et du coin inférieur droit de la zone rectangulaire, les mêmes que la méthode ci-dessus
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. Au format gauche en haut à droite en bas Renvoie les quatre valeurs de coordonnées du rectangle, c'est-à-dire le format carrelé, tel que : 0 0 400 400 ou 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))); }
10. une chaîne au format carrelé, tel que : 0 0 400 400, déterminez si elle est légale, puis convertissez-la en un objet 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(']'); }
11. Écrivez les valeurs d'attribut contenues dans Rect dans le flux PrintWriter donné au format [gauche, haut] [droite, bas]
public final boolean isEmpty() { return left >= right || top >= bottom; }
12. Déterminez si Rect est un objet vide, c'est-à-dire si la valeur d'attribut qu'il contient n'est pas 0<. 🎜>
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 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 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; }
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; }
.
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、按照指定的值缩放当前矩形区域

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Le chargement de classe de Java implique le chargement, la liaison et l'initialisation des classes à l'aide d'un système hiérarchique avec Bootstrap, Extension et Application Classloaders. Le modèle de délégation parent garantit que les classes de base sont chargées en premier, affectant la classe de classe personnalisée LOA

L'article examine la mise en œuvre de la mise en cache à plusieurs niveaux en Java à l'aide de la caféine et du cache de goyave pour améliorer les performances de l'application. Il couvre les avantages de configuration, d'intégration et de performance, ainsi que la gestion de la politique de configuration et d'expulsion le meilleur PRA

L'article discute de l'utilisation de JPA pour la cartographie relationnelle des objets avec des fonctionnalités avancées comme la mise en cache et le chargement paresseux. Il couvre la configuration, la cartographie des entités et les meilleures pratiques pour optimiser les performances tout en mettant en évidence les pièges potentiels. [159 caractères]

L'article discute de l'utilisation de Maven et Gradle pour la gestion de projet Java, la construction de l'automatisation et la résolution de dépendance, en comparant leurs approches et leurs stratégies d'optimisation.
