Android動畫效果Widget(飛行模式)

1. 功能:

創建Widget後,若爲飛行模式,點擊Widget,取消飛行模式,否則設置爲飛行模式。在變化過程中有動畫效果。

2. 實現思想:
對應main.xml佈局文件,Widget由三張圖片組成,pane上層左邊爲airplane,右邊爲switch點擊桌面widget時圖標的時候,左邊airplane四張圖標動態的在切換,直到設置爲飛行模式或者取消飛行模式狀態完成時,airplane切換停止,同時右邊switch圖片切換settrings_switch_on或者settrings_switch_off。
 
3.       程序中用到圖片資源文件如下:
settings_icon_airplane_01.png     

settings_icon_airplane_02.png     

settings_icon_airplane_03.png     
 
  
settings_icon_airplane_04.png 
   
settings_pane_off.png    

settings_switch_off.png     

settings_switch_on.png      

widget_icon_airplane.png    

 

  1. code: 
  2. 佈局文件main.xml 
  3. <?xml version="1.0" encoding="utf-8"?> 
  4. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  5.     android:layout_width="wrap_content" 
  6.     android:layout_height="wrap_content"> 
  7.     <ImageView android:id="@+id/setting_pane" 
  8.        android:layout_width="wrap_content" 
  9.        android:layout_height="wrap_content" 
  10.        android:src="@drawable/settings_pane_off"/> 
  11.     <ImageView android:id="@+id/setting_airplane" 
  12.            android:layout_width="wrap_content" 
  13.            android:layout_height="wrap_content" 
  14.            android:layout_alignParentLeft="true" 
  15.            android:layout_centerVertical="true" 
  16.            android:layout_marginLeft="6dip" 
  17.            android:src="@drawable/settings_icon_airplane_04"/> 
  18.     <ImageView android:id="@+id/setting_switch" 
  19.            android:layout_width="wrap_content" 
  20.            android:layout_height="wrap_content" 
  21.            android:layout_toRightOf="@id/setting_airplane" 
  22.            android:layout_centerVertical="true" 
  23.            android:layout_marginLeft="4dip" 
  24.            android:src="@drawable/settings_switch_off"/> 
  25. </RelativeLayout> 
  26.   
  27. 在res下新建xml文件夾,然後新建widget_provider.xml 
  28. <?xml version="1.0" encoding="UTF-8"?> 
  29. <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" 
  30.     android:minWidth="50dip" <-指定寬度度-> 
  31.     android:minHeight="50dip" <-指定高度-> 
  32.     android:initialLayout="@layout/main"/> 
  33.   
  34. 新建AirplaneModeEnabler類 
  35. public class AirplaneModeEnabler{ 
  36. //此方法判斷是否爲飛行模式 
  37.  public static boolean isAirplaneModeOn(Context context){ 
  38.   return Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,0)!=0; 
  39.  } 
  40. //此方法設置或取消飛行模式,enabling參數爲true,則設爲飛行模式,否則取消飛行模式
  41.  public static void setAirplaneModeOn(Context context,boolean enabling){ 
  42.   Settings.System.putInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, enabling?1:0); 
  43.   Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 
  44.   intent.putExtra("state", enabling); 
  45.   context.sendBroadcast(intent); 
  46.  } 
  47.   
  48. 建MyWidget 類,繼承AppWidgetProvider,此類則widget第一次創建時執行oupdate方法,
  49. 即是廣播接受者,也是廣播發送者
  50. public class MyWidget extends AppWidgetProvider { 
  51.   
  52.  private Context mContext = null
  53.  public RemoteViews remoteViews = new RemoteViews("com.archermind.widget", R.layout.main); 
  54.  public final static String SET_AIRPLANE_ACTION = "com.archermind.set_airplane_mode"
  55.  private static final int START_ANIMATION = 0; //開始動畫
  56.  private static final int END_ANIMATION = 1; //結束動畫
  57.  private static Boolean mRunAnimation = false
  58.  private Handler mHandler = new Handler() { 
  59.   @Override 
  60.   public void handleMessage(Message msg) { 
  61.    //接受到消息後開始動畫效果,即連續切換4張圖片
  62.    if (msg.what == START_ANIMATION) { 
  63.     Log.i("state", "START_ANIMATION: mRunAnimation = " + mRunAnimation); 
  64.     if (!mRunAnimation) { 
  65.      return; 
  66.     }
  67.     //更新widget背景圖片
  68.     remoteViews.setImageViewResource(R.id.setting_airplane, mDrawable[msg.arg1]); 
  69.     AppWidgetManager appWidgetManger = AppWidgetManager 
  70.      .getInstance(mContext); 
  71.     int[] appIds = appWidgetManger.getAppWidgetIds(new ComponentName( 
  72.             mContext, MyWidget.class)); 
  73.     for (int id: appIds) { 
  74.      appWidgetManger.updateAppWidget(id, remoteViews); 
  75.     } 
  76.      
  77.     // send message for next frame 
  78.     Message message = mHandler.obtainMessage(START_ANIMATION); 
  79.     message.arg1 = (msg.arg1 + 1) % 4; 
  80.     mHandler.sendMessageDelayed(message, 200); 
  81.    } else if (msg.what == END_ANIMATION) {  //結束動畫,
  82.     Log.i("state", "END_ANIMATION: mRunAnimation = " + mRunAnimation); 
  83.     AppWidgetManager appWidgetManger = AppWidgetManager 
  84.         .getInstance(mContext); 
  85.     int[] appIds = appWidgetManger.getAppWidgetIds(new ComponentName( 
  86.            mContext, MyWidget.class)); 
  87.     for (int id: appIds) { 
  88.      updateAppWidget(mContext, appWidgetManger, id); 
  89.     } 
  90.    } 
  91.    Log.i("hThreadId",Long.toString(Thread.currentThread().getId())); 
  92.   } 
  93.  }; 
  94.   
  95.  private int[] mDrawable = { 
  96.   R.drawable.settings_icon_airplane_01, 
  97.   R.drawable.settings_icon_airplane_02, 
  98.   R.drawable.settings_icon_airplane_03, 
  99.   R.drawable.settings_icon_airplane_04 
  100.  }; 
  101.   
  102.  @Override 
  103.  public void onDeleted(Context context, int[] appWidgetIds) { 
  104.   super.onDeleted(context, appWidgetIds); 
  105.   Log.i("method", "onDeleted()"); 
  106.  } 
  107.  @Override 
  108.  public void onDisabled(Context context) { 
  109.   super.onDisabled(context); 
  110.   Log.i("method", "onDisabled()"); 
  111.  } 
  112.  @Override 
  113.  public void onEnabled(Context context) { 
  114.   super.onEnabled(context); 
  115.   Log.i("method", "onEnabled()"); 
  116.  //創建widgt時,調用此方法,註冊電話監聽器
  117.   TelephonyManager telephonyManager=(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 
  118.   telephonyManager.listen( mPhoneStateListener,PhoneStateListener.LISTEN_SERVICE_STATE); 
  119.  }
        //接受到發送到廣播時執行此方法
  1.  @Override 
  2.  public void onReceive(Context context, Intent intent) { 
  3.   Log.i("method", "onReceive()"); 
  4.   super.onReceive(context, intent); 
  5.   Log.i("action",intent.getAction()); 
  6.   if(mContext ==null){ 
  7.    mContext = context
  8.   }

  9.   if(intent.getAction().equals(SET_AIRPLANE_ACTION)){ 
  10.    boolean airplaneMode = AirplaneModeEnabler.isAirplaneModeOn(context); 
  11.    if(airplaneMode){ 
  12.           AirplaneModeEnabler.setAirplaneModeOn(context, !airplaneMode); 
  13.          }else{ 
  14.           AirplaneModeEnabler.setAirplaneModeOn(context, !airplaneMode); 
  15.          } 
  16.     
  17.    Log.e("state", "onReceive: mRunAnimation = true"); 
  18.    mRunAnimation = true
  19.    Message msg = mHandler.obtainMessage(START_ANIMATION); 
  20.    msg.arg1 = 0
  21.    mHandler.sendMessage(msg); 
  22.   } 
  23.  } 
  24.   
  25.  @Override 
  26.  public void onUpdate(Context context, AppWidgetManager appWidgetManager, 
  27.    int[] appWidgetIds) { 
  28.   super.onUpdate(context, appWidgetManager, appWidgetIds); 
  29.   Log.i("method", "onUpdate()"); 
  30.   if(mContext==null){ 
  31.    mContext = context
  32.   }
  33. //創建RemoteViews,並調用updateAppWidget更新背景圖片
  34.   remoteViews = new RemoteViews(context.getPackageName(), R.layout.main); 
  35.   int n = appWidgetIds.length; 
  36.      for (int i = 0; i < n; i++) { 
  37.         int appWidgetId = appWidgetIds[i]; 
  38.         updateAppWidget(context, appWidgetManager, appWidgetId); 
  39.      } 
  40.      Log.i("length of appIds", ""+appWidgetIds.length); 
  41.  } 
  42.  //判斷當前是否爲飛行模式,並設置不同到背景圖片
  43.  public void updateAppWidget(Context context, 
  44.             AppWidgetManager appWidgeManger, int appWidgetId) { 
  45.   boolean airplaneMode = AirplaneModeEnabler.isAirplaneModeOn(context); 
  46.   if(airplaneMode){ 
  47.    remoteViews.setImageViewResource(R.id.setting_airplane,R.drawable.settings_icon_airplane_04); 
  48.    remoteViews.setImageViewResource(R.id.setting_switch,R.drawable.settings_switch_on); 
  49.   }else{ 
  50.    remoteViews.setImageViewResource(R.id.setting_airplane,R.drawable.settings_icon_airplane_04); 
  51.    remoteViews.setImageViewResource(R.id.setting_switch,R.drawable.settings_switch_off); 
  52.   }
  53. //單機widget時發送廣播
  54.   Intent intentClick = new Intent(SET_AIRPLANE_ACTION); 
  55.         PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, 
  56.                 intentClick, 0); 
  57.         remoteViews.setOnClickPendingIntent(R.id.setting_pane, pendingIntent); 
  58.         appWidgeManger.updateAppWidget(appWidgetId, remoteViews); 
  59.     } 
  60.  //電話監聽器,用來監聽是否爲飛行模式
  61.  PhoneStateListener mPhoneStateListener = new PhoneStateListener(){ 
  62.   @Override 
  63.   public void onServiceStateChanged(ServiceState serviceState) { 
  64.    super.onServiceStateChanged(serviceState); 
  65.    Log.i("phThreadId",Long.toString(Thread.currentThread().getId())); 
  66.    switch(serviceState.getState()){ 
  67.    case ServiceState.STATE_IN_SERVICE: 
  68.     Log.i("state", "STATE_IN_SERVICE mRunAnimation = false"); 
  69.     mRunAnimation = false
  70.     mHandler.sendMessage(Message.obtain(mHandler, END_ANIMATION)); 
  71.     break; 
  72.    case ServiceState.STATE_POWER_OFF: 
  73.     Log.i("state", "STATE_POWER_OFF mRunAnimation = false"); 
  74.     mRunAnimation = false
  75.     mHandler.sendMessage(Message.obtain(mHandler, END_ANIMATION)); 
  76.     break; 
  77.    case ServiceState.STATE_OUT_OF_SERVICE: 
  78.     Log.i("state", "STATE_OUT_OF_SERVICE"); 
  79.     break; 
  80.    case ServiceState.STATE_EMERGENCY_ONLY: 
  81.     Log.i("state", "STATE_EMERGENCY_ONLY"); 
  82.     break; 
  83.    } 
  84.   } 
  85.  }; 
  86.   
  87. <?xml version="1.0" encoding="utf-8"?> 
  88. <manifest xmlns:android="http://schemas.android.com/apk/res/android" 
  89.       package="com.archermind.widget" 
  90.       android:versionCode="1" 
  91.       android:versionName="1.0"> 
  92.     <application android:icon="@drawable/widget_icon_airplane" android:label="@string/app_name"> 
  93.         <receiver android:name=".MyWidget" 
  94.                   android:label="@string/app_name" android:icon="@drawable/widget_icon_airplane"> 
  95.             <intent-filter> 
  96.                 <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
  97.                 <action android:name="com.archermind.set_airplane_mode" /> 
  98.             </intent-filter> 
  99.             <meta-data android:name="android.appwidget.provider" 
  100.                  android:resource="@xml/widget_provider"/> 
  101.         </receiver> 
  102.     </application> 
  103.     <uses-permission android:name="android.permission.WRITE_SETTINGS" /> 
  104. </manifest> 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章