0%

与上文自定义Button样式相同,新建Android XML文件,类型选Drawable,根结点选selector,在这定义具体的样式。

<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:state_pressed="true"
        android:drawable="@drawable/focused" />
    <item android:state_checked="false" android:state_pressed="true"
        android:drawable="@drawable/normal" />
    <item android:state_checked="false" android:drawable="@drawable/normal" />
    <item android:state_checked="true" android:drawable="@drawable/focused" />
</selector>

state_checked 选中状态 state_pressed按下状态 即分别设置checkbox选中和没选中时,按下和没按下时显示的图片. 应用到Checkbox与Button不同,并不是设置Background属性,而是设置style属性,所以我们要写一个style。 在strings.xml写一个style,

<style name="MyCheckBox" parent="@android:style/Widget.CompoundButton.CheckBox">
<item name="android:button">@drawable/checkbox</item>
</style>

应用到Checkbox:

    <CheckBox android:layout_width="wrap_content" 
    android:layout_height="wrap_content"
    style="@style/MyCheckBox"
    />

现在的用户对APP的外观看得很重要,如果APP内所有元件都用Android默认样式写,估计下面评论里就有一堆在骂UI丑的。今天学习自定义Button按钮样式。Button样式修改的是Button的背景(Background)属性。 首先写一个定义Button样式的XML文件: 新建Android XML文件,类型选Drawable,根结点选selector,文件名就buton_style吧。 程序自动给我们刚刚建的文件里加了selector结点,我们只需要在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/play_press" />
    <item android:state_focused="true" android:drawable="@drawable/play_press" />
    <item android:drawable="@drawable/play" />
</selector>

我这里获取焦点跟点击时显示的是同一张图片,必须严格照上面的顺序写,不可倒。 接下来只要在布局时写Button控件时应用到Button的Background属性即可。

<Button android:id="@+id/button1"
    android:layout_width="wrap_content" android:layout_height="wrap_content"
    android:background="@drawable/button_style"
></Button>

最终效果图: 点击时会变。 源代码下载: [download id=”19”] 再加上一种自定义样式方法,上面的是用图片,其实我们可以直接通过定义xml文件来实现不同的样式: 在上面的源代码基础上,只需要修改button_style文件,同样三种状态分开定义:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape>
            <gradient android:startColor="#0d76e1" android:endColor="#0d76e1"
                android:angle="270" />
            <stroke android:width="1dip" android:color="#f403c9" />
            <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="1dip" android:color="#f403c9" />
            <corners android:radius="2dp" />
            <padding android:left="10dp" android:top="10dp"
                android:right="10dp" android:bottom="10dp" />
        </shape>
    </item>

    <item>
        <shape>
            <gradient android:startColor="#000000" android:endColor="#ffffff"
                android:angle="180" />
            <stroke android:width="1dip" android:color="#f403c9" />
            <corners android:radius="5dip" />
            <padding android:left="10dp" android:top="10dp"
                android:right="10dp" android:bottom="10dp" />
        </shape>
    </item>
</selector>

gradient 主体渐变 startColor开始颜色,endColor结束颜色 ,angle开始渐变的角度(值只能为90的倍数,0时为左到右渐变,90时为下到上渐变,依次逆时针类推) stroke 边框 width 边框宽度,color 边框颜色 corners 圆角 radius 半径,0为直角 padding text值的相对位置

在Android里,调用系统功能一般都是通过设置Intent的Action实现的。

Intent intent=new Intent("android.intent.action.CALL_BUTTON");
startActivity(intent);

Android开发判断WIFI状态方法

WifiManager wm=(WifiManager)this.getSystemService(Context.WIFI_SERVICE);
        //得到WifiManager实例
        switch(wm.getWifiState()){
        //switch判断状态
        case WifiManager.WIFI_STATE_DISABLED:
            statetv.setText("WIFI已关闭");
            break;
        case WifiManager.WIFI_STATE_DISABLING:
            statetv.setText("WIFI正在关闭");
            break;
        case WifiManager.WIFI_STATE_ENABLED:
            statetv.setText("WIFI已打开");
            break;
        case WifiManager.WIFI_STATE_ENABLING:
            statetv.setText("WIFI正在打开");
            break;
        case WifiManager.WIFI_STATE_UNKNOWN:
            statetv.setText("WIFI状态未知");
            break;
        }

statetv是一个TextView

首先,我们先要知道该应用的包名。 原理:通过PackageManager 获取需要检测的包信息,如果不存在(就是没安装),就会抛出NameNotFoundException 异常 下面是代码:

    public static boolean appIsInstalled(Context context,String pageName){
        try {
            PackageInfo packinfo = context.getPackageManager().getPackageInfo(pageName,0);
            return true;
        } catch (NameNotFoundException e) {
            // TODO Auto-generated catch block
            return false;
        }
    }

写成静态方法了,只需要传入Context和需要检测的包名即可。

2011.10.17加注:Item包含HorizontalScrollView 同样会导致无法点击无法,且无法通过requestFocusFromTouch()解决 我的ListView每个Item都有一个ImageView,两个TextView,当添加Item后,执行listAdapter.notifyDataSetChanged();更新视图,发现ListView的Item不能再点击了,但是还是可以滑动,切换到其他Activity后返回又可以点击,貌似是更新后失去了焦点。于是在执行listAdapter.notifyDataSetChanged()后,试着加上listview.requestFocusFromTouch(),问题解决。

前面说到PendingIntent传送数据丢失解决办法,但是如果主屏幕上有多个Widget,而PendingIntent在不同的Widget有不同的Bundle参数时,你会发现,不管在哪个Widget上点击,启动的Activity或者Service接收到的参数都是最后一个Widget的,后面在添加PendingIntent时,把前面的PendingIntent也替换了。 其实解决方法很简单,还是如前文一样,修改getActivity方法的参数,不过这次改的是第二个参数,

PendingIntent pendingIntent=PendingIntent.getActivity(context,0, intent,PendingIntent.FLAG_UPDATE_CURRENT);

如上面的代码,第二个参数是固定的0,Android开发文档里称为request Code,英文原文为”Private request code for the sender”,直译为发送器的私有请求代码。其实这个int值就相当于PendingIntent的一个ID,PendingIntent会根据这个ID来查看是否已存在该PendingIntent,然后根据第四个参数来作相应的操作,关于第四个参数的含义,请参考PendingIntent传送数据丢失解决办法一文。 如果在生成PendingIntent时,第二个参数相同,那么就相当于在原来的PendingIntent上修改,我们看到的当然是最后一次修改的结果。所以解决方法就是把第二个参数设为一个动态的值,这里最好的办法就是设为appWidgetId,每个Widget都有一个唯一的ID,不会重复。 发现一个奇怪的问题,在我自己的程序中,是用一个for循环来循环绑定PendingIntent的,同时循环里还有一个线程来处理耗时操作。按上面的修改,我发现如果把绑定PendingIntent的代码放在循环体内,Thread外,上面的修改无效,但是如果放在Thread内,就有效了,暂时不知道原因,如有知道的同学希望留言说一声。

前面已经说过,在Android1.5以上的版本,AppWidget的更新时间是强制限定在30分钟的。那么,当在主屏幕添加多个相同的AppWidget时,又是怎么更新的呢? 经真机测试,当添加AppWidget时,传给onUpdate的参数int[] appWidgetIds,长度始终为1,内容就是刚刚添加的AppWidget的ID,当桌面上有多个相同的AppWidget时,所有Widget的更新时间以第一个为准。就是说当第一个Widget间隔30分钟开始更新了,其他的也跟着更新,这时,传给onUpdate的参数int[] appWidgetIds,长度就是桌面上AppWidget的数量,值就是Widget的ID