我必须在每个圆圈中画一个带数字的圆圈.
我的问题是我无法将文本置于我想要的中心.
为什么中心绘制文字与绘制线条的中心不一样???
我的问题是我无法将文本置于我想要的中心.
为什么中心绘制文字与绘制线条的中心不一样???
sfdzqgs
fsdgf dsbfd ds ds fdg sfgnfhggdf wdvfbdfsf dsgfhdr sdgfdshstqRSSgqg sqfgshdf dgerfztiaruhisrguhtrqiorgeuqzengohbçzioqrgethriZQGEHOQRAGIRGOGfjfnfgkjkjvfrejneofnbfoig vjlj vvjfndbjfdnj figsn
/*enter code here * Author : * date : 06/12/2013 * * * enter code here */ package com.example.ando_dessin_test; //merci a http://supertos.free.fr/supertos.PHP?page=1066 import java.util.Random; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Align; import android.graphics.Paint.Style; import android.os.Bundle; import android.view.View; import android.view.Window; import android.view.WindowManager; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Desactiver la barre de titre de notre application requestWindowFeature(Window.FEATURE_NO_TITLE); // Passer la fenêtre en full-creen == cacher la barre de notification getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(new RenderView(this)); } // Création d'une classe interne RenderView pour gérer un affichage simple // permettant // de montrer que nous occupons bien tout l'écran class RenderView extends View { public RenderView(Context context) { super(context); } // Dessinons sur la totalité de l'écran protected void onDraw(Canvas canvas) { canvas.drawRGB(0,0); // Instance de Paint pour définir l'attribut couleur de notre point,// ainsi que // sa taille. Paint paint = new Paint(); // Nous allons dessiner nos points par rapport à la résolution de // l'écran int iWidth = canvas.getWidth(); // Largeur int iHeight = canvas.getHeight(); // Hauteur // float radius = 0;//Radius caused an error so I initialized this // variable Random rand = new Random(); // j'ai l'impression detre dans les etoiles avec ces petits points // Affichons 10000 points de toutes les couleurs for (int i = 0; i < 10000; i++) { // Affecter une couleur de manière aléatoire paint.setARGB(255,rand.nextInt(256),rand.nextInt(256)); // Puis dessiner nos points dans le canevas canvas.drawPoint(rand.nextInt(iWidth),rand.nextInt(iHeight),paint); } // aficchons notre fameux cercle // Canvas canvas = new Canvas(); Paint circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG); circlePaint.setColor(Color.RED); circlePaint.setStyle(Style.STROKE); circlePaint.setStrokeWidth(10); float rayonDuCercle = canvas.getWidth() / 2; canvas.drawCircle((float) canvas.getWidth() / 2,(float) canvas.getHeight() / 2,rayonDuCercle,circlePaint); float rayonDuCerclePetit = canvas.getWidth() / 6; canvas.drawCircle((float) canvas.getWidth() / 2,rayonDuCerclePetit,circlePaint); /* * // Random rand = new Random(); //Affichons 100 segments de toutes * les couleurs for (int i=0; i < 100; i++) { // Affecter une * couleur de manière aléatoire paint.setARGB(255,* rand.nextInt(256),rand.nextInt(256)); // * Définir l'épaisseur du segment paint.setStrokeWidth * (rand.nextInt(10)); // Puis dessiner nos points dans le cavenas * canvas.drawLine(rand.nextInt(iWidth),* rand.nextInt(iWidth),paint); } */ paint.setARGB(255,rand.nextInt(256)); // Définir l'épaisseur du segment paint.setStrokeWidth(2); // Puis dessiner nos points dans le cavenas // okcanvas.drawLine((float)((float)Math.cos(0)*rayonDuCerclePetit)+canvas.getWidth()/2,// canvas.getHeight()/2,canvas.getWidth()/2+rayonDuCercle,paint); // okcanvas.drawLine((float)((float)Math.cos(Math.PI/2)*rayonDuCerclePetit)+canvas.getWidth()/2,// ((float)Math.sin(Math.PI/2)*rayonDuCerclePetit)+canvas.getHeight()/2,canvas.getWidth()/2+rayonDuCercle*(float)Math.cos(Math.PI/2),// rayonDuCercle*(float)Math.sin(Math.PI/2)+canvas.getHeight()/2,// paint); // okkk // canvas.drawLine((float)((float)Math.cos(Math.PI/4)*rayonDuCerclePetit)+canvas.getWidth()/2,// ((float)Math.sin(Math.PI/4)*rayonDuCerclePetit)+canvas.getHeight()/2,canvas.getWidth()/2+rayonDuCercle*(float)Math.cos(Math.PI/4),// rayonDuCercle*(float)Math.sin(Math.PI/4)+canvas.getHeight()/2,// paint); // initPaint(paint,); // pourquoi j'utilise 2 boucles ? Parce que pour limiter l'espace // memoire j'utilise le même canva et la seul difference entre ces // deux element est la couleur. // cette boucle affiche des rayons for (int i = 0; i < 8; i++) { setRayon(canvas,(Math.PI / 4) * i,paint,rayonDuCerclePetit); } paint.setTextAlign(Align.RIGHT); // cette boucle affichage du texte for (int i = 1; i < 9; i++) { setText(canvas,String.valueOf(i),rayonDuCercle * 0.7,80); // si je suis le dernier element j'affiche le 9 du centre if (i == 8) { paint.setTextAlign(Align.CENTER); setText(canvas,String.valueOf(i + 1),(Math.PI / 4) * i,rayonDuCercle * 0,80); } } } /* * info pour unen raison que j'ai pas chercher a comprendre l'angle * positif s'affiche comme si c'été un ange negatif . Donc je bidouille * en multipliant l'angle par -1 */ void setRayon(Canvas canvas,double angleRad,Paint paint,float rayonDuCercle,float rayonDuCerclePetit) { // angleRad=angleRad*-1; angleRad = (Math.toRadians((double) 70) + angleRad) * -1; canvas.drawLine( (float) ((float) Math.cos(angleRad) * rayonDuCerclePetit) + canvas.getWidth() / 2,((float) Math.sin(angleRad) * rayonDuCerclePetit) + canvas.getHeight() / 2,canvas.getWidth() / 2 + rayonDuCercle * (float) Math.cos(angleRad),rayonDuCercle * (float) Math.sin(angleRad) + canvas.getHeight() / 2,paint); } /* * info pour unen raison que j'ai pas chercher a comprendre l'angle * positif s'affiche comme si c'été un ange negatif . Donc je bidouille * en multipliant l'angle par -1 */ void setText(Canvas canvas,String Txt,double rayonTxt,int sizeText) { paint.setColor(Color.WHITE); paint.setTextSize(sizeText); angleRad = (Math.toRadians((double) 50) + angleRad) * -1; // axe des ordonees enhaut a gauche -> canvas.drawText(Txt,(float) // Math.cos(angleRad)*(float) rayonTxt,// (float)Math.sin(angleRad)*(float) rayonTxt,paint); // ligne suivante j'ai centree l'axe canvas.drawText(Txt,(float) Math.cos(angleRad) * (float) rayonTxt + canvas.getWidth() / 2,(float) Math.sin(angleRad) * (float) rayonTxt + canvas.getHeight() / 2,paint); } /* * private void initPaint(Paint paint,Drawable drawable,float * textHeight,float baselineOffset) { paint = new Paint(); * paint.setStyle(Paint.Style.STROKE); paint.setColor(Color.BLUE); paint * = new Paint(); paint.setStyle(Paint.Style.FILL_AND_STROKE); * paint.setAntiAlias(true); paint.setColor(Color.WHITE); * paint.setTextSize(30); paint.setTextAlign(Align.CENTER); FontMetrics * fontMetrics = paint.getFontMetrics(); baselineOffset = * fontMetrics.bottom; // bottom is the maximum amount that the text * descends // I'm not sure why this is different from descent... * textHeight = fontMetrics.bottom - fontMetrics.top; // drawable = * getResources().getDrawable(R.drawable.ic_launcher); } */ } }
解决方法
回答这个问题我很开心,这是我最后的努力:
第一张图片仅用于测试和确定额外填充的empical值;第二个是删除额外代码后的最终产品.
圆形的错觉几乎是完美的(对于人眼来说,我猜)
这是修改后的布局,activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:background="#f000" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" android:id="@+id/bg" > <TextView android:id="@+id/txt9" android:layout_width="160dp" android:layout_height="160dp" android:layout_centerInParent="true" android:gravity="center" android:text="9" android:textSize="40sp" android:textStyle="bold" android:textColor="#ffff" /> <TextView android:id="@+id/txt1" android:layout_width="80dp" android:layout_height="80dp" android:layout_above="@id/txt9" android:layout_alignLeft="@id/txt9" android:paddingRight="12dp" android:paddingTop="12dp" android:gravity="center" android:text="1" android:textSize="40sp" android:textStyle="bold" android:textColor="#ffff" /> <TextView android:id="@+id/txt8" android:layout_width="80dp" android:layout_height="80dp" android:layout_alignTop="@id/txt1" android:layout_toRightOf="@id/txt1" android:paddingLeft="12dp" android:paddingTop="12dp" android:gravity="center" android:text="8" android:textSize="40sp" android:textStyle="bold" android:textColor="#ffff" /> <TextView android:id="@+id/txt2" android:layout_width="80dp" android:layout_height="80dp" android:layout_alignTop="@id/txt9" android:layout_toLeftOf="@id/txt9" android:paddingLeft="12dp" android:paddingBottom="12dp" android:gravity="center" android:text="2" android:textSize="40sp" android:textStyle="bold" android:textColor="#ffff" /> <TextView android:id="@+id/txt3" android:layout_width="80dp" android:layout_height="80dp" android:layout_below="@id/txt2" android:layout_toLeftOf="@id/txt9" android:paddingLeft="12dp" android:paddingTop="12dp" android:gravity="center" android:text="3" android:textSize="40sp" android:textStyle="bold" android:textColor="#ffff" /> <TextView android:id="@+id/txt4" android:layout_width="80dp" android:layout_height="80dp" android:layout_below="@id/txt9" android:layout_alignLeft="@id/txt9" android:paddingRight="12dp" android:paddingBottom="12dp" android:gravity="center" android:text="4" android:textSize="40sp" android:textStyle="bold" android:textColor="#ffff" /> <TextView android:id="@+id/txt5" android:layout_width="80dp" android:layout_height="80dp" android:layout_alignTop="@id/txt4" android:layout_toRightOf="@id/txt4" android:paddingLeft="12dp" android:paddingBottom="12dp" android:gravity="center" android:text="5" android:textSize="40sp" android:textStyle="bold" android:textColor="#ffff" /> <TextView android:id="@+id/txt7" android:layout_width="80dp" android:layout_height="80dp" android:layout_alignTop="@id/txt9" android:layout_toRightOf="@id/txt9" android:paddingRight="12dp" android:paddingBottom="12dp" android:gravity="center" android:text="7" android:textSize="40sp" android:textStyle="bold" android:textColor="#ffff" /> <TextView android:id="@+id/txt6" android:layout_width="80dp" android:layout_height="80dp" android:layout_below="@id/txt7" android:layout_toRightOf="@id/txt9" android:paddingRight="12dp" android:paddingTop="12dp" android:gravity="center" android:text="6" android:textSize="40sp" android:textStyle="bold" android:textColor="#ffff" /> </RelativeLayout>
这是更新的代码(您将获得更多优化),MainActivity.java
package com.example.numbers; import java.util.Random; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Style; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.widget.RelativeLayout; public class MainActivity extends Activity { final Paint pnt = new Paint(Paint.ANTI_ALIAS_FLAG); final Random rnd = new Random(); RelativeLayout rlBG; @Override protected final void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Make it fullscreen // Desactiver la barre de titre de notre application requestWindowFeature(Window.FEATURE_NO_TITLE); // Passer la fenêtre en full-creen == cacher la barre de notification getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_main); rlBG = (RelativeLayout) findViewById(R.id.bg); rlBG.setPadding(0,0); final CustomView cv = new CustomView(this); rlBG.addView(cv); sendViewToBack(cv); } private static void sendViewToBack(final View v) { final ViewGroup parent = (ViewGroup)v.getParent(); if (parent != null) { parent.removeView(v); parent.addView(v,0); } } private class CustomView extends View { public CustomView(final Context ctx) { super(ctx); } @Override protected final void onDraw(final Canvas cnv) { // super.onDraw(cnv); // Clear the canvas cnv.drawRGB(0,0); // Instance de Paint pour définir l'attribut couleur de notre point,// ainsi que sa taille. // Nous allons dessiner nos points par rapport à la résolution de // l'écran final int width = cnv.getWidth(); // Largeur final int height = cnv.getHeight(); // Hauteur final float rayonDuCercle = (float) (cnv.getWidth() *.5) - 5; final float rayonDuCerclePetit = (float) (cnv.getWidth() * .167); // drawStars(cnv,width,height); // drawRays(cnv,rayonDuCerclePetit); // drawCircles(cnv,height,rayonDuCerclePetit); } private final void drawCircles ( final Canvas cnv,final int width,final int height,final float rayonDuCercle,final float rayonDuCerclePetit ) { // // aficchons notre fameux cercle pnt.setColor(Color.parseColor("#ffff0000")); pnt.setStyle(Style.STROKE); pnt.setStrokeWidth(10); cnv.drawCircle((float) (cnv.getWidth() * .5),(float) (cnv.getHeight() * .5),pnt); cnv.drawCircle((float) (cnv.getWidth() * .5),pnt); // ???????????????????????????????????????????????????????????????? /* Random rand = new Random(); //Affichons 100 segments de toutes les couleurs for (int i=0; i < 100; i++) { // Affecter une couleur de manière aléatoire paint.setARGB(255,rand.nextInt(256)); // Définir l'épaisseur du segment paint.setStrokeWidth (rand.nextInt(10)); // Puis dessiner nos points dans le cavenas canvas.drawLine(rand.nextInt(iWidth),rand.nextInt(iWidth),paint); } */ pnt.setARGB(255,rnd.nextInt(256),rnd.nextInt(256)); // Définir l'épaisseur du segment pnt.setStrokeWidth(2); // ???????????????????????????????????????????????????????????????? // Puis dessiner nos points dans le cavenas // okcanvas.drawLine((float)((float)Math.cos(0)*rayonDuCerclePetit)+canvas.getWidth()/2,paint); // okcanvas.drawLine((float)((float)Math.cos(Math.PI/2)*rayonDuCerclePetit)+canvas.getWidth()/2,// paint); // okkk // canvas.drawLine((float)((float)Math.cos(Math.PI/4)*rayonDuCerclePetit)+canvas.getWidth()/2,// paint); // initPaint(paint,); } private final void drawRays ( final Canvas cnv,final float rayonDuCerclePetit ) { // pourquoi j'utilise 2 boucles ? Parce que pour limiter l'espace // memoire j'utilise le même canva et la seul difference entre ces // deux element est la couleur. // cette boucle affiche des rayons for (int i = 8; i > -1; --i) { setRayon(cnv,(Math.PI * .25) * i,pnt,rayonDuCerclePetit); } } private final void drawStars (final Canvas cnv,final int height) { // j'ai l'impression detre dans les etoiles avec ces petits points // Affichons (1/100th of screen size) points de toutes les couleurs final int stars = (int) ((width * height) *.01); for (int i = stars; i > 0; --i) { // Affecter une couleur de manière aléatoire pnt.setARGB(255,rnd.nextInt(256)); // Puis dessiner nos points dans le canevas cnv.drawPoint(rnd.nextInt(width),rnd.nextInt(height),pnt); } } /* * info pour unen raison que j'ai pas chercher a comprendre l'angle * positif s'affiche comme si c'été un ange negatif . Donc je bidouille * en multipliant l'angle par -1 */ void setRayon ( final Canvas cnv,final Paint pnt,final float rayonDuCerclePetit ) { angleRad = (Math.toRadians(90) + angleRad) * -1; cnv.drawLine ( ((float) Math.cos(angleRad) * rayonDuCerclePetit) + (float) (cnv.getWidth() * .5),((float) Math.sin(angleRad) * rayonDuCerclePetit) + (float) (cnv.getHeight() * .5),(float) (cnv.getWidth() * .5) + (rayonDuCercle * (float) Math.cos(angleRad)),(rayonDuCercle * (float) Math.sin(angleRad)) + (float) (cnv.getHeight() * .5),pnt ); } } }