如何对齐一个居中的大圆周围的8个小圆圈,如附图所示?

时间:2015-10-21 12:30:36

标签: android android-layout relativelayout

我必须做这个布局:enter image description here

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

enter image description here

以下是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>

我试图避免在小圆圈上使用边距,因为与顶部/底部/右/左圆相比,对角圆必须与中心精确对齐。

我该怎么做?

3 个答案:

答案 0 :(得分:6)

我告诉你另一种方法。

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


 }
}

你可以扩展这个类,添加方法来设置资源的dimmensions,控制圆圈的数量,它们的大小,填充,onTouch,阴影,颜色....

enter image description here

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

答案 1 :(得分:5)

这可以帮到你。

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

输出是:

enter image description here

答案 2 :(得分:0)

你应该在这里使用自定义视图 - 你可以用布局来做很多力 - 但它会很乱并且表现不佳