Android 中的圆形按钮

84

我想在一个安卓程序中创建圆角按钮。我已经查看了如何创建带有圆角的EditText?

我的目标是:

  1. 圆角边缘按钮
  2. 在不同状态下更改按钮背景或外观(如OnClick,Focus)
  3. 使用自己的PNG作为背景而不是创建一个形状。

1
http://nishantvnair.wordpress.com/2010/11/09/customize-button-in-android/ - Sergey Benner
Google推出了新的框架,其中最新技术包括Jetpack Compose。 - Ucdemir
10个回答

137

你可以通过使用背景选择器资源button_background.xml来实现带圆角的按钮,而无需使用ImageView。

<?xml version="1.0" encoding="utf-8" ?> 
     <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <!--  Non focused states 
      --> 
      <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/button_unfocused" /> 
      <item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/button_unfocused" /> 
     <!--  Focused states 
      --> 
      <item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/button_focus" /> 
      <item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/button_focus" /> 
     <!--  Pressed 
      --> 
      <item android:state_pressed="true" android:drawable="@drawable/button_press" /> 
    </selector>

对于每个状态,都有一个可绘制资源文件,例如button_press.xml:

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
  <stroke android:width="1dp" android:color="#FF404040" /> 
  <corners android:radius="6dp" /> 
  <gradient android:startColor="#FF6800" android:centerColor="#FF8000" android:endColor="#FF9700" android:angle="90" /> 
</shape>

注意corners元素,它可以让你获得圆角!

然后在按钮上设置背景可绘制对象:

android:background="@drawable/button_background"

编辑(9/2018):同样的技巧可以用来创建圆形按钮。圆形实际上就是一个边长为正方形边长的1/2的正方形按钮。

此外,在上面的示例中,strokegradient不是必需的元素,它们只是示例和您可以看到圆角形状的方式。


1
CSMith。我已经让选择器工作了。第二部分让我有点困惑,不知道在哪里放置代码。我需要创建一个单独的XML文件吗?如果是这样,我该如何调用它?对于按钮,我仍然将其背景设置为@drawable/button_background...谢谢。 - ControlAltDelete
1
CSmith。那么这个单独的xml文件在哪里被调用呢?在上面的例子中,您将背景设置为可绘制对象,这很好地实现了交互时背景的更改。但是,如果您不创建带有圆角的png并使用九宫格来避免失真,则按钮不会变成圆形。 - ControlAltDelete
2
我对Android开发还比较新,这个问题可能有点幼稚:我应该将XML文件添加到哪个“drawable”文件夹中?我有四个不同的“drawable”文件夹:drawable-hdpidrawable-mdpidrawable-xhdpidrawable-xxhdpi - ikartik90
3
@ikartik90,请使用drawable文件夹。其他文件夹通常用于覆盖“基本”drawable文件夹中的特定密度资产或设置,而在此示例中没有任何特定密度的覆盖存在。 - CSmith
为什么每个都有两个? - CodyBugstein
显示剩余8条评论

87
如果您需要在Android中使用圆形按钮,则需创建一个名为"RoundShapeBtn.xml"的XML文件作为drawable。
 <?xml version="1.0" encoding="utf-8"?>
  <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" android:padding="10dp">   
  <solid android:color="#6E6E6E"/> <!-- this one is ths color of the Rounded Button -->
  <corners
   android:bottomRightRadius="10dp"
   android:bottomLeftRadius="10dp"
   android:topLeftRadius="10dp"
   android:topRightRadius="10dp"/>
</shape>

将此代码添加到您的按钮代码中:

android:background="@drawable/RoundShapeBtn"

1
我是否也应在此处添加字体以使按钮文本具有特定字体? - Garima Tiwari
@GarimaTiwari 是的,你可以在设计相关领域做更多的事情。 - Pir Fahim Shah
4
如果您在文件名中使用大写字母,实际上会出现构建错误。 :) - tplive

18
在安卓中,可以在drawable文件夹中创建XML文件,例如:

rounded_button.xml

请注意,我仅翻译内容并保留HTML标记,不提供解释。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">

    <corners android:radius="20dp"/> // if you want clear round shape then make radius size is half of your  button`s height.
    <solid android:color="#EEFFFFFF"/> // Button Colour
    <padding
        android:bottom="5dp"
        android:left="10dp"
        android:right="10dp"
        android:top="5dp"/>

</shape>

现在将这个xml文件作为您的按钮背景。

 <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:background="@drawable/rounded_button"
        android:text="@string/button_text"
        android:textColor="@color/black"/>

这实际上是大多数人正在寻找的东西。非常弯曲光滑的矩形边缘。我如何在按钮上添加阴影?谢谢! - S bruce
1
太棒了!如果有人因为需要制作不同颜色的圆形按钮XML而感到烦恼,那么您可以从可绘制的XML中删除solid android:color,并改为使用每个Buttonandroid:backgroundTint指定颜色。 - Kartik Chugh
@K_7 如果你这样做,就会失去高度和阴影。只需按照这个方法,当你按住按钮时,就能得到高度和阴影。 - Jeffrey Liu

6

按照以下方式扩展ImageView

public class RoundedImageView extends ImageView {
  private static final String TAG = "RoundedImageView";

  private float mRadius = 0f;

  public RoundedImageView(Context context) {
    super(context);
  }

  public RoundedImageView(Context context, AttributeSet attrs) {
    super(context, attrs);

    // retrieve styles attributes
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundedView);
    mRadius = a.getDimension(R.styleable.RoundedView_radius, 0f);
    a.recycle();
  }

  @Override
  protected void onDraw(Canvas canvas) {
    // only do this if we actually have a radius
    if(mRadius > 0) {
      RectF rect = new RectF(0, 0, getWidth(), getHeight());
      Path clipPath = new Path();
      clipPath.addRoundRect(rect, mRadius, mRadius, Path.Direction.CW);
      canvas.clipPath(clipPath);
    }
    super.onDraw(canvas);
  }
}

将您的普通背景资源应用于它,它应该被剪裁成圆角。


默认情况下,R.styleable.RoundedView_radius和R.styleable.RoundedView是否存在? - Sergey Benner
Cody,我该如何查看android.widget.imageview.class的源代码呢?我一直收到"Do you want to attach a source file to it because it was not found in eclipse"的提示。 - ControlAltDelete
@Jib,你可以在这里访问Android源代码:http://source.android.com/source/downloading.html - Cody Caughlan
谢谢Cody,这个编程解决方案正是我所需要的。 - DwarDoh

4

把按钮的状态和形状放在一个xml选择器文件中会更好。这样可以使您的应用程序运行更快/更好。可以尝试以下代码(感谢《Android应用开发入门》)。这里不是垃圾邮件,只是展示这不是我的代码。

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android" >

    <item android:state_pressed="true" >
    <shape android:shape="rectangle"  >
     <corners android:radius="12dip" />
     <stroke android:width="1dip" android:color="#333333" />
     <gradient android:angle="-90" android:startColor="#333333"      android:endColor="#555555"  />            
    </shape>
    </item>
    <item android:state_focused="true">
    <shape android:shape="rectangle"  >
     <corners android:radius="12dip" />
     <stroke android:width="1dip" android:color="#333333" />
     <solid android:color="#58857e"/>       
    </shape>
    </item>  
    <item >
    <shape android:shape="rectangle"  >
     <corners android:radius="12dip" />
     <stroke android:width="1dip" android:color="#333333" />
     <gradient android:angle="-90" android:startColor="#333333" android:endColor="#555555" />            
    </shape>
    </item>

    </selector>

P.S.-设计提示:渐变和圆角矩形最好在几乎看不出它们存在的时候使用-明智使用。


4
这可以通过使用"corner"属性来实现。请参考下面的xml。
<item>
    <shape android:shape="rectangle" >
        <stroke
            android:height="1.0dip"
            android:width="1.0dip"
            android:color="#ffee82ee" />

        <solid android:color="#ffee82ee" />

        <corners
            android:bottomLeftRadius="102.0dip"
            android:bottomRightRadius="102.0dip"
            android:radius="102.0dip"
            android:topLeftRadius="102.0dip"
            android:topRightRadius="102.0dip" />
    </shape>
</item>


3
谷歌建议不要模仿其他平台的用户界面元素,官方文档推荐使用原生Android设计。在Android应用程序中,不应该使用圆形的iOS样式按钮。

67
开发者决定将丑陋的用户界面作为标准,并非我们的错。 - Yehonatan
这可能有点过时了,但我想补充一下,我们之前公司的应用程序几乎没有在应用商店中展示,因为它违反了很多iOS UI样式。我们不得不进行修订,并考虑适当的Material设计要素。遵循指南总是很重要的! - lase
2
@lase 完全不同意,指南只是指导方针,而不是硬性规定。 - martinseal1987
@即使Play商店不遵循指南也不会拒绝您的应用程序,因为它们在任何意义上都不是规则。 - martinseal1987
让我去告诉我的UI设计师... - Chris Rollins
显示剩余3条评论

2
可以使用环形形状的可绘制对象来创建圆角按钮,可以参见http://www.zoftino.com/android-shape-drawable-examples。请注意保留HTML标记。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:innerRadius="0dp"
    android:shape="ring"
    android:thickness="40dp"
    android:useLevel="false">
    <solid android:color="@color/colorPrimary" />
    <padding android:bottom="50dp"
        android:left="16dp"
        android:right="16dp"
        android:top="50dp"/>
</shape>

2
创建名为btnOval的可绘制资源-->然后将代码粘贴;
 <?xml version="1.0" encoding="utf-8"?>
      <shape xmlns:android="http://schemas.android.com/apk/res/android" 
android:shape="oval"  
android:padding="10dp">   
      <solid android:color="#6E6E6E"/> 
    </shape>

"在按钮标签内使用用户,如下所示:"
<Button
andorid:width=""
android:hieght=""
android:background="@Drawable/btnOval"
/>

0
尝试以下代码 创建一个名为circular_button.xml的可绘制文件,并插入以下内容
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#008577" />
<corners android:bottomRightRadius="100dp"
    android:bottomLeftRadius="100dp"
    android:topRightRadius="100dp"
    android:topLeftRadius="100dp"/>
</shape>

然后将按钮的背景更改为此可绘制文件

 <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/circle_button"
                android:text="Button"/>

如果你想要一个完整的圆形按钮,你可以使用下面的drawable。
<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">

    <solid
        android:color="#008577"/>

    <size
        android:width="120dp"
        android:height="120dp"/>
</shape>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接