如何像对齐的图像所示那样,将8个小圆圈对齐在一个居中的大圆圈周围? [英] How to align 8 little circles around of a centered big circle, like attached image shows?

查看:81
本文介绍了如何像对齐的图像所示那样,将8个小圆圈对齐在一个居中的大圆圈周围?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须执行以下布局:

I have to do this layout:

我试图使用RelativeLayout和layout_toRightOf,layout_below等对齐视图,但是我实现的最好成绩是:

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

这是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.

我该怎么办?

推荐答案

我向您展示了另一种方法.

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);
    }


 }
}

您可以扩展此类,添加方法以设置资源的尺寸,控制圆的数目,圆的大小,填充,onTouch,阴影,颜色....

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"/>

更新版本:

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();

}
}

片段中:

  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();
        }
    });

这篇关于如何像对齐的图像所示那样,将8个小圆圈对齐在一个居中的大圆圈周围?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆