在Android开发过程中,经常需要改变控件的默认样式, 那么通常会使用多个图片来解决。不过这种方式可能需要多个图片,比如一个按钮,需要点击时的式样图片,默认的式样图片。 这样就容易使apk变大。

 

除了使用drawable这样的图片外,还有其他方法吗?

 

自定义图形shape,Android上支持以下几种属性shape、gradient、stroke、corners、padding、solid等。

 

先来看两个例子:

 

 


    1. <shape  
    2. xmlns:android="http://schemas.android.com/apk/res/android"  
    3. android:shape="rectangle">  
    4. <gradient android:startColor="#FFFF0000"  
    5. android:endColor="#80FF00FF"  
    6. android:angle="270" />  
    7. <padding android:left="50dp"  
    8. android:top="20dp" android:right="7dp"  
    9. android:bottom="7dp" />  
    10. <corners android:radius="8dp" />  
    11. </shape>


     

     

     

    效果:


     

     


      1. <?xml version="1.0" encoding="UTF-8"?>  
      2. <shape android:shape="rectangle"  
      3. xmlns:android="http://schemas.android.com/apk/res/android">  
      4. <solid android:color="#b4000000" />  
      5. <stroke android:width="2.0dip"  
      6. android:color="#b4ffffff"  
      7. android:dashWidth="3.0dip"  
      8. android:dashGap="0.0dip" />  
      9. <padding android:left="7.0dip"  
      10. android:top="7.0dip" android:right="7.0dip"  
      11. android:bottom="7.0dip" />  
      12. <corners android:radius="8.0dip" />  
      13. </shape>


       

       

       

      效果:


      【Android UI】 Shape详解 (GradientDrawable)_2d

       

       

      总结一下Shape的所有子属性,如图:

       


      【Android UI】 Shape详解 (GradientDrawable)_2d_02

       

      简单说明一下:

       

      gradient   -- 对应颜色渐变。 startcolor、endcolor就不多说了。 android:angle 是指从哪个角度开始变。

      solid      --  填充。

      stroke   --  描边。

      corners  --  圆角。

      android:padding_left、android:padding_right这些是一个道理。

       

       


       

       

      上面这些不是本讲重点。 本讲的重点是这些xml中属性,与Java类的对应关系, 以及如何使用Java类写出上面一样的效果!

       

      首先来看对应关系:

       

      父节点 shape   --   ShapeDrawable

       [子节点] gradient   --  

       [子节点] padding   --   

      [子节点] corners   --   setCornerRadius 、setCornerRadii

       [子节点] solid       --    

      setStroke

       [子节点]  size --   setSize

       

      发现只有几个是可以对应的~~ 看来通过Java代码来实现上述是行不通的..

      如果你对Android系统自带的UI控件感觉不够满意,可以尝试下自定义控件,我们就以Button为例,很早以前Android123就写到过Android Button按钮控件美化方法里面提到了xml的selector构造。当然除了使用drawable这样的图片外今天Android开发网谈下自定义图形shape的方法,对于Button控件Android上支持以下几种属性shape、gradient、stroke、corners等。 

            我们就以目前系统的Button的selector为例说下: 


      Xml代码  


      1. <shape>  
      2. <gradient  
      3. android:startColor="#ff8c00"  
      4. android:endColor="#FFFFFF"  
      5. android:angle="270" />  
      6. <stroke  
      7. android:width="2dp"  
      8. android:color="#dcdcdc" />  
      9. <solid android:color="#ff9d77"/>  
      10. <corners  
      11. android:radius="2dp" />  
      12. <padding  
      13. android:left="10dp"  
      14. android:top="10dp"  
      15. android:right="10dp"  
      16. android:bottom="10dp" />  
      17. </shape>


      对于上面,这条shape的定义,分别为渐变,在gradient中startColor属性为开始的颜色,endColor为渐变结束的颜色,下面的 angle是角度。接下来是stroke可以理解为边缘,corners为拐角这里radius属性为半径,最后是相对位置属性padding。 



          对于一个Button完整的定义可以为 


      Xml代码  



        1. <?xml version="1.0" encoding="utf-8"?>  
        2. <selector  
        3. xmlns:android="http://schemas.android.com/apk/res/android">  
        4. <item android:state_pressed="true" >  
        5. <shape>  
        6. <gradient  
        7. android:startColor="#ff8c00"  
        8. android:endColor="#FFFFFF"  
        9. android:angle="270" />  
        10. <stroke  
        11. android:width="2dp"  
        12. android:color="#dcdcdc" />  
        13. <corners  
        14. android:radius="2dp" />  
        15. <padding  
        16. android:left="10dp"  
        17. android:top="10dp"  
        18. android:right="10dp"  
        19. android:bottom="10dp" />  
        20. </shape>  
        21. </item>  
        22.   
        23. <item android:state_focused="true" >  
        24. <shape>  
        25. <gradient  
        26. android:startColor="#ffc2b7"  
        27. android:endColor="#ffc2b7"  
        28. android:angle="270" />  
        29. <stroke  
        30. android:width="2dp"  
        31. android:color="#dcdcdc" />  
        32. <corners  
        33. android:radius="2dp" />  
        34. <padding  
        35. android:left="10dp"  
        36. android:top="10dp"  
        37. android:right="10dp"  
        38. android:bottom="10dp" />  
        39. </shape>  
        40. </item>  
        41.   
        42. <item>        
        43. <shape>  
        44. <gradient  
        45. android:startColor="#ff9d77"  
        46. android:endColor="#ff9d77"  
        47. android:angle="270" />  
        48. <stroke  
        49. android:width="2dp"  
        50. android:color="#fad3cf" />  
        51. <corners  
        52. android:radius="2dp" />  
        53. <padding  
        54. android:left="10dp"  
        55. android:top="10dp"  
        56. android:right="10dp"  
        57. android:bottom="10dp" />  
        58. </shape>  
        59. </item>  
        60. </selector>



          注意Android123提示大家,以上几个item的区别主要是体现在state_pressed按下或state_focused获得焦点时,当当来判断显示什么类型,而没有state_xxx属性的item可以看作是常规状态下。 



        附shape全部属性定义: 


        Xml代码  



          1. <?xml version="1.0" encoding="utf-8"?>   
          2. <shape xmlns:android="http://schemas.android.com/apk/res/android"   
          3. android:shape=["rectangle" | "oval" | "line" | "ring"] >   
          4. <gradient   
          5. android:angle="integer"   
          6. android:centerX="integer"   
          7. android:centerY="integer"   
          8. android:centerColor="integer"   
          9. android:endColor="color"   
          10. android:gradientRadius="integer"   
          11. android:startColor="color"   
          12. android:type=["linear" | "radial" | "sweep"]   
          13. android:usesLevel=["true" | "false"] />   
          14. <solid   
          15. android:color="color" />   
          16. <stroke   
          17. android:width="integer"   
          18. android:color="color"   
          19. android:dashWidth="integer" <!--点划线-->  
          20. android:dashGap="integer" />   
          21. <padding   
          22. android:left="integer"   
          23. android:top="integer"   
          24. android:right="integer"   
          25. android:bottom="integer" />   
          26. <corners   
          27. android:radius="integer"   
          28. android:topLeftRadius="integer"   
          29. android:topRightRadius="integer"   
          30. android:bottomLeftRadius="integer"   
          31. android:bottomRightRadius="integer" />   
          32. </shape>