How to align 8 little circles around of a centered big circle, like attached image shows?
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?


add a comment |
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?


Add some views or marginTop to 1st and 3rd circle and give marginBottom to bottom left and right corner circle
– curiousMind
Oct 21 '15 at 12:35
@Daniel can you please post your xml?
– pRaNaY
Oct 21 '15 at 12:41
Please google forandroid radial menu
– Fantômas
Oct 21 '15 at 12:48
@pRaNay I edited the post with the xml
– Daniel Nazareth
Oct 21 '15 at 12:52
add a comment |
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?


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?




edited Oct 21 '15 at 12:50
Daniel Nazareth
asked Oct 21 '15 at 12:30


Daniel NazarethDaniel Nazareth
198420
198420
Add some views or marginTop to 1st and 3rd circle and give marginBottom to bottom left and right corner circle
– curiousMind
Oct 21 '15 at 12:35
@Daniel can you please post your xml?
– pRaNaY
Oct 21 '15 at 12:41
Please google forandroid radial menu
– Fantômas
Oct 21 '15 at 12:48
@pRaNay I edited the post with the xml
– Daniel Nazareth
Oct 21 '15 at 12:52
add a comment |
Add some views or marginTop to 1st and 3rd circle and give marginBottom to bottom left and right corner circle
– curiousMind
Oct 21 '15 at 12:35
@Daniel can you please post your xml?
– pRaNaY
Oct 21 '15 at 12:41
Please google forandroid radial menu
– Fantômas
Oct 21 '15 at 12:48
@pRaNay I edited the post with the xml
– Daniel Nazareth
Oct 21 '15 at 12:52
Add some views or marginTop to 1st and 3rd circle and give marginBottom to bottom left and right corner circle
– curiousMind
Oct 21 '15 at 12:35
Add some views or marginTop to 1st and 3rd circle and give marginBottom to bottom left and right corner circle
– curiousMind
Oct 21 '15 at 12:35
@Daniel can you please post your xml?
– pRaNaY
Oct 21 '15 at 12:41
@Daniel can you please post your xml?
– pRaNaY
Oct 21 '15 at 12:41
Please google for
android radial menu
– Fantômas
Oct 21 '15 at 12:48
Please google for
android radial menu
– Fantômas
Oct 21 '15 at 12:48
@pRaNay I edited the post with the xml
– Daniel Nazareth
Oct 21 '15 at 12:52
@pRaNay I edited the post with the xml
– Daniel Nazareth
Oct 21 '15 at 12:52
add a comment |
3 Answers
3
active
oldest
votes
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();
}
});
Thanks so much! That's a great answer, it works perfectly!
– Daniel Nazareth
Oct 21 '15 at 19:52
@DanielNazareth You are welcome. Remember to call clear method on onDestroy. If you dont call it causes memory leak.
– Adam Miśtal
Oct 21 '15 at 20:03
How would you load more circles around it in a spiral like manner? And how would you make it pannable?
– Lucas Senechal
Apr 23 '16 at 6:18
If you like circles in spiral you have to change algoritm for calculating x,y . Now x,y are calculated as point on circle, change it to point on spiral. If you want pannable just: developer.android.com/training/gestures/scale.html#pan
– Adam Miśtal
Apr 23 '16 at 7:35
add a comment |
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:
Thanks so much! It works like a charm, just accepted Adam Miśtal's answer because using a custom view is better for perform, but that's exactly what I needed, if I could, I've accepted both answers
– Daniel Nazareth
Oct 21 '15 at 19:51
yes , you are welcome :) @Adam's more specific.
– pRaNaY
Oct 22 '15 at 7:13
add a comment |
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
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f33259384%2fhow-to-align-8-little-circles-around-of-a-centered-big-circle-like-attached-ima%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
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();
}
});
Thanks so much! That's a great answer, it works perfectly!
– Daniel Nazareth
Oct 21 '15 at 19:52
@DanielNazareth You are welcome. Remember to call clear method on onDestroy. If you dont call it causes memory leak.
– Adam Miśtal
Oct 21 '15 at 20:03
How would you load more circles around it in a spiral like manner? And how would you make it pannable?
– Lucas Senechal
Apr 23 '16 at 6:18
If you like circles in spiral you have to change algoritm for calculating x,y . Now x,y are calculated as point on circle, change it to point on spiral. If you want pannable just: developer.android.com/training/gestures/scale.html#pan
– Adam Miśtal
Apr 23 '16 at 7:35
add a comment |
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();
}
});
Thanks so much! That's a great answer, it works perfectly!
– Daniel Nazareth
Oct 21 '15 at 19:52
@DanielNazareth You are welcome. Remember to call clear method on onDestroy. If you dont call it causes memory leak.
– Adam Miśtal
Oct 21 '15 at 20:03
How would you load more circles around it in a spiral like manner? And how would you make it pannable?
– Lucas Senechal
Apr 23 '16 at 6:18
If you like circles in spiral you have to change algoritm for calculating x,y . Now x,y are calculated as point on circle, change it to point on spiral. If you want pannable just: developer.android.com/training/gestures/scale.html#pan
– Adam Miśtal
Apr 23 '16 at 7:35
add a comment |
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();
}
});
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();
}
});
edited Oct 21 '15 at 14:32
answered Oct 21 '15 at 13:48
Adam MiśtalAdam Miśtal
515212
515212
Thanks so much! That's a great answer, it works perfectly!
– Daniel Nazareth
Oct 21 '15 at 19:52
@DanielNazareth You are welcome. Remember to call clear method on onDestroy. If you dont call it causes memory leak.
– Adam Miśtal
Oct 21 '15 at 20:03
How would you load more circles around it in a spiral like manner? And how would you make it pannable?
– Lucas Senechal
Apr 23 '16 at 6:18
If you like circles in spiral you have to change algoritm for calculating x,y . Now x,y are calculated as point on circle, change it to point on spiral. If you want pannable just: developer.android.com/training/gestures/scale.html#pan
– Adam Miśtal
Apr 23 '16 at 7:35
add a comment |
Thanks so much! That's a great answer, it works perfectly!
– Daniel Nazareth
Oct 21 '15 at 19:52
@DanielNazareth You are welcome. Remember to call clear method on onDestroy. If you dont call it causes memory leak.
– Adam Miśtal
Oct 21 '15 at 20:03
How would you load more circles around it in a spiral like manner? And how would you make it pannable?
– Lucas Senechal
Apr 23 '16 at 6:18
If you like circles in spiral you have to change algoritm for calculating x,y . Now x,y are calculated as point on circle, change it to point on spiral. If you want pannable just: developer.android.com/training/gestures/scale.html#pan
– Adam Miśtal
Apr 23 '16 at 7:35
Thanks so much! That's a great answer, it works perfectly!
– Daniel Nazareth
Oct 21 '15 at 19:52
Thanks so much! That's a great answer, it works perfectly!
– Daniel Nazareth
Oct 21 '15 at 19:52
@DanielNazareth You are welcome. Remember to call clear method on onDestroy. If you dont call it causes memory leak.
– Adam Miśtal
Oct 21 '15 at 20:03
@DanielNazareth You are welcome. Remember to call clear method on onDestroy. If you dont call it causes memory leak.
– Adam Miśtal
Oct 21 '15 at 20:03
How would you load more circles around it in a spiral like manner? And how would you make it pannable?
– Lucas Senechal
Apr 23 '16 at 6:18
How would you load more circles around it in a spiral like manner? And how would you make it pannable?
– Lucas Senechal
Apr 23 '16 at 6:18
If you like circles in spiral you have to change algoritm for calculating x,y . Now x,y are calculated as point on circle, change it to point on spiral. If you want pannable just: developer.android.com/training/gestures/scale.html#pan
– Adam Miśtal
Apr 23 '16 at 7:35
If you like circles in spiral you have to change algoritm for calculating x,y . Now x,y are calculated as point on circle, change it to point on spiral. If you want pannable just: developer.android.com/training/gestures/scale.html#pan
– Adam Miśtal
Apr 23 '16 at 7:35
add a comment |
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:
Thanks so much! It works like a charm, just accepted Adam Miśtal's answer because using a custom view is better for perform, but that's exactly what I needed, if I could, I've accepted both answers
– Daniel Nazareth
Oct 21 '15 at 19:51
yes , you are welcome :) @Adam's more specific.
– pRaNaY
Oct 22 '15 at 7:13
add a comment |
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:
Thanks so much! It works like a charm, just accepted Adam Miśtal's answer because using a custom view is better for perform, but that's exactly what I needed, if I could, I've accepted both answers
– Daniel Nazareth
Oct 21 '15 at 19:51
yes , you are welcome :) @Adam's more specific.
– pRaNaY
Oct 22 '15 at 7:13
add a comment |
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:
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:
answered Oct 21 '15 at 14:03


pRaNaYpRaNaY
13.7k1169114
13.7k1169114
Thanks so much! It works like a charm, just accepted Adam Miśtal's answer because using a custom view is better for perform, but that's exactly what I needed, if I could, I've accepted both answers
– Daniel Nazareth
Oct 21 '15 at 19:51
yes , you are welcome :) @Adam's more specific.
– pRaNaY
Oct 22 '15 at 7:13
add a comment |
Thanks so much! It works like a charm, just accepted Adam Miśtal's answer because using a custom view is better for perform, but that's exactly what I needed, if I could, I've accepted both answers
– Daniel Nazareth
Oct 21 '15 at 19:51
yes , you are welcome :) @Adam's more specific.
– pRaNaY
Oct 22 '15 at 7:13
Thanks so much! It works like a charm, just accepted Adam Miśtal's answer because using a custom view is better for perform, but that's exactly what I needed, if I could, I've accepted both answers
– Daniel Nazareth
Oct 21 '15 at 19:51
Thanks so much! It works like a charm, just accepted Adam Miśtal's answer because using a custom view is better for perform, but that's exactly what I needed, if I could, I've accepted both answers
– Daniel Nazareth
Oct 21 '15 at 19:51
yes , you are welcome :) @Adam's more specific.
– pRaNaY
Oct 22 '15 at 7:13
yes , you are welcome :) @Adam's more specific.
– pRaNaY
Oct 22 '15 at 7:13
add a comment |
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
add a comment |
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
add a comment |
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
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
answered Oct 21 '15 at 13:11
ligiligi
23.1k32100184
23.1k32100184
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f33259384%2fhow-to-align-8-little-circles-around-of-a-centered-big-circle-like-attached-ima%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Add some views or marginTop to 1st and 3rd circle and give marginBottom to bottom left and right corner circle
– curiousMind
Oct 21 '15 at 12:35
@Daniel can you please post your xml?
– pRaNaY
Oct 21 '15 at 12:41
Please google for
android radial menu
– Fantômas
Oct 21 '15 at 12:48
@pRaNay I edited the post with the xml
– Daniel Nazareth
Oct 21 '15 at 12:52