标签归档:代码示范

Android中的Selector的用法

Android中的Selector主要是用来改变ListView和Button控件的默认背景。其使用方法可以按一下步骤来设计:(以在mylist_view.xml为例)

  1. 创建mylist_view.xml文件

首先在res目录下新建drawable文件夹,再在新建的drawable文件夹中新建mylist_view.xml,其目录结构为:res/drawable/mylist_view.xml。

2.根据具体需求编辑mylist_view.xml文件
新建mylist_view.xml文件后,在没有添加任何属性时其内部代码结构为:

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

下面就可以根据项目需求,在其内部定义为自己想要的样式了,主要属性如下:

<?xml version="1.0" encoding="utf-8" ?>     
<selector xmlns:android="http://schemas.android.com/apk/res/android">   
<!-- 默认时的背景图片-->    
  <item android:drawable="@drawable/pic1" />      
<!-- 没有焦点时的背景图片 -->    
  <item android:state_window_focused="false"     
        android:drawable="@drawable/pic1" />     
<!-- 非触摸模式下获得焦点并单击时的背景图片 -->    
  <item android:state_focused="true" android:state_pressed="true"   android:drawable= "@drawable/pic2" />   
<!-- 触摸模式下单击时的背景图片-->    
<item android:state_focused="false" android:state_pressed="true"   android:drawable="@drawable/pic3" />    
<!--选中时的图片背景-->    
  <item android:state_selected="true"   android:drawable="@drawable/pic4" />     
<!--获得焦点时的图片背景-->    
  <item android:state_focused="true"   android:drawable="@drawable/pic5" />     
</selector>  

3.引用mylist_view.xml文件
三种方法可以来引用刚才创建的文件:
1.在ListView中添加如下属性代码

android:listSelector="@drawable/mylist_view"  

2.在ListView的item界面中添加如下属性代码

android:background="@drawable/mylist_view"  

3.利用JAVA代码直接编写

Drawable drawable =     getResources().getDrawable(R.drawable.mylist_view);   
listView.setSelector(drawable);  

为了防止列表拉黑的情况发生,需要在ListView中添加以下的属性代码

android:cacheColorHint="@android:color/transparent"  

属性介绍:

  • android:state_selected选中
  • android:state_focused获得焦点
  • android:state_pressed点击
  • android:state_enabled设置是否响应事件,指所有事件

Android开发示例:如何设置圆角的EditText

设置EditText边框为圆角如下图所示:

首先定义一个圆角xml,路径:res/drawable/rounded_edittext.xml

  1. <?xml version=“1.0” encoding=“utf-8”?>
  2. <shape xmlns:Android=“http://schemas.android.com/apk/res/android”
  3.     android:shape=“rectangle” android:padding=“10dp”>
  4.     <solid android:color=“#FFFFFF” />
  5.     <corners android:bottomRightRadius=“15dp”
  6.         android:bottomLeftRadius=“15dp” android:topLeftRadius=“15dp”
  7.         android:topRightRadius=“15dp” />
  8. </shape>

显示控件的xml中

  1. <EditText android:id=“@+id/edt_operator_name” style=“@style/syncEditText”
  2.                     android:hint=“@string/hint_operator_name”
  3. android:background=“@drawable/rounded_edittext”
  4. android:layout_width=“250dip”
  5. android:layout_height=“wrap_content”
  6. android:paddingTop=“10dip”
  7. android:paddingBottom=“10dip”
  8. android:gravity=“center_vertical” />

其中关键的就是设置编辑文本控件的background属性为刚定义的圆角xml。

即:

  1. android:background=“@drawable/rounded_edittext”

 

android软键盘弹出引起的各种不适终极解决方案

很多写登录界面的开发者都会遇到一个问题:那就是在登录界面时,当你点击输入框时,下边的按钮有时会被输入框挡住,这个不利于用户的体验,所以很多人希望软键盘弹出时,也能把按钮挤上去。很多开发者想要监听键盘的状态,这无疑是一个很麻烦的做法。
我们可以在AndroidManifest.xml的Activity设置属性:

xml
android:windowSoftInputMode = "adjustResize"

软键盘弹出时,要对主窗口布局重新进行布局,并调用onSizeChanged方法,切记一点当我们设置为“adjustResize”时,我们的界面不要设置为全屏模式,否则设置了这个属性也不会有什么效果。而当我们设置
xml
android: windowSoftInputMode = "adjustPan"

时,主窗口就不会调用onSizeChanged方法,界面的一部分就会被软键盘覆盖住,就不会被挤到软键盘之上了。

我们通过一段代码来测试一下,当我们设置了该属性后,弹出输入法时,系统做了什么.
重写Layout布局:

    public class ResizeLayout extends LinearLayout{ 
        private static int count = 0; 
         
        public ResizeLayout(Context context, AttributeSet attrs)            { 
            super(context, attrs); 
        } 
         
        @Override 
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {     
            super.onSizeChanged(w, h, oldw, oldh);          
            Log.e("onSizeChanged " + count++, "=>onResize called! w="+w + ",h="+h+",oldw="+oldw+",oldh="+oldh); 
       } 
         
        @Override 
        protected void onLayout(boolean changed, int l, int t, int r, int b) { 
            super.onLayout(changed, l, t, r, b); 
            Log.e("onLayout " + count++, "=>OnLayout called! l=" + l + ", t=" + t + ",r=" + r + ",b="+b); 
        } 
         
        @Override 
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);       
            Log.e("onMeasure " + count++, "=>onMeasure called! widthMeasureSpec=" + widthMeasureSpec + ", heightMeasureSpec=" + heightMeasureSpec); 
        } 

我们的布局设置为:

    <com.winuxxan.inputMethodTest.ResizeLayout  
        xmlns:android="http://schemas.android.com/apk/res/android" 
        android:id="@+id/root_layout" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        android:orientation="vertical" 
        > 
         
        <EditText 
            android:layout_width="fill_parent"  
            android:layout_height="wrap_content"  
        /> 
       
        <LinearLayout 
                android:id="@+id/bottom_layout" 
                android:layout_width="fill_parent"  
                android:layout_height="fill_parent"  
                android:orientation="vertical" 
                android:gravity="bottom">s 
        
        <TextView   
            android:layout_width="fill_parent"  
            android:layout_height="wrap_content"  
            android:text="@string/hello" 
            android:background="#77777777" 
          /> 
       </LinearLayout> 
    </com.winuxxan.inputMethodTest.ResizeLayout> 

AndroidManifest.xml的Activity设置属性:

android:windowSoftInputMode = "adjustResize"

运行程序,点击文本框,查看调试信息:

E/onMeasure 6(7960): =>onMeasure called! widthMeasureSpec=1073742144, heightMeasureSpec = 1073742024

E/onMeasure 7(7960): =>onMeasure called! widthMeasureSpec=1073742144, heightMeasureSpec = 1073742025

E/onSizeChanged 8(7960): =>onSizeChanged called! w=320,h=201,oldw=320,oldh=377

E/onLayout 9(7960): =>OnLayout called! l=0, t=0,r=320,b=201

从调试结果我们可以看出,当我们点击文本框后,根布局调用了onMeasure,onSizeChanged和onLayout。

windowSoftInputMode的值如果设置为adjustPan,那么该Activity主窗口并不调整屏幕的大小以便留出软键盘的空间。相反,当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分。这个通常是不期望比调整大小,因为用户可能关闭软键盘以便获得与被覆盖内容的交互操作。
上面的例子中,我们将AndroidManifest.xml的属性进行更改:

xml
android: windowSoftInputMode = "adjustPan"

重新运行,并点击文本框,查看调试信息:
E/onMeasure 6(8378): =>onMeasure called! widthMeasureSpec=1073742144, heightMeasureSpec=1073742200
E/onMeasure 7(8378): =>onMeasure called! widthMeasureSpec=1073742144, heightMeasureSpec=1073742201
E/onLayout 8(8378): =>OnLayout called! l=0, t=0,r=320,b=377
我们看到:系统也重新进行了measrue和layout,但是我们发现,layout过程中onSizeChanged并没有调用,这说明输入法弹出前后并没有改变原有布局的大小。

当然还有其他属性可以设置:

  • stateUnspecified 软键盘的状态(是否它是隐藏或可见)没有被指定。系统将选择一个合适的状态或依赖于主题的设置。 这个是为了软件盘行为默认的设置。
  • stateUnchanged 软键盘被保持无论它上次是什么状态,是否可见或隐藏,当主窗口出现在前面时。
  • stateHidden 当用户选择该Activity时,软键盘被隐藏——也就是,当用户确定导航到该Activity时,而不是返回到它由于离开另一个Activity。
  • stateAlwaysHidden 软键盘总是被隐藏的,当该Activity主窗口获取焦点时。
  • stateVisible 软键盘是可见的,当那个是正常合适的时(当用户导航到Activity主窗口时)。
  • stateAlwaysVisible 当用户选择这个Activity时,软键盘是可见的——也就是,也就是,当用户确定导航到该Activity时,而不是返回到它由于离开另一个Activity。
  • adjustUnspecifie 它不被指定是否该Activity主窗口调整大小以便留出软键盘的空间,或是否窗口上的内容得到屏幕上当前的焦点是可见的。系统将自动选择这些模式中一种主要依赖于是否窗口的内容有任何布局视图能够滚动他们的内容。如果有这样的一个视图,这个窗口将调整大小,这样的假设可以使滚动窗口的内容在一个较小的区域中可见的。这个是主窗口默认的行为设置。
  • adjustResize 该Activity主窗口总是被调整屏幕的大小以便留出软键盘的空间
  • adjustPan 该Activity主窗口并不调整屏幕的大小以便留出软键盘的空间。相反,当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分。这个通常是不期望比调整大小,因为用户可能关闭软键盘以便获得与被覆盖内容的交互操作。

 

Android API之CheckedTextView demo(单选,多选)

类CheckedTextView继承超类TextView并实现Checkable接口。当ListView的setChoiceMode方法并设定为CHOICE_MODE_SINGLE或者CHOICE_MODE_MULTIPLE,而非CHOICE_MODE_NONE时,使用此类是很有用的。

使用范例:

  1. /res/layout/main.xml中添加相应资源ID
<ListView
    android:id="@+id/listView"  
    android:layout_width="fill_parent"  
    android:layout_height="wrap_content" 
/>
<CheckedTextView 
    android:id="@+id/checkedTextView1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:checkMark="?android:attr/listChoiceIndicatorMultiple"
    android:text="@string/checkedTextView1"
/>
<CheckedTextView  
    android:id="@+id/checkedTextView2"  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:checkMark="?android:attr/listChoiceIndicatorMultiple" 
    android:text="@string/checkedTextView2" 
/>
<CheckedTextView 
    android:id="@+id/checkedTextView3"  
    android:layout_width="fill_parent"  
    android:layout_height="wrap_content"  
    android:checkMark="?android:attr/listChoiceIndicatorMultiple"
    android:text="@string/checkedTextView3"  
/>

   
<CheckedTextView  
    android:id="@+id/checkedTextView4"  
    android:layout_width="fill_parent"  
    android:layout_height="wrap_content"  
    android:checkMark="?android:attr/listChoiceIndicatorMultiple"  
    android:text="@string/checkedTextView4"
/>
  1. /res/values/strings.xml 资源
<string name="hello">TextView多选框</string>   
<string name="app_name">CheckedTextView</string>   
<string name="checkedTextView1">TextView多选框1</string>   
<string name="checkedTextView2">TextView多选框2</string>  
<string name="checkedTextView3">TextView多选框3</string>  
<string name="checkedTextView4">TextView多选框4</string>
  1. 源代码中使用
listView=(ListView)findViewById(R.id.listView);     
checkedTextView1=(CheckedTextView)findViewById(R.id.checkedTextView1);      
checkedTextView2=(CheckedTextView)findViewById(R.id.checkedTextView2);     
checkedTextView3=(CheckedTextView)findViewById(R.id.checkedTextView3);    
checkedTextView4=(CheckedTextView)findViewById(R.id.checkedTextView4);
      
//设置checkedTextView1为选中状态      
checkedTextView1.setChecked(true);            
//设置checkedTextView2的页边距,即距上/下/左/右各20像素,默认为未选中状态     
checkedTextView2.setPadding(20, 20, 20, 20);     
//设置checkedTextView3为选中状态,并更改其显示图标,使用android系统资源arrow_down_float   
checkedTextView3.setChecked(true);      
checkedTextView3.setCheckMarkDrawable(android.R.drawable.arrow_down_float);     
//设置checkedTextView4反转状态,由默认的未选中反转为选中状态       
checkedTextView4.toggle();
//点击状态后变更相反,如选中变为未选中,未选中的变为选中
checkedTextView1.setOnClickListener(new View.OnClickListener()
{                           
                          
    @Override                           
    public void onClick(View v) {                           
    // TODO Auto-generated method stub                                   
     checkedTextView1.toggle();                        
}
});       

//点击状态后变更相反,如选中变为未选中,未选中的变为选中
checkedTextView2.setOnClickListener(new View.OnClickListener()
{                           
                          
    @Override                           
    public void onClick(View v) {                           
    // TODO Auto-generated method stub                                   
     checkedTextView2.toggle();                        
}
});        


 

 //点击状态后变更相反,即下三角转化为上三角符号
checkedTextView3.setOnClickListener(new View.OnClickListener()
{                  
    @Override                 
    public void onClick(View v) {                           
    // TODO Auto-generated method stub  
checkedTextView3.setCheckMarkDrawable(android.R.drawable.arrow_up_float);               
    }

});

 //点击状态后变更相反,如选中变为未选中,未选中的变为选中
checkedTextView4.setOnClickListener(new View.OnClickListener()
{                           
                          
    @Override                           
    public void onClick(View v) {                           
    // TODO Auto-generated method stub                                   
     checkedTextView4.toggle();                        
}
});        

       
//设置listView的模式为CHOICE_MODE_SINGLE   
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

转 Android动态显示隐藏密码输入框的内容(实用)

通过设置EditText的setTransformationMethod()方法来实现隐藏密码或这显示密码,示例如下:

  1. private Button mBtnPassword;  
  2. private EditText mEtPassword;  
  3. private boolean mbDisplayFlg = false;  
  4.   
  5.    /** Called when the activity is first created. */  
  6.    @Override  
  7.    public void onCreate(Bundle savedInstanceState) {  
  8.        super.onCreate(savedInstanceState);  
  9.        setContentView(R.layout.main);  
  10.          
  11.        mEtPassword = (EditText)findViewById(R.id.password);  
  12.        mBtnPassword = (Button)findViewById(R.id.btnPassword);  
  13.        mBtnPassword.setOnClickListener(new OnClickListener() {  
  14.   
  15.         @Override  
  16.         public void onClick(View v) {  
  17.             // TODO Auto-generated method stub  
  18.             Log.d(“AndroidTest”“mbDisplayFlg = “ + mbDisplayFlg);  
  19.             if (!mbDisplayFlg) {  
  20.                 // display password text, for example “123456”  
  21.                 mEtPassword.setTransformationMethod(HideReturnsTransformationMethod.getInstance());  
  22.             } else {  
  23.                 // hide password, display “.”  
  24.                 mEtPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());  
  25.             }  
  26.             mbDisplayFlg = !mbDisplayFlg;  
  27.             mEtPassword.postInvalidate();  
  28.         }  
  29.           
  30.        });  
  31.         
  32.    }  

 

 

main.xml

  1. <?xml version=“1.0” encoding=“utf-8”?>  
  2. <LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”  
  3.     android:orientation=“vertical” android:layout_width=“fill_parent”  
  4.     android:layout_height=“fill_parent”>  
  5.     <Button android:id=“@+id/btnPassword”  
  6.         android:layout_width=“wrap_content”  
  7.         android:layout_height=“wrap_content”  
  8.         android:text=“密码” />  
  9.     <EditText android:id=“@+id/password”  
  10.         android:layout_width=“fill_parent”  
  11.         android:layout_height=“wrap_content”  
  12.         android:password=“true”  
  13.         android:textSize=“18sp”  
  14.         android:text=“123456”>  
  15.     </EditText>  
  16. </LinearLayout>  

 

Android自定义Dialog

这段时间在做一个项目,需要使用到自定义Dialog,先在网上找了一下资料,发现还是有很多没有讲清楚的,在此给出一个Demo,一来可以方便广大码农,二来也可以方便自己,以备不时之需。。。

先来一张图吧,很简单,只有一个Activity,当点击Button的时候就弹出这个自定义的Dialog

里面的几张图都比较丑,我不多会美工,随便用powerpoint画了几张图,原理是一样的,先不计较这些。下面正入正题

为了照顾到所有的码农,在些把所有的代码都贴出来

新建工程在此就不贴出来了,只是为了方便大家的复制粘贴,取包名为com.and.mydialog,主Activity取名为MyDialogActivity

package com.and.mydialog;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MyDialogActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Button button = (Button) findViewById(R.id.button1);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                
                //初始化一个自定义的Dialog
                Dialog dialog = new MyDialog(MyDialogActivity.this,
                        R.style.MyDialog);

                dialog.show();
            }
        });

    }
}

主布局文件main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <Button 
        android:text="显示自定义Dialog" 
        android:id="@+id/button1"
        android:layout_height="wrap_content" 
        android:layout_width="fill_parent"/>
</LinearLayout>

新建一个自定义的Dialog类,取名MyDialog,继承自Dialog

package com.and.mydialog;

import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;

public class MyDialog extends Dialog {

    Context context;
    public MyDialog(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        this.context = context;
    }
    public MyDialog(Context context, int theme){
        super(context, theme);
        this.context = context;
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.dialog);
    }

}

相应的布局文件dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_vertical|center_horizontal"
    android:background="@drawable/dialog_bg">
    <RelativeLayout 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="30dip"
        android:paddingTop="10dip">
        <ImageView 
            android:id="@+id/dialog_title_image"
            android:layout_alignParentLeft="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/dialog_title_image"/>
        <TextView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dip"
            android:layout_centerInParent="true"
            android:text="Title"
            android:layout_toRightOf="@id/dialog_title_image"
            android:textColor="#000000"
            android:textSize="30sp"/>
        
    </RelativeLayout>
    <TextView 
            android:layout_width="fill_parent"
            android:layout_height="1dip"
            android:background="@drawable/lins"
            android:layout_marginTop="5dip"/>
    <TextView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="This is a custom dialog"
        android:textColor="#000000"
        android:layout_marginTop="10dip"
        android:layout_marginLeft="30dip"/>
    <RelativeLayout 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingTop="10dip"
        android:gravity="bottom|center_horizontal"
        android:paddingBottom="10dip">
        <Button 
            android:id="@+id/dialog_button_cancel"
            android:layout_alignParentLeft="true"
            android:layout_width="100dip"
            android:layout_height="wrap_content"
            android:text="确定"/>
        <Button 
            android:id="@+id/dialog_button_ok"
            android:layout_width="100dip"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@id/dialog_button_cancel"
            android:layout_marginLeft="35dip"
            android:text="取消"/>
    </RelativeLayout>
</LinearLayout>

最主要的,是自定义的Style,我们自定义一个式样,用来改变默认的Dialog样式

在values文件夹下新建一个styles.xml文件,如下。。。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="MyDialog" parent="@android:Theme.Dialog">
        <item name="android:windowFrame">@null</item>
        <item name="android:windowNoTitle">true</item> 
        <item name="android:windowBackground">@drawable/dialog_bg</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:windowContentOverlay">@null</item>
    </style>
</resources>

这样应该就OK了,为了方便大家测试本示例,在此一并附上不怎么好看的素材。。。

注意,这里有三张图片,第三张图片是一条线,在自定义的式样的时候取消了标题栏,为了美观,添加此线条,看上去还是有标题栏的感觉。。。在此基本上完成了。

由于水平有限,这些内容基本上都是在网上找的,然后自己整理了一下,写了一篇相对比较清晰的,如果大家还有什么疑问的话,随时可以跟我联系,共同学习。。。

———————————————————————————忧伤的分割线——————————————————————————

不好意思,刚刚实测了一下,发现还有一个很简单的方法,在不改变前面的布局前提下,只需要修改主类(MyDialogActivity.java)

package com.and.mydialog;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MyDialogActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Button button = (Button) findViewById(R.id.button1);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

//                Dialog dialog = new MyDialog(MyDialogActivity.this,
//                        R.style.MyDialog);
                //此处直接new一个Dialog对象出来,在实例化的时候传入主题
                Dialog dialog = new Dialog(MyDialogActivity.this, R.style.MyDialog);
 //设置它的ContentView
                dialog.setContentView(R.layout.dialog);

                dialog.show();
            }
        });

    }
}

Android自定义Switch控件代码示例

 

Switch是Android的一个开关控件,相当于IPhone的UISwitch效果,但是该控件是4.0以后才有得,故而有些项目需要的时候不得不自己去实现该控件功能,网上主要流行的方法是继承View等控件自己在onDraw()里面绘制控件,但是不是效果不太理想就是体验性太差,另外也有修改官方Switch控件的,综合网上资料,觉得修改官方Switch控件比较靠谱,比较体验性方面性能方面都有保证,API接口大都是一致的,本人选择这种方式。

 

修改Switch的主要思想是:

1. Switch中含有高版本SDK代码,需要去掉或者改写这样的代码

2. Switch对应declare-styleable属性声明应该在Android SDK安装目录中找到对应的源码声明片段,基本上copy过来就行了。所在路径:Androidandroid-sdkplatformsandroid-17datares

 

修改后的MySwitch控件接口基本与原Switch控件一致,并且除了可支持所有SDK外,增加了2项小功能:

1. 支持用Track背景图片的方式代替Texton Textoff等文字方式表现开关状态

2.支持调整控制Switch的高度

 

下面贴出Switch修改的关键代码:

 

 

/** 
 * <p>  
 * modified from android SDK 14(4.0) android.widget.Switch. 
 * <br/> 
 * <strong>new feature: </strong> 
 * <ol> 
 * <li>support SDK 1 or higher. </li> 
 * <li>you can use track drawable instead of text to display the changes of off-on state!</li> 
 * <li>you can control the Switch minimum height. </li> 
 * </ol> 
 * </p> 
 *   
 *  @see {@link Switch} 
 *  @author Wison 
 */  
public class MySwitch extends CompoundButton {  
    // Support track drawable instead of text  
    private Drawable mTrackOnDrawable;  
    private Drawable mTrackOffDrawable;  
      
    // Support minimum height  
    private int mSwitchMinHeight;  
  
    /** 
     * Construct a new Switch with a default style determined by the given theme attribute, 
     * overriding specific style attributes as requested. 
     * 
     * @param context The Context that will determine this widget's theming. 
     * @param attrs Specification of attributes that should deviate from the default styling. 
     * @param defStyle An attribute ID within the active theme containing a reference to the 
     *                 default style for this widget. e.g. android.R.attr.switchStyle. 
     */  
    public MySwitch(Context context, AttributeSet attrs, int defStyle) {  
        super(context, attrs, defStyle);  
  
        mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);  
        Resources res = getResources();  
        mTextPaint.density = res.getDisplayMetrics().density;  
        //float scaledDensity = res.getDisplayMetrics().scaledDensity;  
        //mTextPaint.setCompatibilityScaling(res.getCompatibilityInfo().applicationScale);  
  
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Switch, defStyle, 0);  
  
        // off-on 模式: 图片模式或文字模式,图片模式是用Track背景图片表示off-on的状态,文字模式是用文字来表示off-on状态。  
        mTrackOnDrawable = a.getDrawable(R.styleable.Switch_trackOn);  
        mTrackOffDrawable = a.getDrawable(R.styleable.Switch_trackOff);  
        if (checkTrackOffOnDrawable()) {  
            // 如果设定图片模式,则默认显示off状态  
            mTrackDrawable = mTrackOffDrawable;  
        } else {  
            mTrackDrawable = a.getDrawable(R.styleable.Switch_track);  
        }  
          
        mThumbDrawable = a.getDrawable(R.styleable.Switch_thumb);  
        mTextOn = a.getText(R.styleable.Switch_textOn);  
        mTextOff = a.getText(R.styleable.Switch_textOff);  
        mThumbTextPadding = a.getDimensionPixelSize(R.styleable.Switch_thumbTextPadding, 0);  
        mSwitchMinWidth = a.getDimensionPixelSize(R.styleable.Switch_switchMinWidth, 0);  
          
        mSwitchMinHeight = a.getDimensionPixelSize(R.styleable.Switch_switchMinHeight, 0);  
          
        mSwitchPadding = a.getDimensionPixelSize(R.styleable.Switch_switchPadding, 0);  
  
        int appearance = a.getResourceId(R.styleable.Switch_switchTextAppearance, 0);  
        if (appearance != 0) {  
            setSwitchTextAppearance(context, appearance);  
        }  
        a.recycle();  
  
        ViewConfiguration config = ViewConfiguration.get(context);  
        mTouchSlop = config.getScaledTouchSlop();  
        mMinFlingVelocity = config.getScaledMinimumFlingVelocity();  
  
        // Refresh display with current params  
        refreshDrawableState();  
        setChecked(isChecked());  
    }  
  
    private boolean checkTrackOffOnDrawable() {  
        return mTrackOnDrawable != null && mTrackOffDrawable != null;  
    }  
  
    @SuppressLint("NewApi")  
    @Override  
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
        if (mOnLayout == null) {  
            mOnLayout = makeLayout(mTextOn);  
        }  
        if (mOffLayout == null) {  
            mOffLayout = makeLayout(mTextOff);  
        }  
        mTrackDrawable.getPadding(mTempRect);  
        final int maxTextWidth = Math.max(mOnLayout.getWidth(), mOffLayout.getWidth());  
        final int switchWidth = Math.max(mSwitchMinWidth,  
                maxTextWidth * 2 + mThumbTextPadding * 4 + mTempRect.left + mTempRect.right);  
          
//        final int switchHeight = mTrackDrawable.getIntrinsicHeight();  
        int switchHeight;  
        if (mSwitchMinHeight <= 0) {  
            switchHeight = mTrackDrawable.getIntrinsicHeight();  
        } else {  
            switchHeight = Math.max(mSwitchMinHeight, mTempRect.top + mTempRect.bottom);  
        }  
          
        mThumbWidth = maxTextWidth + mThumbTextPadding * 2;  
  
        mSwitchWidth = switchWidth;  
        mSwitchHeight = switchHeight;  
  
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
        final int measuredHeight = getMeasuredHeight();  
        if (measuredHeight < switchHeight) {  
            if (Build.VERSION.SDK_INT >= 11) {  
                setMeasuredDimension(getMeasuredWidthAndState(), switchHeight);  
            } else {  
                setMeasuredDimension(getMeasuredWidth(), switchHeight);  
            }  
        }  
    }  
  
    @Override  
    public void setChecked(boolean checked) {  
        if (checkTrackOffOnDrawable()) {  
            mTrackDrawable = checked ? mTrackOnDrawable : mTrackOffDrawable;  
            refreshDrawableState();  
        }  
        super.setChecked(checked);  
        mThumbPosition = checked ? getThumbScrollRange() : 0;  
        invalidate();  
    }  
  
    @Override  
    protected void onDraw(Canvas canvas) {  
        super.onDraw(canvas);  
        // Draw the switch  
        int switchLeft = mSwitchLeft;  
        int switchTop = mSwitchTop;  
        int switchRight = mSwitchRight;  
        int switchBottom = mSwitchBottom;  
          
        if (checkTrackOffOnDrawable()) {  
            mTrackDrawable = getTargetCheckedState() ? mTrackOnDrawable : mTrackOffDrawable;  
            refreshDrawableState();  
        }  
          
        mTrackDrawable.setBounds(switchLeft, switchTop, switchRight, switchBottom);  
        mTrackDrawable.draw(canvas);  
  
        canvas.save();  
          
        mTrackDrawable.getPadding(mTempRect);  
        int switchInnerLeft = switchLeft + mTempRect.left;  
        int switchInnerTop = switchTop + mTempRect.top;  
        int switchInnerRight = switchRight - mTempRect.right;  
        int switchInnerBottom = switchBottom - mTempRect.bottom;  
        canvas.clipRect(switchInnerLeft, switchTop, switchInnerRight, switchBottom);  
  
        mThumbDrawable.getPadding(mTempRect);  
        final int thumbPos = (int) (mThumbPosition + 0.5f);  
        int thumbLeft = switchInnerLeft - mTempRect.left + thumbPos;  
        int thumbRight = switchInnerLeft + thumbPos + mThumbWidth + mTempRect.right;  
  
        mThumbDrawable.setBounds(thumbLeft, switchTop, thumbRight, switchBottom);  
        mThumbDrawable.draw(canvas);  
  
        // mTextColors should not be null, but just in case  
        if (mTextColors != null) {  
            mTextPaint.setColor(mTextColors.getColorForState(getDrawableState(),  
                    mTextColors.getDefaultColor()));  
        }  
        mTextPaint.drawableState = getDrawableState();  
  
        Layout switchText = getTargetCheckedState() ? mOnLayout : mOffLayout;  
  
        if (switchText != null) {  
            canvas.translate((thumbLeft + thumbRight) / 2 - switchText.getWidth() / 2,  
                    (switchInnerTop + switchInnerBottom) / 2 - switchText.getHeight() / 2);  
            switchText.draw(canvas);  
        }  
        canvas.restore();  
    }  
}  

 

 

下面是关键属性声明:

<declare-styleable name="Switch">  
      
    <!-- Drawable to use when the switch is in the checked/"on" state. -->  
    <attr name="trackOn" format="reference" />  
    <!-- Drawable to use when the switch is in the unchecked/"off" state. -->  
    <attr name="trackOff" format="reference" />  
    <!-- Minimum height for the switch component -->  
    <attr name="switchMinHeight" format="dimension" />  
      
    <!-- Drawable to use as the "thumb" that switches back and forth. -->  
    <attr name="thumb" format="reference" />  
    <!-- Drawable to use as the "track" that the switch thumb slides within. -->  
    <attr name="track" format="reference" />  
    <!-- Text to use when the switch is in the checked/"on" state. -->  
    <attr name="textOn" format="string" />  
    <!-- Text to use when the switch is in the unchecked/"off" state. -->  
    <attr name="textOff" format="string" />  
    <!-- Amount of padding on either side of text within the switch thumb. -->  
    <attr name="thumbTextPadding" format="dimension" />  
    <!-- TextAppearance style for text displayed on the switch thumb. -->  
    <attr name="switchTextAppearance" format="reference" />  
    <!-- Minimum width for the switch component -->  
    <attr name="switchMinWidth" format="dimension" />  
    <!-- Minimum space between the switch and caption text -->  
    <attr name="switchPadding" format="dimension" />  
</declare-styleable>  

以下是效果图:

 

Android中全屏或者取消标题栏的三种方法

先介绍去掉标题栏的方法:

第一种:也一般入门的时候经常使用的一种方法

requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏

注意这句一定要写在setContentView()方法的前面,不然会报错的

第二种:在AndroidManifest.xml文件中定义

<application android:icon=@drawable/icon
android:label
=@string/app_name
android:theme
=”@android:style/Theme.NoTitleBar”>

可以看出,这样写的话,整个应用都会去掉标题栏,如果只想去掉某一个Activity的标题栏的话,可以把这个属性加到activity标签里面

第三种:这种在一般的应用中不常用,就是在res/values目录下面新建一个style.xml的文件

例如:

<?xml version=”1.0″ encoding=”UTF-8″ ?>
<resources>
<style name=”notitle>
<item name=”android:windowNoTitle”>true</item>
</style> 
</resources>

这样,我们就自定义了一个style,就相当于一个主题,然后在AndroidManifest.xml文件中定义

<application android:icon=”@drawable/icon”
android:label
=”@string/app_name”
android:theme
=”@style/notitle>

这样也可以达到去掉标题栏的效果

三种去掉标题栏方法的总结

第一种,有的时候我们会看到,会先出现标题栏,然后再消失,因为我们只是在activity的oncreate方法中定义的,第二种相对第一种比较好一些,不会出现这种情况,第三种我个人感觉最好,这样把功能分开,便于维护和扩展

再介绍全屏的方法:

第一种

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

第二种

android:theme=”@android:style/Theme.NoTitleBar.Fullscreen”

第三种

application android:icon=”@drawable/icon”
android:label
=”@string/app_name”
android:theme
=”@style/fullscreem”

大家自己总结一下吧,个人感觉第三种比较好,看自己的喜欢用吧

android BottomTabBar 代码示例


 1 在Android app开发过程中,会发现很多App的底部(顶部一样) 会仿效IPHONE的设计。。做一个导航。  如下图黑色部分:


(这个是实现效果)                                                                 这个是设计原型

 

1.1 要是中间部分没有那个拱起来的部分,那么可能设计还简单一些。。 仔细分析下设计原型,,,中间那个 摇摇 的图标要大一些,而且和其他图标没在一个水平线上。

 

1.2  总的思想就是 先封装一个 没有 凸起 的通用,自动适配的组。。。然后。。。在上面 通过 FrameLayout 放置一个 突起的组建。。。

 

1.3 设计细节

1.3.1  自己写一个  BottomTabBar   (extends) LinearLayout .  通过 Inflater 加载一个 自定义的 View (通过xml配置), 在View 的xml 中,注意书写好适配就OK了。

注意 layout_weight 的使用。(参见上一篇 listview)

 

 

自定义LinearLayout:

 

package com.dp.android.widget;
import com.dp.android.elong.shake.R;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
public class BottomTabBar extends LinearLayout {
    //--implements two kinds of constructions--
    public  BottomTabBar(Context context) {
        super(context);
        init(context);
    }
    public BottomTabBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }
    private void init(Context context) {
        LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);
        setLayoutParams(lp);
        LayoutInflater mInflater = LayoutInflater.from(context);
        View v = mInflater.inflate(R.layout.bottom_tabs, null);
        addView(v,lp);
    }
}

 

自定义的View(xml 形式)

<?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
       xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
        <!-- 搜索 -->
        <LinearLayout
            android:id="@+id/ll_bottom_tabls_search"
            style = "@style/bottom_tabs_ll"
            >
            <ImageView
                android:id="@+id/im_search"
                style = "@style/bottom_tabs_image"
                android:src="@drawable/bottom_tab_search" />
            <TextView
                style = "@style/bottom_tabs_tv"
                android:text="@string/bottom_tab_search"
                />
         </LinearLayout>
        <!-- 摇过 -->
        <LinearLayout
            android:id="@+id/ll_bottom_tabls_history"
            style = "@style/bottom_tabs_ll"
            >
            <ImageView
                android:id="@+id/im_history"
                style = "@style/bottom_tabs_image"
                android:src="@drawable/bottom_tab_history" />
            <TextView
                style = "@style/bottom_tabs_tv"
                android:text="@string/bootom_tab_shake"
                />
         </LinearLayout>
        <!-- 换一个 -->
        <LinearLayout
            android:id="@+id/ll_bottom_tabls_change"
            style = "@style/bottom_tabs_ll"
            >
            <ImageView
                android:id="@+id/im_change"
                style = "@style/bottom_tabs_image"
                android:src="@drawable/bottom_tab_blank"
                />
            <TextView
                style = "@style/bottom_tabs_tv"
                android:text="@string/bottom_tab_change"
                />
         </LinearLayout>
        <!-- 收藏 -->
        <LinearLayout
            android:id="@+id/ll_bottom_tabls_collection"
            style = "@style/bottom_tabs_ll"
            >
            <ImageView
                android:id="@+id/im_collection"
                style = "@style/bottom_tabs_image"
                android:src="@drawable/bottom_tab_collection"
                />
            <TextView
                style = "@style/bottom_tabs_tv"
                android:text="@string/bootom_tab_collection"
                />
         </LinearLayout>
        <!-- 更多 -->
        <LinearLayout
            android:id="@+id/ll_bottom_tabls_more"
            style = "@style/bottom_tabs_ll"
            >
            <ImageView
                android:id="@+id/im_more"
                style = "@style/bottom_tabs_image"
                android:src="@drawable/bottom_tab_more"
                />
            <TextView
                style = "@style/bottom_tabs_tv"
                android:text="@string/bootom_tab_more"
                />
         </LinearLayout>
    </LinearLayout>

 

view 中用到的 三个 style

<style name="bottom_tabs_ll" >
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:background">@color/black</item>
    <item name="android:orientation">vertical</item>
    <item name="android:gravity">center</item>
    <item name="android:layout_gravity">bottom</item>
    <item name="android:layout_weight">1</item>
</style>
<style name="bottom_tabs_image" >
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:paddingTop">5dip</item>
</style>
<style name="bottom_tabs_tv" >
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:textSize">12sp</item>
    <item name="android:textColor">@color/common_white</item>
    <item name="android:paddingTop">3dip</item>
    <item name="android:gravity">center</item>
</style>

//—————————————————————下面是如何使用自己定义的 组建了————————————-

1: 注意 BottomTabBar ,,, 这里面还用到了自定义的 “凸起” 组件。 MyBottmArc

 

<FrameLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@color/shake_yellow_bg"
android:orientation="vertical"
>
<com.dp.android.widget.BottomTabBar
android:id="@+id/bottom_tab_bar1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="30dip"
/>

<com.dp.android.widget.MyBottmArc
android:id="@+id/im_change"
android:layout_width="80dip"
android:layout_height="60dip"
android:padding="15dip"
android:src="@drawable/bottom_tab_search"
android:layout_gravity="top|center_horizontal"
/>

</FrameLayout>

 

//————————————————————————————–下面看看  凸起 是怎么弄的———————————————————————————

凸起 也是自己定义了一个 ImageView,  这个ImageView 的背景  就是绘制半个 圆弧。。。“拱形”

 

package com.dp.android.widget;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.widget.ImageView;
public class MyBottmArc extends ImageView {
    private static Paint paint = new Paint();
    public MyBottmArc(Context context) {
        super(context);
    }
    public MyBottmArc(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public MyBottmArc(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    protected void onDraw(Canvas canvas) {
        Rect m_rect = canvas.getClipBounds();
        canvas.save();
        paint.setColor(0xff000000);
        float m_left = m_rect.left;
        float m_top = m_rect.top;
        float m_right = m_rect.right;
        float m_bottom = (1.2f)*(m_rect.bottom);
        RectF m_rectf = new RectF(m_left,m_top,m_right,m_bottom);
        canvas.drawOval(m_rectf, paint);
        canvas.restore();
        super.onDraw(canvas);
    }
}

 

 

android-Service和Thread的区别

1.服务不是单一的进程。服务没有自己的进程,应用程序可以不同,服务运行在相同的进程中。

2.服务不是线程。可以在线程中工作。

一.在应用中,如果是长时间的在后台运行,而且不需要交互的情况下,使用服务。

同样是在后台运行,不需要交互的情况下,如果只是完成某个任务,之后就不需要运行,而且可能是多个任务,需要长时间运行的情况下使用线程。

二.如果任务占用CPU时间多,资源大的情况下,要使用线程。

 

servie是系统的组件,它由系统进程托管(servicemanager);它们之间的通信类似于client和server,是一种轻量级的ipc通信,这种通信的载体是binder,它是在linux层交换信息的一种ipc。而thread是由本应用程序托管。

 

1). Thread:Thread 是程序执行的最小单元,它是分配CPU的基本单位。可以用Thread 来执行一些异步的操作。

 

2). Service:Service 是android的一种机制,当它运行的时候如果是Local Service,那么对应的Service 是运行在主进程的main 线程上的。如:onCreate,onStart 这些函数在被系统调用的时候都是在主进程的main 线程上运行的。如果是Remote Service,那么对应的Service 则是运行在独立进程的main 线程上。

 

既然这样,那么我们为什么要用Service 呢?其实这跟android 的系统机制有关,我们先拿Thread 来说。Thread 的运行是独立于Activity 的,也就是说当一个Activity 被finish 之后,如果你没有主动停止Thread 或者Thread 里的run 方法没有执行完毕的话,Thread 也会一直执行。因此这里会出现一个问题:当Activity 被finish 之后,你不再持有该Thread 的引用。另一方面,你没有办法在不同的Activity 中对同一Thread 进行控制。

 

举个例子:如果你的Thread 需要不停地隔一段时间就要连接服务器做某种同步的话,该Thread 需要在Activity 没有start的时候也在运行。这个时候当你start 一个Activity 就没有办法在该Activity 里面控制之前创建的Thread。因此你便需要创建并启动一个Service ,在Service 里面创建、运行并控制该Thread,这样便解决了该问题(因为任何Activity 都可以控制同一Service,而系统也只会创建一个对应Service 的实例)。

 

因此你可以把Service 想象成一种消息服务,而你可以在任何有Context 的地方调用Context.startService、Context.stopService、Context.bindService,Context.unbindService,来控制它,你也可以在Service 里注册BroadcastReceiver,在其他地方通过发送broadcast 来控制它,当然这些都是Thread 做不到的。

———————————————————————————

 

广播接收者(BroadcastReceiver)用于接收广播Intent,广播Intent的发送是通过调用Context.sendBroadcast()、Context.sendOrderedBroadcast()来实现的。通常一个广播Intent可以被订阅了此Intent的多个广播接收者所接收,这个特性跟JMS中的Topic消息接收者类似。要实现一个广播接收者方法如下:
第一步:继承BroadcastReceiver,并重写onReceive()方法。
public class IncomingSMSReceiver extends BroadcastReceiver {
@Override public void onReceive(Context context, Intent intent) {
}
}
第二步:订阅感兴趣的广播Intent,订阅方法有两种:
第一种:使用代码进行订阅
IntentFilter filter = new IntentFilter(“android.provider.Telephony.SMS_RECEIVED”);
IncomingSMSReceiver receiver = new IncomingSMSReceiver();
registerReceiver(receiver, filter);
第二种:在AndroidManifest.xml文件中的<application>节点里进行订阅:
<receiver android:name=”.IncomingSMSReceiver”>
<intent-filter>
<action android:name=”android.provider.Telephony.SMS_RECEIVED”/>
</intent-filter>
</receiver>

如果你想别人接收到的短信,达到你不可告人的目的,那么使用BroadcastReceiver
当系统收到短信时,会发出一个广播Intent,Intent的action名称为、

如果要短信终止广播就要配置上你的广播接收者的级别

<intent-filter android:priority=”100″ >
<action android:name=”android.provider.Telephony.SMS_RECEIVED” />
</intent-filter>

android.provider.Telephony.SMS_RECEIVED,该Intent存放了系统接收到的短信内容,我们使用名称“pdus”即可从Intent中获取到短信内容。

在AndroidManifest.xml文件中的<application>节点里对接收到短信的广播Intent进行订阅:
<receiver android:name=”.你的receiver名称”>
<intent-filter><action android:name=”android.provider.Telephony.SMS_RECEIVED”/></intent-filter></receiver>
在AndroidManifest.xml文件中添加以下权限:
<uses-permission android:name=”android.permission.RECEIVE_SMS”/><!– 接收短信权限 –>
<uses-permission android:name=”android.permission.SEND_SMS”/><!– 发送短信权限 –>

广播接收者的响应性

在Android中,每次广播消息到来时都会创建BroadcastReceiver实例并执行onReceive() 方法, onReceive() 方法执行完后,BroadcastReceiver 的实例就会被销毁。当onReceive() 方法在10秒内没有执行完毕,Android会认为该程序无响应。所以在BroadcastReceiver里不能做一些比较耗时的操作,否侧会弹出ANR(Application No Response)错误对话框。如果需要完成一项比较耗时的工作,应该通过发送Intent给Service,由Service来完成。这里不能使用子线程来解决,因为BroadcastReceiver的生命周期很短,子线程可能还没有结束BroadcastReceiver就先结束了。BroadcastReceiver一旦结束,此时BroadcastReceiver所在的进程很容易在系统需要内存时被优先杀死,因为它属于空进程(没有任何活动组件的进程)。如果它的所在进程被杀死,那么正在工作的子线程也会被杀死。所以采用子线程来解决是不可靠的。

public class IncomingSMSReceiver extends BroadcastReceiver {
@Override public void onReceive(Context context, Intent intent) {
//发送Intent启动服务,由服务来完成比较耗时的操作
Intent service = new Intent(context, XxxService.class);
context.startService(service);
}

除了短信到来广播Intent,Android还有很多广播Intent,如:开机启动、电池电量变化、时间已经改变等广播Intent。
接收电池电量变化广播Intent ,在AndroidManifest.xml文件中的<application>节点里订阅此Intent:
<receiver android:name=”.IncomingSMSReceiver”>
<intent-filter>
<action android:name=”android.intent.action.BATTERY_CHANGED”/>
</intent-filter>
</receiver>

接收开机启动广播Intent,在AndroidManifest.xml文件中的<application>节点里订阅此Intent:
<receiver android:name=”.IncomingSMSReceiver”>
<intent-filter>
<action android:name=”android.intent.action.BOOT_COMPLETED”/>
</intent-filter>
</receiver>
并且要进行权限声明:
<uses-permission android:name=”android.permission.RECEIVE_BOOT_COMPLETED”/>

广播接收者补充

广播分两种
有序广播 按照广播的优先级 发给相对应的广播接收者-1000-1000 激活广播通过onrecve方法处理
无序广播

有序广播有一个特例
sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler, initialCode, initialData, initialExtras);
resultReceiver 广播接受者 如果我们显示的指定了广播接收者
无论如何 都会接受广播 无法通过abortBroadcast();的方法终止广播
比如拨打电话有个out_goingcall 的广播是指定广播接收者的无法通过abortBroadcast()方法终止的,但是是可以将拨打的电话号码数据清空置为null,setResultData(null)就无法拨打电话

 

另外一种特殊的广播sendStickyBroadcast(intent) // 阴魂不散的广播
一般广播事件发送完毕被广播接受者接收到onReceive执行完毕后广播接收者的生命周期就结束了 这个会保持长时间的停留直到广播事件结束完毕
例如系统的Wifi,网卡状态的改变要一定的时间,保证网络状态更新完毕后才结束

代码中注册,如果代码没有执行,就接受不到广播事件

什么时候使用广播,例如sdcard新增图片的时候是无法显示到图库的当sdcard被挂载状态发生改变才会重新加载sdcard的数据

这时可以发送一个sd挂载的通知,通知系统的gallery去获取到新的图片.

Intent intent = newIntent(Intent.ACTION_MEDIA_MOUNTED,Uri.parse(“file://”+Environment.getExternalStorageDirectory()));

sendBroadcast(intent);