Android: Creating a Circular TextView?

后端 未结 11 1591
我在风中等你
我在风中等你 2020-12-04 08:53

My current simple XML is below, however i would like the 3 TextViews within it to be circular, rather than rectangular.

How can I change my code to do so?

         


        
相关标签:
11条回答
  • 2020-12-04 09:35

    It's a rectangle that prevents oval shape background to get circular.
    Making view a square will fix everything.

    I found this solution to be clean and working for varying textsize and text length.

    public class EqualWidthHeightTextView extends TextView {
    
        public EqualWidthHeightTextView(Context context) {
            super(context);
        }
    
        public EqualWidthHeightTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public EqualWidthHeightTextView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
            int r = Math.max(getMeasuredWidth(),getMeasuredHeight());
            setMeasuredDimension(r, r);
    
        }
    }
    


    Usage

    <com.commons.custom.ui.EqualWidthHeightTextView
        android:id="@+id/cluster_count"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="10+"
        android:background="@drawable/oval_light_blue_bg"
        android:textColor="@color/white" />
    


    oval_light_blue_bg.xml

    <shape xmlns:android="http://schemas.android.com/apk/res/android"<br>
           android:shape="oval">
       <solid android:color="@color/light_blue"/>
       <stroke android:color="@color/white" android:width="1dp" />
    </shape>
    
    0 讨论(0)
  • 2020-12-04 09:41

    Much of the Answer here seems to be hacks to the shape drawable, while android in itself supports this with the shapes functionality. This is something that worked perfectly for me.You can do this in two ways

    Using a fixed height and width, that would stay the same regardless of the text that you put it as shown below

    <shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    
    <solid android:color="@color/alpha_white" />
    
        <size android:width="25dp" android:height="25dp"/>
    
    <stroke android:color="@color/color_primary" android:width="1dp"/>
    
    </shape>
    

    Using Padding which re-adjusts the shape regardless of the text in the textview it as shown below

    <solid android:color="@color/alpha_white" />
    
    <padding
        android:bottom="@dimen/semi_standard_margin"
        android:left="@dimen/semi_standard_margin"
        android:right="@dimen/semi_standard_margin"
        android:top="@dimen/semi_standard_margin" />
    
    <stroke android:color="@color/color_primary" android:width="2dp"/>
    

    semi_standard_margin = 4dp

    0 讨论(0)
  • 2020-12-04 09:42

    use this in your drawable

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" 
        android:shape="oval">
    
    
        <solid android:color="#55ff55"/>
    
    
        <size android:height="60dp"
            android:width="60dp"/>
    
    </shape>
    

    Set background for the textview as this

    0 讨论(0)
  • 2020-12-04 09:44

    1.Create an xml circle_text_bg.xml in your res/drawable folder with the code below

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
         <solid android:color="#fff" />
    
        <stroke
            android:width="1dp"
            android:color="#98AFC7" />
        <corners
             android:bottomLeftRadius="50dp"
             android:bottomRightRadius="50dp"
             android:topLeftRadius="50dp"
             android:topRightRadius="50dp" />
        <size
             android:height="20dp"
             android:width="20dp" />
    </shape>
    

    2.Use circle_text_bg as the background for your textview. NB: In order to get a perfect circle your textview height and width should be the same.Preview of what your textview with text 1, 2, 3 with this background should look like this

    0 讨论(0)
  • 2020-12-04 09:45

    The typical solution is to define the shape and use it as background but as the number of digits varies it's no more a perfect circle, it looks like a rectangle with round edges or Oval. So I have developed this solution, it's working great. Hope it will help someone.

    Here is the code of custom TextView

    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.util.AttributeSet;
    import android.widget.TextView;
    
    public class CircularTextView extends TextView
    {
    private float strokeWidth;
    int strokeColor,solidColor;
    
    public CircularTextView(Context context) {
        super(context);
    }
    
    public CircularTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    public CircularTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    
    
    @Override
    public void draw(Canvas canvas) {
    
        Paint circlePaint = new Paint();
        circlePaint.setColor(solidColor);
        circlePaint.setFlags(Paint.ANTI_ALIAS_FLAG);
    
        Paint strokePaint = new Paint();
        strokePaint.setColor(strokeColor);
        strokePaint.setFlags(Paint.ANTI_ALIAS_FLAG);
    
        int  h = this.getHeight();
        int  w = this.getWidth();
    
        int diameter = ((h > w) ? h : w);
        int radius = diameter/2;
    
        this.setHeight(diameter);
        this.setWidth(diameter);
    
        canvas.drawCircle(diameter / 2 , diameter / 2, radius, strokePaint);
    
        canvas.drawCircle(diameter / 2, diameter / 2, radius-strokeWidth, circlePaint);
    
        super.draw(canvas);
    }
    
    public void setStrokeWidth(int dp)
    {
        float scale = getContext().getResources().getDisplayMetrics().density;
        strokeWidth = dp*scale;
    
    }
    
    public void setStrokeColor(String color)
    {
        strokeColor = Color.parseColor(color);
    }
    
    public void setSolidColor(String color)
    {
        solidColor = Color.parseColor(color);
    
    }
    }
    

    Then in your XML, give some padding and make sure its gravity is center

    <com.app.tot.customtextview.CircularTextView
            android:id="@+id/circularTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="11"
            android:gravity="center"
            android:padding="3dp"/>
    

    And you can set the stroke width

    circularTextView.setStrokeWidth(1);
    circularTextView.setStrokeColor("#ffffff");
    circularTextView.setSolidColor("#000000");
    
    0 讨论(0)
  • 2020-12-04 09:46

    You can try this in round_tv.xml in drawable folder:

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <stroke android:color="#22ff55" android:width="3dip"/>
    
        <corners
            android:bottomLeftRadius="30dp"
            android:bottomRightRadius="30dp"
            android:topLeftRadius="30dp"
            android:topRightRadius="30dp" />
    
        <size
            android:height="60dp"
            android:width="60dp" />
    
    </shape>
    

    Apply that drawable in your textviews as:

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/round_tv"
        android:gravity="center_vertical|center_horizontal"
        android:text="ffffd"
        android:textColor="#000"
        android:textSize="20sp" />
    

    Output:

    enter image description here

    Hope this helps.

    Edit: If your text is too long, Oval shape is more preferred.

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
    
        <stroke android:color="#55ff55" android:width="3dip"/>
    
        <corners
            android:bottomLeftRadius="30dp"
            android:bottomRightRadius="30dp"
            android:topLeftRadius="30dp"
            android:topRightRadius="30dp" />
    
        <size
            android:height="60dp"
            android:width="60dp" />
    
    </shape>
    

    Output:

    enter image description here

    If you still need it a proper circle, then I guess you will need to set its height dynamically after setting text in it, new height should be as much as its new width so as to make a proper circle.

    0 讨论(0)
提交回复
热议问题