当然除了使用drawable这样的图片外今天谈下自定义图形shape的方法,对于button控件android上支持以下几种属性shape、gradient、stroke、corners等。

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

<shape>            <gradient                android:startcolor="#ff8c00"                android:endcolor="#ffffff"                android:angle="270" />            <stroke                android:width="2dp"                android:color="#dcdcdc" />            <corners                android:radius="2dp" />            <padding                android:left="10dp"                android:top="10dp"                android:right="10dp"                android:bottom="10dp" />        </shape>

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

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

<?xml version="1.0" encoding="utf-8"?><selector    xmlns:android="http://www.norkoo.com">    <item android:state_pressed="true" >        <shape>            <gradient                android:startcolor="#ff8c00"                android:endcolor="#ffffff"                android:angle="270" />            <stroke                android:width="2dp"                android:color="#dcdcdc" />            <corners                android:radius="2dp" />            <padding                android:left="10dp"                android:top="10dp"                android:right="10dp"                android:bottom="10dp" />        </shape>    </item>    <item android:state_focused="true" >        <shape>            <gradient                android:startcolor="#ffc2b7"                android:endcolor="#ffc2b7"                android:angle="270" />            <stroke                android:width="2dp"                android:color="#dcdcdc" />            <corners                android:radius="2dp" />            <padding                android:left="10dp"                android:top="10dp"                android:right="10dp"                android:bottom="10dp" />        </shape>    </item>    <item>                <shape>            <gradient                android:startcolor="#ff9d77"                android:endcolor="#ff9d77"                android:angle="270" />            <stroke                android:width="2dp"                android:color="#fad3cf" />            <corners                android:radius="2dp" />            <padding                android:left="10dp"                android:top="10dp"                android:right="10dp"                android:bottom="10dp" />        </shape>    </item></selector>

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

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android" >

<item

android:color="hex_color"

android:state_pressed=["true" | "false"]

android:state_focused=["true" | "false"]

android:state_selected=["true" | "false"]

android:state_active=["true" | "false"]

android:state_checkable=["true" | "false"]

android:state_checked=["true" | "false"]

android:state_enabled=["true" | "false"]

android:state_window_focused=["true" | "false"] />

</selector>

elements:

<selector>

必须。必须是根元素。包含一个或多个<item>元素。

attributes:

xmlns:android

string,必须。定义xml的命名空间,必须是

“http://schemas.android.com/apk/res/android”.

<item>

定义特定状态的color,通过它的特性指定。必须是<selector>的子元素。

attributes:

android:color

16进制颜色。必须。这个颜色由rgb值指定,可带alpha。

这个值必须以“#”开头,后面跟随alpha-red-green-blue信息:

l #rgb

l #argb

l #rrggbb

l #aarrggbb

android:state_pressed

boolean。“true”表示按下状态使用(例如按钮按下);“false”表示非按下状态使用。

android:state_focused

boolean。“true”表示聚焦状态使用(例如使用滚动球/d-pad聚焦button);“false”表示非聚焦状态使用。

android:state_selected

boolean。“true”表示选中状态使用(例如tab打开);“false”表示非选中状态使用。

android:state_checkable

boolean。“true”表示可勾选状态时使用;“false”表示非可勾选状态使用。(只对能切换可勾选—非可勾选的构件有用。)

android:state_checked

boolean。“true”表示勾选状态使用;“false”表示非勾选状态使用。

android:state_enabled

boolean。“true”表示可用状态使用(能接收触摸/点击事件);“false”表示不可用状态使用。

android:window_focused

boolean。“true”表示应用程序窗口有焦点时使用(应用程序在前台);“false”表示无焦点时使用(例如notification栏拉下或对话框显示)。

注意:记住一点,statelist中第一个匹配当前状态的item会被使用。因此,如果第一个item没有任何状态特性的话,那么它将每次都被使用,这也是为什么默认的值必须总是在最后(如下面的例子所示)。

examples:

xml文件保存在res/color/button_text.xml

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:state_pressed="true"

android:color="#ffff0000"/> <!-- pressed -->

<item android:state_focused="true"

android:color="#ff0000ff"/> <!-- focused -->

<item android:color="#ff000000"/> <!-- default -->

</selector>

这个layout xml会应用colorstatelist到一个view上:

<button

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/button_text"

android:textcolor="@color/button_text" />

在android上开发项目,如果仅仅是采用默认的样式可能不是很美观,需要编写响应的样式来使界面美观,在iphone上常用的圆角ListView的实现。

本人实现的原理如下:

通过重写ListView中拦截触摸的事件方式,在生成ListView时候根据不同行采用不同的样式。如第一个行,最末一行,和中建行。(特殊的情况下只有一行的时候,四个角均为圆角考虑)。

实现如下:

最后一行为时候,下方两个角为圆角样式如下:

app_list_corner_round_bottom.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <gradient android:startColor="#BFEEFF"         android:endColor="#40B9FF"         android:angle="270"/>    <corners android:bottomLeftRadius="6dip"        android:bottomRightRadius="6dip" /></shape> 

第一行为圆角且仅仅为一条记录使用样式:

app_list_corner_round.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <gradient android:startColor="#BFEEFF"         android:endColor="#40B9FF"         android:angle="270"/>    <corners android:topLeftRadius="6dip"        android:topRightRadius="6dip"        android:bottomLeftRadius="6dip"        android:bottomRightRadius="6dip"/></shape> 

第一行为圆角且有多条记录使用样式:

app_list_corner_round_top.xml

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <gradient android:startColor="#BFEEFF"         android:endColor="#40B9FF"         android:angle="270"/>    <corners android:topLeftRadius="6dip"        android:topRightRadius="6dip"/></shape> 

多行记录非第一行和最末一行使用的样式:

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <gradient android:startColor="#BFEEFF"         android:endColor="#40B9FF"         android:angle="270"/></shape> 

重写的ListView

package com.easyway.listview.corner;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.AdapterView;import android.widget.ListView;/** *  圆角ListView *      重写ListView的样式实现相关的样式 *  app_list_corner_round_top.xml *  <?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <gradient android:startColor="#BFEEFF"         android:endColor="#40B9FF"         android:angle="270"/>    <corners android:topLeftRadius="6dip"        android:topRightRadius="6dip"/></shape>  *   *  android:shape 配置的是图形的形式,主要包括方形、圆形等,上边代码为方形。 *  gradient节点主要配置起点颜色、终点颜色、中间点的坐标、中间点的颜色、渐变角度(90度为上下渐变,0为左右渐变), *  padding节点主要配置上下左右边距, *  corners节点配置四周园角的半径。  *   *  * @Title:  * @Description: 实现TODO * @Copyright:Copyright (c) 2011 * @Company:易程科技股份有限公司 * @Date:2012-7-16 * @author  longgangbai * @version 1.0 */public class CornerListView extends ListView {    public CornerListView(Context context) {        super(context);    }    public CornerListView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);    }    public CornerListView(Context context, AttributeSet attrs) {        super(context, attrs);    }    /**     * 重写此方式实现不同行的样式不一样     *      */    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        switch (ev.getAction()) {        //        case MotionEvent.ACTION_DOWN:                int x = (int) ev.getX();                int y = (int) ev.getY();                //返回记录数据行数                int itemnum = pointToPosition(x, y);                if (itemnum == AdapterView.INVALID_POSITION)                        break;                                 else{                if(itemnum==0){                        if(itemnum==(getAdapter().getCount()-1)){                                                                setSelector(R.drawable.app_list_corner_round); //仅仅一行记录的样式                        }else{                            setSelector(R.drawable.app_list_corner_round_top); //多行且第一行的样式                        }                }else if(itemnum==(getAdapter().getCount()-1))  //最后一行的样式                        setSelector(R.drawable.app_list_corner_round_bottom);                else{                                                setSelector(R.drawable.app_list_corner_shape);                }                }                break;        case MotionEvent.ACTION_UP:                break;        }                return super.onInterceptTouchEvent(ev);    }}

主要布局类main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:id="@+id/listview_layout"    android:layout_height="fill_parent"    android:orientation="vertical" >    <LinearLayout        android:id="@+id/linearLayout1"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical"        android:paddingBottom="5dp"        android:paddingLeft="25dp"        android:paddingTop="15dp" >        <TextView            android:id="@+id/menu_1"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="@string/setting"            android:textColor="@color/gray" />    </LinearLayout>    <com.easyway.listview.corner.CornerListView        android:id="@+id/list1"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_marginLeft="15dp"        android:layout_marginRight="15dp"        android:background="@drawable/shape_bg_listview"        android:cacheColorHint="@null"/></LinearLayout>

每行的布局:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <RelativeLayout        android:id="@+id/relativeLayout1"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:paddingBottom="10dip"        android:paddingLeft="15dip"        android:paddingRight="5dip"        android:paddingTop="10dip" >        <TextView            android:id="@+id/item_title"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentLeft="true"            android:layout_alignParentTop="true"            android:textColor="@color/gray"            android:textSize="15sp" />        <ImageView            android:id="@+id/imageView1"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:layout_centerVertical="true"            android:layout_marginRight="16dp"            android:src="@drawable/right" />            </RelativeLayout></LinearLayout>

主要类:

package com.easyway.listview.corner;import java.util.ArrayList;import java.util.HashMap;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.LinearLayout;import android.widget.SimpleAdapter;/** * Android实现圆角ListView示例 *          实现圆角ListView原理主要采用添加相关的样式布局。 *          通过重写ListView中特定的方法 *              拦截触摸事件的方法。 *              public boolean onInterceptTouchEvent(MotionEvent ev)  *              根据横轴坐标计算行数,并实现 *               * @Title:  * @Description: 实现TODO * @Copyright:Copyright (c) 2011 * @Company:易程科技股份有限公司 * @Date:2012-7-16 * @author  longgangbai * @version 1.0 */public class RoundCornerActivity extends Activity {private CornerListView cornerListView = null;private ArrayList<HashMap<String, String>> maplist = null;    private LinearLayout linearLayout;/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//设置布局setContentView(R.layout.main);//获取布局对象linearLayout=(LinearLayout)findViewById(R.id.listview_layout);//设置壁纸为背景图片linearLayout.setBackgroundDrawable(getWallpaper());//获取初始化数据maplist=getData();        //创建一个适配器对象SimpleAdapter adapter1 = new SimpleAdapter(this, maplist,R.layout.simple_list_item_1, new String[] { "item" },new int[] { R.id.item_title });//创建ListView对象cornerListView = (CornerListView) findViewById(R.id.list1);//设置适配器cornerListView.setAdapter(adapter1);initListener();}private void initListener() {//添加响应时间cornerListView.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {if (arg2 == 0) {System.out.println("0");}else{System.out.println("1");}}});}/** * 模拟数据 * @return */public ArrayList<HashMap<String, String>> getData() {maplist = new ArrayList<HashMap<String, String>>();HashMap<String, String> map1 = new HashMap<String, String>();HashMap<String, String> map2 = new HashMap<String, String>();HashMap<String, String> map3 = new HashMap<String, String>();HashMap<String, String> map4 = new HashMap<String, String>();map1.put("item", "公交");map2.put("item", "火车");map3.put("item", "地铁");map4.put("item", "航空");maplist.add(map1);maplist.add(map2);maplist.add(map3);maplist.add(map4);return maplist;}}

更多相关文章

  1. Android(安卓)Material Design动画 View state changes|视图状态
  2. Android最好用的播放器ExoPlayer的使用及自定义UI
  3. Android(安卓)解决启动页白屏或者黑屏的问题
  4. 修改系统action bar字体大小、粗细、颜色等样式的方法
  5. 强制保持Android(安卓)Activity状态
  6. 关于使用Android(安卓)Application的注意点
  7. Android(安卓)Activity生命周期管理 .
  8. android Activity设置透明主题样式方法
  9. Android的BroadcastReciver收不到Broadcast(系统广播)的原因之一

随机推荐

  1. Android(安卓)OpenGL 显示基本图形及相关
  2. 普通android工程转换为C/C++工程之后,再还
  3. 快速Android开发系列通信篇之EventBus
  4. Android系统
  5. Android将转为闭源模式么?
  6. Android的日志工具Log及制定日志工具
  7. [Android]直接使用代码建立Android视图元
  8. Ubuntu下android学习——(1)开发环境的搭建
  9. Android读写XML(中)——SAX
  10. 瘸腿蛤蟆笔记cocos2d-x-3.2移植到到andro