android 按钮自定义

简介: 引用:http://www.gx2005.cn/tech/ShowArticle.asp?ArticleID=438 在Android(安卓)开发应用中,默认的Button是由系统渲染和管理大小的。而我们看到的成功的移动应用,都是有着酷炫的外观和使用体验的。

引用:http://www.gx2005.cn/tech/ShowArticle.asp?ArticleID=438

Android(安卓)开发应用中,默认的Button是由系统渲染和管理大小的。而我们看到的成功的移动应用,都是有着酷炫的外观和使用体验的。因此,我们在开发产品的时候,需要对默认按钮进行美化。在本篇里,笔者结合在应用开发中的经验,探讨一下自定义背景的按钮、自定义形状按钮的实现方法。

首先看实现效果截图:

 

自定义背景的按钮目前有2种方式实现,矢量和位图。

 

1. 矢量图形绘制的方式

矢量图形绘制的方式实现简单,适合对于按钮形状和图案要求不高的场合。步骤如下:

(a) 使用xml定义一个圆角矩形,外围轮廓线实线、内填充渐变色,xml代码如下。

view plain copy to clipboard print ? 
01.//bg_alibuybutton_default.xml   
02.<? xml   version = "1.0"   encoding = "utf-8" ?>    
03.< layer-list   xmlns:android = "http://schemas.android.com/apk/res/android" >    
04.   < item >    
05.      < shape   android:shape = "rectangle" >     
06.         < solid   android:color = "#FFEC7600"   />    
07.         < corners    
08.            android:topLeftRadius = "5dip"    
09.            android:topRightRadius = "5dip"    
10.            android:bottomLeftRadius = "5dip"    
11.            android:bottomRightRadius = "5dip"   />    
12.      </ shape >    
13.   </ item >    
14.   < item   android:top = "1px"   android:bottom = "1px"   android:left = "1px"   android:right = "1px" >    
15.     < shape >    
16.        < gradient     
17.            android:startColor = "#FFEC7600"   android:endColor = "#FFFED69E"     
18.            android:type = "linear"   android:angle = "90"    
19.            android:centerX = "0.5"   android:centerY = "0.5"   />    
20.        < corners    
21.            android:topLeftRadius = "5dip"    
22.            android:topRightRadius = "5dip"    
23.            android:bottomLeftRadius = "5dip"    
24.            android:bottomRightRadius = "5dip"   />    
25.      </ shape >    
26.   </ item >      
27.</ layer-list >    
view plaincopy to clipboardprint?
01.//bg_alibuybutton_default.xml   
02.<?xml  
03. version="1.0" encoding="utf-8"?>  
04.<layer-list    
05.xmlns:android="http://schemas.android.com/apk/res/android">  
06.   <item>  
07.      <shape android:shape="rectangle">    
08.         <solid android:color="#FFEC7600" />  
09.         <corners  
10.            android:topLeftRadius="5dip"  
11.            android:topRightRadius="5dip"  
12.            android:bottomLeftRadius="5dip"  
13.            android:bottomRightRadius="5dip" />  
14.      </shape>  
15.   </item>  
16.   <item android:top="1px" android:bottom="1px" android:left="1px"    
17.android:right="1px">  
18.     <shape>  
19.        <gradient    
20.            android:startColor="#FFEC7600" android:endColor="#FFFED69E"    
21.            android:type="linear" android:angle="90"  
22.            android:centerX="0.5" android:centerY="0.5" />  
23.        <corners  
24.            android:topLeftRadius="5dip"  
25.            android:topRightRadius="5dip"  
26.            android:bottomLeftRadius="5dip"  
27.            android:bottomRightRadius="5dip" />  
28.      </shape>  
29.   </item>     
30.</layer-list>  
//bg_alibuybutton_default.xml
<?xml
 version="1.0" encoding="utf-8"?>
<layer-list 
xmlns:android="http://schemas.android.com/apk/res/android">
   <item>
      <shape android:shape="rectangle"> 
         <solid android:color="#FFEC7600" />
         <corners
   android:topLeftRadius="5dip"
         android:topRightRadius="5dip"
         android:bottomLeftRadius="5dip"
         android:bottomRightRadius="5dip" />
      </shape>
   </item>
   <item android:top="1px" android:bottom="1px" android:left="1px" 
android:right="1px">
     <shape>
        <gradient 
         android:startColor="#FFEC7600" android:endColor="#FFFED69E" 
         android:type="linear" android:angle="90"
   android:centerX="0.5" android:centerY="0.5" />
  <corners
   android:topLeftRadius="5dip"
         android:topRightRadius="5dip"
         android:bottomLeftRadius="5dip"
         android:bottomRightRadius="5dip" />
      </shape>
   </item>  
</layer-list> 
同样定义bg_alibuybutton_pressed.xml和 bg_alibuybutton_selected.xml,内容相同,就是渐变颜色不同,用于按钮按下后的背景变化效果。

(b) 定义按钮按下后的效果变化描述文件drawable/bg_alibuybutton.xml,代码如下。

view plain copy to clipboard print ? 
01.<? xml   version = "1.0"   encoding = "UTF-8" ?>    
02.< selector   xmlns:android = "http://schemas.android.com/apk/res/android" >    
03.    < item   android:state_pressed = "true"    
04.        android:drawable = "@drawable/bg_alibuybutton_pressed"   />    
05.    < item   android:state_focused = "true"    
06.        android:drawable = "@drawable/bg_alibuybutton_selected"   />    
07.    < item   android:drawable = "@drawable/bg_alibuybutton_default"   />    
08.</ selector >    
view plaincopy to clipboardprint?
01.<?xml  
02. version="1.0" encoding="UTF-8"?>  
03.<selector    
04.xmlns:android="http://schemas.android.com/apk/res/android">  
05.    <item android:state_pressed="true"  
06.        android:drawable="@drawable/bg_alibuybutton_pressed" />  
07.    <item android:state_focused="true"  
08.        android:drawable="@drawable/bg_alibuybutton_selected" />  
09.    <item android:drawable="@drawable/bg_alibuybutton_default" />  
10.</selector>  
<?xml
 version="1.0" encoding="UTF-8"?>
<selector 
xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:state_pressed="true"
  android:drawable="@drawable/bg_alibuybutton_pressed" />
 <item android:state_focused="true"
  android:drawable="@drawable/bg_alibuybutton_selected" />
 <item android:drawable="@drawable/bg_alibuybutton_default" />
</selector> 
(c) 在你需要的界面定义文件中,如layout/main.xml中定义一个Button控件。

view plain copy to clipboard print ? 
01.< Button    
02.    android:layout_width = "120dip"    
03.    android:layout_height = "40dip"    
04.    android:text = "矢量背景按钮"         android:background = "@drawable/bg_alibuybutton"   />    
view plaincopy to clipboardprint?
01.     
02.  <Button  
03.        android:layout_width="120dip"  
04.        android:layout_height="40dip"  
05.        android:text="矢量背景按钮"          
06.android:background="@drawable/bg_alibuybutton" />  
  
  <Button
     android:layout_width="120dip"
     android:layout_height="40dip"
     android:text="矢量背景按钮"     
android:background="@drawable/bg_alibuybutton" /> 
这样,自定义背景的按钮就可以使用了,在实现onClick方法后就可以响应操作。

 

2. 9-patch图片背景方式

此种方法相对复杂繁琐,但可以制作出更多、更复杂样式的按钮图样。

什么是9-patch格式呢?

9-patch格式,是在Android(安卓)中特有的一种PNG图片格式,以"***.9.png"结尾。此种格式的图片定义了可以伸缩拉伸的区域和文字显示区域,这样,就可以在Android(安卓)开发中对非矢量图进行拉伸而仍然保持美观。如果使用位图而没有经过9-patch处理的话,效果就会想第一张截图中的“普通图片背景按钮”那样被无情的拉伸,影响效果。Android(安卓)中大量用了这种技术,默认的按钮的背景就是用了类似的方法实现的。我们看一下 google官方的描述:

 

 

该格式相对于一般PNG图片来说,多了上下左右各一条1px的黑线。左、上黑线隔开了9个格子,当中一个格子(见上图Strechable Area区域)声明为可以进行拉伸。右、下两条黑线所定义的Paddingbox区域是在该图片当做背景时,能够在图片上填写文字的区域。每条黑线都是可以不连续的,这样就可以定义出很多自动拉伸的规格。Android(安卓) sdk中提供了设置的工具,启动命令位于:$ANDROID_SDK/tools/draw9patch.bat,使用它对于原始PNG进行设置9- patch格式,非常方便,如下图。

         

draw9patch工具的右侧是能够看到各方向拉伸后的效果图,你所要做的就是在图上最外侧一圈1px宽的像素上涂黑线。

注意,在draw9patch.bat第一次运行时,sdk2.2版本上会报错:java.lang.NoClassDefFoundError:org/jdesktop/swingworker/SwingWorker。需要下载swing-worker-1.1.jar ,放入$android_sdk/tools/lib路径下,成功运行。

此种方法实现的步骤如下。

(a) 使用draw9patch.bat作完图片后,得到两张按钮背景,分别是正常和按下状态下的,命名为bg_btn.9.png和 bg_btn_2.9.png。

(b) 编写图片使用描述文件bg_9patchbutton.xml。

view plain copy to clipboard print ? 
01.// in bg_9patchbutton.xml   
02.<? xml   version = "1.0"   encoding = "UTF-8" ?>    
03.< selector   xmlns:android = "http://schemas.android.com/apk/res/android" >    
04.    < item   android:state_pressed = "true"    
05.        android:drawable = "@drawable/bg_btn_2"   />    
06.    < item   android:state_focused = "true"    
07.        android:drawable = "@drawable/bg_btn_2"   />    
08.    < item   android:drawable = "@drawable/bg_btn"   />    
09.</ selector >    
view plaincopy to clipboardprint?
01.//    
02.in bg_9patchbutton.xml   
03.<?xml version="1.0" encoding="UTF-8"?>  
04.<selector    
05.xmlns:android="http://schemas.android.com/apk/res/android">  
06.    <item android:state_pressed="true"  
07.        android:drawable="@drawable/bg_btn_2" />  
08.    <item android:state_focused="true"  
09.        android:drawable="@drawable/bg_btn_2" />  
10.    <item android:drawable="@drawable/bg_btn" />  
11.</selector>  
// 
in bg_9patchbutton.xml
<?xml version="1.0" encoding="UTF-8"?>
<selector 
xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:state_pressed="true"
  android:drawable="@drawable/bg_btn_2" />
 <item android:state_focused="true"
  android:drawable="@drawable/bg_btn_2" />
 <item android:drawable="@drawable/bg_btn" />
</selector> 
(c) 在界面定义文件 layout/main.xml中添加Button、ImageButton按钮控件的定义。Button、ImageButton都是可以使用背景属性的。

view plain copy to clipboard print ? 
01.< Button    
02.    android:layout_width = "120dip"    
03.    android:layout_height = "40dip"    
04.    android:text = "9-patch图片背景按钮"    
05.    android:background = "@drawable/bg_9patchbutton"   />    
06.< Button    
07.    android:layout_width = "200dip"    
08.    android:layout_height = "40dip"    
09.    android:text = "9-patch图片背景按钮"    
10.    android:background = "@drawable/bg_9patchbutton"   />    
11.< Button    
12.    android:layout_width = "120dip"    
13.    android:layout_height = "80dip"    
14.    android:text = "9-patch图片背景按钮"    
15.    android:background = "@drawable/bg_9patchbutton"   />    
16.< ImageButton    
17.    android:layout_width = "120dip"    
18.    android:layout_height = "40dip"    
19.    android:src = "@drawable/bg_9patchbutton"    
20.    android:scaleType = "fitXY"    
21.    android:background = "@android:color/transparent"   />    
view plaincopy to clipboardprint?
01.  
02.<Button  
03.    android:layout_width="120dip"  
04.    android:layout_height="40dip"  
05.    android:text="9-patch图片背景按钮"  
06.    android:background="@drawable/bg_9patchbutton" />  
07.  <Button  
08.    android:layout_width="200dip"  
09.    android:layout_height="40dip"  
10.    android:text="9-patch图片背景按钮"  
11.    android:background="@drawable/bg_9patchbutton" />  
12.  <Button  
13.    android:layout_width="120dip"  
14.    android:layout_height="80dip"  
15.    android:text="9-patch图片背景按钮"  
16.    android:background="@drawable/bg_9patchbutton" />  
17.  <ImageButton  
18.    android:layout_width="120dip"  
19.    android:layout_height="40dip"  
20.    android:src="@drawable/bg_9patchbutton"  
21.    android:scaleType="fitXY"  
22.    android:background="@android:color/transparent" />  
  
  <Button
     android:layout_width="120dip"
     android:layout_height="40dip"
     android:text="9-patch图片背景按钮"
     android:background="@drawable/bg_9patchbutton" />
    <Button
     android:layout_width="200dip"
     android:layout_height="40dip"
     android:text="9-patch图片背景按钮"
     android:background="@drawable/bg_9patchbutton" />
    <Button
     android:layout_width="120dip"
     android:layout_height="80dip"
     android:text="9-patch图片背景按钮"
     android:background="@drawable/bg_9patchbutton" />
    <ImageButton
     android:layout_width="120dip"
     android:layout_height="40dip"
     android:src="@drawable/bg_9patchbutton"
     android:scaleType="fitXY"
     android:background="@android:color/transparent" /> 
以上2种实现按钮的美化,都是标准的矩形按钮为基础。在一些应用中我们可以看到漂亮的自定义形状的异形按钮,这是怎么实现的呢?经过一番研究和实践,找出了一种方便的方法,就是使用ImageButton加上9-patch就可以实现漂亮的自动延伸效果。

3. 自定义形状、颜色、图样的按钮的实现

步骤如下。

(a) 设计一张自定义形状风格背景的图片,如下图。

 

(b) 未点击和按下后的状态各做一张,形成一套图片,如下图。

 forward.png    forward2.png

(c) 创建和编写按钮不同状态的图片使用描述文件drawable/ib_forward.xml

view plain copy to clipboard print ? 
01.// ib_forward.xml   
02.<? xml   version = "1.0"   encoding = "UTF-8" ?>    
03.< selector   xmlns:android = "http://schemas.android.com/apk/res/android" >    
04.    < item   android:state_pressed = "true"    
05.        android:drawable = "@drawable/forward2"   />    
06.    < item   android:state_focused = "true"    
07.        android:drawable = "@drawable/forward2"   />    
08.    < item   android:drawable = "@drawable/forward"   />    
09.</ selector >    
view plaincopy to clipboardprint?
01.//    
02.ib_forward.xml   
03.<?xml version="1.0" encoding="UTF-8"?>  
04.<selector    
05.xmlns:android="http://schemas.android.com/apk/res/android">  
06.    <item android:state_pressed="true"  
07.        android:drawable="@drawable/forward2" />  
08.    <item android:state_focused="true"  
09.        android:drawable="@drawable/forward2" />  
10.    <item android:drawable="@drawable/forward" />  
11.</selector>  
// 
ib_forward.xml
<?xml version="1.0" encoding="UTF-8"?>
<selector 
xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:state_pressed="true"
  android:drawable="@drawable/forward2" />
 <item android:state_focused="true"
  android:drawable="@drawable/forward2" />
 <item android:drawable="@drawable/forward" />
</selector> 
(d) 在界面定义文件 layout/main.xml中添加ImageButton按钮控件的定义。

view plain copy to clipboard print ? 
01.// in layout/main.xml   
02.    < ImageButton    
03.        android:layout_width = "80dip"    
04.        android:layout_height = "40dip"    
05.        android:src = "@drawable/ib_forword"    
06.        android:scaleType = "fitXY"    
07.        android:background = "@android:color/transparent"   />

相关文章
|
4月前
|
Android开发 UED 计算机视觉
Android自定义view之线条等待动画(灵感来源:金铲铲之战)
本文介绍了一款受游戏“金铲铲之战”启发的Android自定义View——线条等待动画的实现过程。通过将布局分为10份,利用`onSizeChanged`测量最小长度,并借助画笔绘制动态线条,实现渐变伸缩效果。动画逻辑通过四个变量控制线条的增长与回退,最终形成流畅的等待动画。代码中详细展示了画笔初始化、线条绘制及动画更新的核心步骤,并提供完整源码供参考。此动画适用于加载场景,提升用户体验。
406 5
Android自定义view之线条等待动画(灵感来源:金铲铲之战)
|
4月前
|
Android开发
Android自定义view之利用PathEffect实现动态效果
本文介绍如何在Android自定义View中利用`PathEffect`实现动态效果。通过改变偏移量,结合`PathEffect`的子类(如`CornerPathEffect`、`DashPathEffect`、`PathDashPathEffect`等)实现路径绘制的动态变化。文章详细解析了各子类的功能与参数,并通过案例代码展示了如何使用`ComposePathEffect`组合效果,以及通过修改偏移量实现动画。最终效果为一个菱形图案沿路径运动,源码附于文末供参考。
|
4月前
|
Android开发 开发者
Android自定义view之利用drawArc方法实现动态效果
本文介绍了如何通过Android自定义View实现动态效果,重点使用`drawArc`方法完成圆弧动画。首先通过`onSizeChanged`进行测量,初始化画笔属性,设置圆弧相关参数。核心思路是不断改变圆弧扫过角度`sweepAngle`,并调用`invalidate()`刷新View以实现动态旋转效果。最后附上完整代码与效果图,帮助开发者快速理解并实践这一动画实现方式。
129 0
|
4月前
|
Android开发 数据安全/隐私保护 开发者
Android自定义view之模仿登录界面文本输入框(华为云APP)
本文介绍了一款自定义输入框的实现,包含静态效果、hint值浮动动画及功能扩展。通过组合多个控件完成界面布局,使用TranslateAnimation与AlphaAnimation实现hint文字上下浮动效果,支持密码加密解密显示、去除键盘回车空格输入、光标定位等功能。代码基于Android平台,提供完整源码与attrs配置,方便复用与定制。希望对开发者有所帮助。
|
4月前
|
XML Java Android开发
Android自定义view之网易云推荐歌单界面
本文详细介绍了如何通过自定义View实现网易云音乐推荐歌单界面的效果。首先,作者自定义了一个圆角图片控件`MellowImageView`,用于绘制圆角矩形图片。接着,通过将布局放入`HorizontalScrollView`中,实现了左右滑动功能,并使用`ViewFlipper`添加图片切换动画效果。文章提供了完整的代码示例,包括XML布局、动画文件和Java代码,最终展示了实现效果。此教程适合想了解自定义View和动画效果的开发者。
208 65
Android自定义view之网易云推荐歌单界面
|
4月前
|
XML 前端开发 Android开发
一篇文章带你走近Android自定义view
这是一篇关于Android自定义View的全面教程,涵盖从基础到进阶的知识点。文章首先讲解了自定义View的必要性及简单实现(如通过三个构造函数解决焦点问题),接着深入探讨Canvas绘图、自定义属性设置、动画实现等内容。还提供了具体案例,如跑马灯、折线图、太极图等。此外,文章详细解析了View绘制流程(measure、layout、draw)和事件分发机制。最后延伸至SurfaceView、GLSurfaceView、SVG动画等高级主题,并附带GitHub案例供实践。适合希望深入理解Android自定义View的开发者学习参考。
508 84
|
4月前
|
Android开发 开发者
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
本文详细介绍了如何通过自定义 `attrs.xml` 文件实现 Android 自定义 View 的属性配置。以一个包含 TextView 和 ImageView 的 DemoView 为例,讲解了如何使用自定义属性动态改变文字内容和控制图片显示隐藏。同时,通过设置布尔值和点击事件,实现了图片状态的切换功能。代码中展示了如何在构造函数中解析自定义属性,并通过方法 `setSetting0n` 和 `setbackeguang` 实现功能逻辑的优化与封装。此示例帮助开发者更好地理解自定义 View 的开发流程与 attrs.xml 的实际应用。
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
|
4月前
|
前端开发 Android开发 UED
讲讲Android为自定义view提供的SurfaceView
本文详细介绍了Android中自定义View时使用SurfaceView的必要性和实现方式。首先分析了在复杂绘制逻辑和高频界面更新场景下,传统View可能引发卡顿的问题,进而引出SurfaceView作为解决方案。文章通过Android官方Demo展示了SurfaceView的基本用法,包括实现`SurfaceHolder.Callback2`接口、与Activity生命周期绑定、子线程中使用`lockCanvas()`和`unlockCanvasAndPost()`方法完成绘图操作。
102 3
|
4月前
|
Android开发 开发者
Android自定义view之围棋动画(化繁为简)
本文介绍了Android自定义View的动画实现,通过两个案例拓展动态效果。第一个案例基于`drawArc`方法实现单次动画,借助布尔值控制动画流程。第二个案例以围棋动画为例,从简单的小球直线运动到双向变速运动,最终实现循环动画效果。代码结构清晰,逻辑简明,展示了如何化繁为简实现复杂动画,帮助读者拓展动态效果设计思路。文末提供完整源码,适合初学者和进阶开发者学习参考。
Android自定义view之围棋动画(化繁为简)
|
10月前
|
缓存 前端开发 Android开发
安卓开发中的自定义视图:从零到英雄
【10月更文挑战第42天】 在安卓的世界里,自定义视图是一块画布,让开发者能够绘制出独一无二的界面体验。本文将带你走进自定义视图的大门,通过深入浅出的方式,让你从零基础到能够独立设计并实现复杂的自定义组件。我们将探索自定义视图的核心概念、实现步骤,以及如何优化你的视图以提高性能和兼容性。准备好了吗?让我们开始这段创造性的旅程吧!
146 1