How to align 8 little circles around of a centered big circle, like attached image shows?

匿名 (未验证) 提交于 2019-12-03 02:50:02

问题:

I have to do this layout:

I was trying to align the views, using RelativeLayout and layout_toRightOf, layout_below, etc, but the best that I achieved was this:

Here are the xml:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" 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">  <TextView     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:text="Hello World!" />  <RelativeLayout     android:id="@+id/big"     android:layout_width="150dp"     android:layout_height="150dp"     android:background="@drawable/circular"     android:layout_margin="10dp"     android:layout_centerInParent="true"/>  <RelativeLayout     android:id="@+id/right"     android:layout_width="50dp"     android:layout_height="50dp"     android:background="@drawable/circular"     android:layout_toRightOf="@+id/big"     android:layout_centerVertical="true"/>  <RelativeLayout     android:id="@+id/left"     android:layout_width="50dp"     android:layout_height="50dp"     android:background="@drawable/circular"     android:layout_toLeftOf="@+id/big"     android:layout_centerVertical="true"/>  <RelativeLayout     android:id="@+id/top"     android:layout_width="50dp"     android:layout_height="50dp"     android:background="@drawable/circular"     android:layout_above="@+id/big"     android:layout_centerHorizontal="true"/>  <RelativeLayout     android:id="@+id/bottom"     android:layout_width="50dp"     android:layout_height="50dp"     android:background="@drawable/circular"     android:layout_below="@+id/big"     android:layout_centerHorizontal="true"/>  <RelativeLayout     android:id="@+id/northeast"     android:layout_width="50dp"     android:layout_height="50dp"     android:background="@drawable/circular"     android:layout_toRightOf="@+id/big"     android:layout_alignTop="@+id/top"/>  <RelativeLayout     android:id="@+id/northwest"     android:layout_width="50dp"     android:layout_height="50dp"     android:background="@drawable/circular"     android:layout_toLeftOf="@+id/big"     android:layout_alignTop="@+id/top"/>  <RelativeLayout     android:id="@+id/southeast"     android:layout_width="50dp"     android:layout_height="50dp"     android:background="@drawable/circular"     android:layout_toRightOf="@+id/big"     android:layout_below="@+id/big"/>      <RelativeLayout     android:id="@+id/southwest"     android:layout_width="50dp"     android:layout_height="50dp"     android:background="@drawable/circular"     android:layout_toLeftOf="@+id/big"     android:layout_below="@+id/big"/>  </RelativeLayout> 

I'm trying to avoid using margin on the little circles, because the diagonal circles have to be aligned exactly to the center, in comparison with the top/bottom/right/left circles.

How can I do that?

回答1:

I show you another approach.

import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View;   public class CircleMenu extends View {  private Paint mainPaint; private Paint secondPaint; private Paint textPaint; private int radius_main =130; private int menuRadialButtonsCount =7; private int menuInnerPadding = 40; private int radialCircleRadius = 60; private int textPadding = 25; private double startAngle = - Math.PI/2f;; public CircleMenu(Context context) {     super(context); }  public CircleMenu(Context context, AttributeSet attrs) {     super(context, attrs); }  public CircleMenu(Context context, AttributeSet attrs, int defStyleAttr) {     super(context, attrs, defStyleAttr); }  @Override protected void onFinishInflate() {     super.onFinishInflate();      mainPaint = new Paint();     mainPaint.setColor(Color.BLUE);     secondPaint = new Paint();     secondPaint.setColor(Color.DKGRAY);     textPaint = new Paint();     textPaint.setColor(Color.BLACK); }  @Override protected void onDraw(Canvas canvas) {     super.onDraw(canvas);    int centerX = canvas.getWidth()/2 ;     int centerY= canvas.getHeight()/2;     canvas.drawCircle(centerX,centerY,radius_main,mainPaint);     for(int i=0;i<menuRadialButtonsCount;i++){         double angle =0;         if(i==0){          angle = startAngle;         }else{             angle = startAngle+(i * ((2 * Math.PI) / menuRadialButtonsCount));         }         int x = (int) (centerX + Math.cos(angle)*(radius_main+menuInnerPadding+radialCircleRadius));         int y = (int) (centerY + Math.sin(angle)*(radius_main+menuInnerPadding+radialCircleRadius));           canvas.drawCircle(x,y,radialCircleRadius,secondPaint);          float tW = textPaint.measureText("Text "+i);         canvas.drawText("Text "+i,x-tW/2,y+radialCircleRadius+textPadding,textPaint);     }    } } 

You can extend this class, add methods to set dimmensions from resources, controlling numer of circles, their size, paddings, onTouch, shadows, colors ....

 <your.package.CircleMenu     android:layout_width="match_parent"     android:layout_height="match_parent"/> 

Updatet version:

import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View;  import java.util.ArrayList;   public class CircleMenu extends View {  public static interface IMenuListener{      public void onMenuClick(MenuCircle item); }  public static class MenuCircle{     private int x,y,radius;     public int id;     public String text;  }  private Paint mainPaint; private Paint secondPaint; private Paint textPaint; private int radius_main =130;  private int menuInnerPadding = 40; private int radialCircleRadius = 60; private int textPadding = 25; private double startAngle = - Math.PI/2f; private ArrayList<MenuCircle> elements; private IMenuListener listener;  public void setListener(IMenuListener listener){     this.listener = listener; } public void clear(){     elements.clear();     listener=null; } public CircleMenu(Context context) {     super(context);     init(); }  public CircleMenu(Context context, AttributeSet attrs) {     super(context, attrs);     init(); }  public CircleMenu(Context context, AttributeSet attrs, int defStyleAttr) {     super(context, attrs, defStyleAttr);     init(); } private void init(){     elements = new ArrayList<>(); } public void addMenuItem(String text,int id){     MenuCircle item = new MenuCircle();     item.id = id;     item.text=text;     elements.add(item);  }   @Override protected void onFinishInflate() {     super.onFinishInflate();      mainPaint = new Paint();     mainPaint.setColor(Color.BLUE);     secondPaint = new Paint();     secondPaint.setColor(Color.DKGRAY);     textPaint = new Paint();     textPaint.setColor(Color.BLACK); }  @Override protected void onDraw(Canvas canvas) {     super.onDraw(canvas);    int centerX = canvas.getWidth()/2 ;     int centerY= canvas.getHeight()/2;     canvas.drawCircle(centerX,centerY,radius_main,mainPaint);     for(int i=0;i<elements.size();i++){         double angle =0;         if(i==0){             angle = startAngle;         }else{             angle = startAngle+(i * ((2 * Math.PI) / elements.size()));         }         elements.get(i).x = (int) (centerX + Math.cos(angle)*(radius_main+menuInnerPadding+radialCircleRadius));         elements.get(i).y = (int) (centerY + Math.sin(angle)*(radius_main+menuInnerPadding+radialCircleRadius));           canvas.drawCircle( elements.get(i).x,elements.get(i).y,radialCircleRadius,secondPaint);          float tW = textPaint.measureText(elements.get(i).text);         canvas.drawText(elements.get(i).text,elements.get(i).x-tW/2,elements.get(i).y+radialCircleRadius+textPadding,textPaint);     }   }  @Override public boolean onTouchEvent(MotionEvent event) {      if(event.getAction()==MotionEvent.ACTION_DOWN){         for(MenuCircle mc : elements){             double distance =  Math.hypot(event.getX()-mc.x,event.getY()-mc.y);             if(distance<= radialCircleRadius){                 //touched                 if(listener!=null)                     listener.onMenuClick(mc);                return true;             }         }      }      return super.onTouchEvent(event); }  @Override protected void onDetachedFromWindow() {     super.onDetachedFromWindow();  } } 

In fragment:

  CircleMenu cm = (CircleMenu) view.findViewById(R.id.c_menu);     cm.addMenuItem("one",1);     cm.addMenuItem("two",2);     cm.addMenuItem("three",3);     cm.addMenuItem("ten",10);     cm.addMenuItem("oh oh",156);     cm.addMenuItem("exit",134);     cm.setListener(new CircleMenu.IMenuListener() {         @Override         public void onMenuClick(CircleMenu.MenuCircle item) {             Toast.makeText(getActivity(),item.text+" "+item.id,Toast.LENGTH_LONG).show();         }     }); 


回答2:

This helps you.

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" 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">   <RelativeLayout     android:id="@+id/rlBig"     android:layout_width="250dp"     android:layout_height="260dp"      android:layout_centerInParent="true">      <RelativeLayout         android:id="@+id/big"         android:layout_width="150dp"         android:layout_height="150dp"         android:layout_centerInParent="true"         android:background="@drawable/round_orange_schdule_meet" />      <RelativeLayout         android:id="@+id/northwest"         android:layout_width="50dp"         android:layout_height="50dp"         android:layout_alignParentLeft="true"         android:layout_alignParentTop="true"         android:layout_marginTop="10dp"         android:background="@drawable/round_orange_schdule_meet" />      <RelativeLayout         android:id="@+id/southeast"         android:layout_width="50dp"         android:layout_height="50dp"         android:layout_alignParentRight="true"         android:layout_alignParentTop="true"         android:background="@drawable/round_orange_schdule_meet" />      <RelativeLayout         android:id="@+id/southwest"         android:layout_width="50dp"         android:layout_height="50dp"         android:layout_alignParentBottom="true"         android:layout_alignParentLeft="true"         android:background="@drawable/round_orange_schdule_meet" />      <RelativeLayout         android:id="@+id/northeast"         android:layout_width="50dp"         android:layout_height="50dp"         android:layout_alignParentBottom="true"         android:layout_alignParentRight="true"         android:background="@drawable/round_orange_schdule_meet" />  </RelativeLayout>  <RelativeLayout     android:id="@+id/right"     android:layout_width="50dp"     android:layout_height="50dp"     android:layout_centerVertical="true"     android:layout_toRightOf="@+id/rlBig"     android:layout_marginLeft="-15dp"     android:background="@drawable/round_orange_schdule_meet" />  <RelativeLayout     android:id="@+id/left"     android:layout_width="50dp"     android:layout_height="50dp"     android:layout_centerVertical="true"     android:layout_marginRight="-15dp"     android:layout_toLeftOf="@+id/rlBig"     android:background="@drawable/round_orange_schdule_meet" />  <RelativeLayout     android:id="@+id/top"     android:layout_width="50dp"     android:layout_height="50dp"     android:layout_above="@+id/rlBig"     android:layout_marginBottom="-15dp"     android:layout_centerHorizontal="true"     android:background="@drawable/round_orange_schdule_meet" />  <RelativeLayout     android:id="@+id/bottom"     android:layout_width="50dp"     android:layout_height="50dp"     android:layout_below="@+id/rlBig"     android:layout_centerHorizontal="true"     android:layout_marginTop="-10dp"     android:background="@drawable/round_orange_schdule_meet" /> 

Output is:



回答3:

You should go with a custom-view here - with a lot of force you might be able to do it with a layout - but it will be messy and not perform well



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!