0

I need perfect circle button in my app. Which scales automatically accordingly to the screen size(height of the layout it is in.)

My xml file : circle1try.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
    <corners
        android:radius="1000dp"
    />
    <solid
        android:color="#ff00b3ff"
    />
</shape>

the place where I use it in my activity layout :

<LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:padding="30dp"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true">

    <Button
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/button1Key"
        android:typeface="monospace"
        android:textSize="20dp"
        android:background="@drawable/circle1try"
        android:textColor="#ffffffff"
        android:text="tap here"
        android:layout_gravity="center"/>
</LinearLayout>

The entire LinearLayout lies in another vertical LinearLayout and I use layout_weight to make sure the space occupied by the layouts have similar proportions on all screens.

This code snippet from the java file related to the button

roundButton=(Button)findViewById(R.id.button1Key);
int btnSize=roundButton.getLayoutParams().height;
roundButton.setLayoutParams(new LinearLayout.LayoutParams(btnSize, btnSize));

and in my app depending on the user actions, I also need to change the color for which I use the following snippet in the same class.

bgShape = (GradientDrawable)roundButton.getBackground();
bgShape.setColor(Color.BLACK);

However the button I get using this process is not a complete circle. It is close to a circle but wide along the x axis. So how do I get a perfectly round button whose color can be easily changed ?

  • 1
    isn't `1000dp` for the radius too much? – Blackbelt Mar 11 '15 at 16:53
  • 1
    Using `` with `shape:"oval"`? – Vikram Mar 11 '15 at 16:54
  • but it doesn't produce any different result from `100dp` radius or `10dp` radius . Not sure what to do about it. –  Mar 11 '15 at 17:07
  • I tried with `shape:"rectangle" and `shape:"oval", with the later `removing `` doesn't make any difference, I still get the same result. –  Mar 11 '15 at 17:14
  • @AakashMaroti That was the point. Using `` with `shape:oval` does nothing. Add a picture of what your activity looks like now. – Vikram Mar 11 '15 at 17:48
  • @Vikram , I do not have enough reputation to post a pic, but here is the link, I have inscribed a perfect circle inside for reference [image](https://drive.google.com/open?id=0B0YRqSOqDC6bbmRVSWQwOVJoeUU&authuser=0) –  Mar 11 '15 at 17:59
  • @AakashMaroti Seems like your width is at the maximum, but still less than the height. As an experiment, use `int btnSize=roundButton.getLayoutParams().width;`. Does that produce a _perfect circle_? – Vikram Mar 11 '15 at 18:04
  • @Vikram It just gets worse using that. –  Mar 11 '15 at 18:24

2 Answers2

1

You can use this library : AndroidCircleButton

or look at another answer on stackoverflow

Community
  • 1
  • 1
Mathieu de Brito
  • 2,536
  • 2
  • 26
  • 30
  • I was wondering if it is possible without using any external liabrary, and also avoid measurements in `dp` as I want to get largest possible shape which fits the proportions of the `LinearLayout`. –  Mar 11 '15 at 17:22
0

Ok ! so what basically does not work with the code is that it scales up the shape even before the layout is drawn. solution ? wait for the layout to be drawn. Initially getHeight() would return 0. I used a ViewTreeObserver. Now it returns the actual value. Code snippet I incorporated that solved my problem.

     ViewTreeObserver vto = player.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            roundButton.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            roundButton.setWidth(player.getHeight());                
            ViewGroup.LayoutParams params=roundButton.getLayoutParams();
            params.width=player.getHeight();
            roundButton.setLayoutParams(params);
        }
    });