閱讀693 返回首頁    go 阿裏雲 go 技術社區[雲棲]


可滑動的係統狀態欄控製麵板(wifi,bluetooth,數據通信,聲音,自動旋轉)

https://blog.csdn.net/comkingfly/article/details/7013677

在係統狀態欄裏添加一些開關,便於用戶操作一些常用的操作,比如開關Wifi,開關藍牙,開關數據通信等,這些都是在設置裏可以控製 的,但是用戶要點擊多次之後才能到達要去的區域,這個對用戶體驗不佳。所以在狀態欄裏添加些控製按鈕很有必要,一般一個頁麵放3到5個開關布局比較好看,但是要是想放多個多個開關,則可以通過布局畫或者用組件。

       左右滑動可以使用ViewFlipper組件來實現視圖之間的切換,然後添加手勢控製類即可。

                     


我為了方便修改項目,把控製麵板的代碼單獨的提取出來,放到一個類裏控製。

首先添加布局,在SystemUI的status_bar_expanded.xml裏添加自定義的類。

  1. <span style="font-size:18px;color:#006600;">    <com.android.systemui.statusbar.SwitchControlPanel   
  2.         android:id="@+id/switch_control_panel"  
  3.         android:layout_height="wrap_content"   
  4.         android:layout_width="match_parent"/></span>  

然後要去SystemUI的StatusBarService.java裏初始化這個類,這樣係統啟動時候就會發現這個類,進而進行操作了。

  1. <pre style="BACKGROUND-COLOR: rgb(240,240,240); MARGIN: 4px 0px" class="java" name="code"><span style="font-size:18px;color:#006600;">SwitchControlPanel  mPanel;</span>  


  1. <span style="font-size:18px;color:#006600;">mPanel = (SwitchControlPanel)expanded.findViewById(R.id.switch_control_panel);</span>  

然後就可以操作SwitchControlPanel.java這個類了,這個是繼承於LinearyLayout,所以要在裏麵添加布局,需要用到inflate這個類,因為不是在Activity裏使用,所以這裏就與眾不同點。


  1. <span style="font-size:18px;color:#006600;">package com.android.systemui.statusbar;  
  2.   
  3. import android.content.BroadcastReceiver;  
  4. import android.content.Context;  
  5. import android.content.Intent;  
  6. import android.content.IntentFilter;  
  7. import android.net.wifi.WifiManager;  
  8. import android.util.AttributeSet;  
  9. import android.util.Log;  
  10. import android.view.GestureDetector;  
  11. import android.view.LayoutInflater;  
  12. import android.view.MotionEvent;  
  13. import android.view.View;  
  14. import android.view.GestureDetector.OnGestureListener;  
  15. import android.view.View.OnTouchListener;  
  16. import android.view.animation.AccelerateInterpolator;  
  17. import android.view.animation.Animation;  
  18. import android.view.animation.TranslateAnimation;  
  19. import android.view.animation.Animation.AnimationListener;  
  20. import android.widget.AdapterView;  
  21. import android.widget.LinearLayout;  
  22. import android.widget.TextView;  
  23. import android.widget.ViewFlipper;  
  24. import android.widget.AdapterView.OnItemClickListener;  
  25.   
  26. import com.android.systemui.R;  
  27.   
  28. public class SwitchControlPanel extends LinearLayout implements OnItemClickListener, OnGestureListener, OnTouchListener,AnimationListener {  
  29.       
  30.     private ViewFlipper mFlipper;  
  31.     GestureDetector mGestureDetector;  
  32.     private int mCurrentLayoutState;  
  33.     private static final int FLING_MIN_DISTANCE = 100;  
  34.     private static final int FLING_MIN_VELOCITY = 200;  
  35.       
  36.     TextView wifiView;  
  37.     LinearLayout wifiLayout;  
  38.     private WifiManager mWifiManager;  
  39.     private IntentFilter mWifiStateFilter;  
  40.       
  41.     public SwitchControlPanel(Context context) {  
  42.         super(context);  
  43.   
  44.     }  
  45.   
  46.     public SwitchControlPanel(Context context, AttributeSet attrs) {  
  47.         super(context, attrs);  
  48.         LayoutInflater inflater = LayoutInflater.from(context);  
  49.         inflater.inflate(R.layout.switch_control_panel, this);  
  50.         Log.e("kingfly""kingfly SwitchControlPanel enter");  
  51.   
  52.     }  
  53.   
  54.     @Override  
  55.     protected void onAttachedToWindow() {  
  56.         super.onAttachedToWindow();  
  57.   
  58.     }  
  59.   
  60.     @Override  
  61.     protected void onFinishInflate() {  
  62.         super.onFinishInflate();  
  63.         mFlipper=(ViewFlipper)findViewById(R.id.flipper);  
  64.         mGestureDetector=new GestureDetector(this);  
  65.           
  66.         wifiLayout=(LinearLayout)mFlipper.findViewById(R.id.switch_wifi);  
  67.         wifiView=(TextView)mFlipper.findViewById(R.id.switch_text_wifi);  
  68.         wifiLayout.setOnClickListener(mChangeWifi);  
  69.         wifiLayout.setOnTouchListener(mOnTouch);  
  70.         wifiView.setOnTouchListener(mOnTouch);  
  71.         mWifiManager = (WifiManager) this.getContext().getSystemService(Context.WIFI_SERVICE);  
  72.         handleWifiStateChanged(mWifiManager.getWifiState());  
  73.         mWifiStateFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);  
  74.         this.getContext().registerReceiver(mWifiReceiver, mWifiStateFilter);  
  75.           
  76.           
  77.         mGestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {  
  78.             @Override  
  79.             public boolean onSingleTapConfirmed(MotionEvent e) {  
  80.                 // TODO Auto-generated method stub  
  81.                 return false;  
  82.             }  
  83.               
  84.             @Override  
  85.             public boolean onDoubleTapEvent(MotionEvent e) {  
  86.                 // TODO Auto-generated method stub  
  87.                 return false;  
  88.             }  
  89.               
  90.             @Override  
  91.             public boolean onDoubleTap(MotionEvent e) {  
  92.                 // TODO Auto-generated method stub  
  93.                 return false;  
  94.             }  
  95.         });  
  96.         mFlipper.setOnTouchListener(this);  
  97.         mCurrentLayoutState=0;  
  98.         mFlipper.setLongClickable(true);  
  99.           
  100.         Log.e("kingfly""kingfly onFinishInflate enter");  
  101.   
  102.     }  
  103.       
  104.       
  105.         private View.OnClickListener mChangeWifi = new View.OnClickListener() {  
  106.             @Override  
  107.             public void onClick(View v) {  
  108.                 if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLED) {  
  109.                     mWifiManager.setWifiEnabled(true);  
  110.                     handleWifiStateChanged(mWifiManager.getWifiState());  
  111.                 } else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {  
  112.                     mWifiManager.setWifiEnabled(false);  
  113.                     handleWifiStateChanged(mWifiManager.getWifiState());  
  114.                 } else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_UNKNOWN) {  
  115.                     mWifiManager.setWifiEnabled(true);  
  116.                     handleWifiStateChanged(mWifiManager.getWifiState());  
  117.                 }  
  118.   
  119.             }  
  120.         };  
  121.           
  122.         private View.OnTouchListener mOnTouch=new View.OnTouchListener() {  
  123.               
  124.             @Override  
  125.             public boolean onTouch(View v, MotionEvent event) {  
  126.                 Log.e("kingfly""kingfly View.onTouch");  
  127.                 mGestureDetector.onTouchEvent(event);  
  128.                 return false;  
  129.             }  
  130.         };  
  131.       
  132.       
  133.   
  134.         private void handleWifiStateChanged(int state) {  
  135.             switch (state) {  
  136.             case WifiManager.WIFI_STATE_ENABLING:  
  137.                 wifiView.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(R.drawable.stat_switch_wifi_off), null, getResources().getDrawable(R.drawable.stat_switch_ind_off));  
  138.                 wifiView.setText(R.string.switch_enabling);  
  139.                 break;  
  140.             case WifiManager.WIFI_STATE_ENABLED:  
  141.                 wifiView.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(R.drawable.stat_switch_wifi_on), null, getResources().getDrawable(R.drawable.stat_switch_ind_on));  
  142.                 wifiView.setText(R.string.switch_wifi_summary);  
  143.                 break;  
  144.             case WifiManager.WIFI_STATE_DISABLING:  
  145.                 wifiView.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(R.drawable.stat_switch_wifi_on), null, getResources().getDrawable(R.drawable.stat_switch_ind_on));  
  146.                 wifiView.setText(R.string.switch_closing);  
  147.                 break;  
  148.             case WifiManager.WIFI_STATE_DISABLED:  
  149.                 wifiView.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(R.drawable.stat_switch_wifi_off), null, getResources().getDrawable(R.drawable.stat_switch_ind_off));  
  150.                 wifiView.setText(R.string.switch_wifi_summary);  
  151.                 break;  
  152.             default:  
  153.                 wifiView.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(R.drawable.stat_switch_wifi_off), null, getResources().getDrawable(R.drawable.stat_switch_ind_off));  
  154.                 wifiView.setText(R.string.switch_wifi_summary);  
  155.             }  
  156.         }  
  157.           
  158.         private final BroadcastReceiver mWifiReceiver = new BroadcastReceiver() {  
  159.             @Override  
  160.             public void onReceive(Context context, Intent intent) {  
  161.                 String action = intent.getAction();  
  162.                 if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {  
  163.                     handleWifiStateChanged(intent.getIntExtra(  
  164.                             WifiManager.EXTRA_WIFI_STATE, mWifiManager  
  165.                                     .getWifiState()));  
  166.                 }  
  167.   
  168.             }  
  169.   
  170.         };  
  171.       
  172.       
  173.     protected Animation inFromRightAnimation() {  
  174.         Animation inFromRight = new TranslateAnimation(  
  175.                 Animation.RELATIVE_TO_PARENT, +1.0f,  
  176.                 Animation.RELATIVE_TO_PARENT, 0.0f,  
  177.                 Animation.RELATIVE_TO_PARENT, 0.0f,  
  178.                 Animation.RELATIVE_TO_PARENT, 0.0f);  
  179.         inFromRight.setDuration(500);  
  180.         inFromRight.setInterpolator(new AccelerateInterpolator());  
  181.         return inFromRight;  
  182.     }  
  183.   
  184.     protected Animation outToLeftAnimation() {  
  185.         Animation outtoLeft = new TranslateAnimation(  
  186.                 Animation.RELATIVE_TO_PARENT, 0.0f,  
  187.                 Animation.RELATIVE_TO_PARENT, -1.0f,  
  188.                 Animation.RELATIVE_TO_PARENT, 0.0f,  
  189.                 Animation.RELATIVE_TO_PARENT, 0.0f);  
  190.         outtoLeft.setDuration(500);  
  191.         outtoLeft.setInterpolator(new AccelerateInterpolator());  
  192.         return outtoLeft;  
  193.     }  
  194.   
  195.     protected Animation inFromLeftAnimation() {  
  196.         Animation inFromLeft = new TranslateAnimation(  
  197.                 Animation.RELATIVE_TO_PARENT, -1.0f,  
  198.                 Animation.RELATIVE_TO_PARENT, 0.0f,  
  199.                 Animation.RELATIVE_TO_PARENT, 0.0f,  
  200.                 Animation.RELATIVE_TO_PARENT, 0.0f);  
  201.         inFromLeft.setDuration(500);  
  202.         inFromLeft.setInterpolator(new AccelerateInterpolator());  
  203.         return inFromLeft;  
  204.     }  
  205.   
  206.     protected Animation outToRightAnimation() {  
  207.         Animation outtoRight = new TranslateAnimation(  
  208.                 Animation.RELATIVE_TO_PARENT, 0.0f,  
  209.                 Animation.RELATIVE_TO_PARENT, +1.0f,  
  210.                 Animation.RELATIVE_TO_PARENT, 0.0f,  
  211.                 Animation.RELATIVE_TO_PARENT, 0.0f);  
  212.         outtoRight.setDuration(500);  
  213.         outtoRight.setInterpolator(new AccelerateInterpolator());  
  214.         return outtoRight;  
  215.     }  
  216.   
  217.     @Override  
  218.     public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {  
  219.         // TODO Auto-generated method stub  
  220.   
  221.     }  
  222.   
  223.     @Override  
  224.     public boolean onDown(MotionEvent arg0) {  
  225.         // TODO Auto-generated method stub  
  226.         return true;  
  227.     }  
  228.   
  229.     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,  
  230.             float velocityY) {  
  231.         Log.e("kingfly""kingfly e1 :"+e1.getX()+" e2 :"+e2.getX());  
  232.         Log.e("kingfly""Kingfly velocityX :"+velocityX+" velocityY :"+velocityY);  
  233.         if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE  
  234.                 && Math.abs(velocityX) > FLING_MIN_VELOCITY) {  
  235.             mFlipper.setInAnimation(inFromRightAnimation());  
  236.             mFlipper.setOutAnimation(outToLeftAnimation());  
  237.             mFlipper.showNext();  
  238.         } else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE  
  239.                 && Math.abs(velocityX) > FLING_MIN_VELOCITY) {  
  240.             mFlipper.setInAnimation(inFromLeftAnimation());  
  241.             mFlipper.setOutAnimation(outToRightAnimation());  
  242.             mFlipper.showPrevious();  
  243.         }  
  244.         return false;  
  245.   
  246.     }  
  247.   
  248.     @Override  
  249.     public void onLongPress(MotionEvent arg0) {  
  250.         // TODO Auto-generated method stub  
  251.   
  252.     }  
  253.   
  254.     @Override  
  255.     public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2,  
  256.             float arg3) {  
  257.         // TODO Auto-generated method stub  
  258.         return false;  
  259.     }  
  260.   
  261.     @Override  
  262.     public void onShowPress(MotionEvent arg0) {  
  263.         // TODO Auto-generated method stub  
  264.   
  265.     }  
  266.   
  267.     @Override  
  268.     public boolean onSingleTapUp(MotionEvent arg0) {  
  269.         // TODO Auto-generated method stub  
  270.         return false;  
  271.     }  
  272.   
  273.     @Override  
  274.     public boolean onTouch(View v, MotionEvent event) {  
  275.         Log.e("kingfly""kingfly onTouch");  
  276.         switch(event.getAction()){  
  277.         case MotionEvent.ACTION_MOVE:  
  278.             v.setAnimation(new Animation() {  
  279.             });  
  280.             break;  
  281.         }     
  282.         return mGestureDetector.onTouchEvent(event);  
  283.     }  
  284.   
  285.     @Override  
  286.     public void onAnimationEnd(Animation arg0) {  
  287.         // TODO Auto-generated method stub  
  288.   
  289.     }  
  290.   
  291.     @Override  
  292.     public void onAnimationRepeat(Animation arg0) {  
  293.         // TODO Auto-generated method stub  
  294.   
  295.     }  
  296.   
  297.     @Override  
  298.     public void onAnimationStart(Animation arg0) {  
  299.         // TODO Auto-generated method stub  
  300.   
  301.     }  
  302. }  
  303. </span>  

裏麵引用的布局文件switch_control_panel.xml

  1. <span style="font-size:18px;color:#006600;"><?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout  
  3.   xmlns:android="https://schemas.android.com/apk/res/android"  
  4.   android:orientation="horizontal"  
  5.   android:layout_width="fill_parent"  
  6.   android:layout_height="wrap_content"  
  7.   android:background="@drawable/stat_switch_bg" >  
  8.     <ViewFlipper   
  9.         android:id="@+id/flipper"   
  10.         android:layout_below="@+id/CockpitLayout"   
  11.         android:layout_height="fill_parent"   
  12.         android:layout_width="fill_parent">  
  13.              <include android:id="@+id/firstlayout" layout="@layout/statusbarfirst"></include>  
  14.              <include android:id="@+id/secondlayout" layout="@layout/statusbarsecond"></include>  
  15.     </ViewFlipper>  
  16. </LinearLayout>  
  17. </span>  

include裏的兩個都是布局文件,statusbarfirst.xml

  1. <span style="font-size:18px;color:#006600;"><?xml version="1.0" encoding="UTF-8"?>  
  2. <LinearLayout  
  3.   xmlns:android="https://schemas.android.com/apk/res/android"  
  4.   android:orientation="horizontal"  
  5.   android:layout_width="fill_parent"  
  6.   android:layout_height="wrap_content">  
  7. <LinearLayout  
  8.         android:id="@+id/switch_wifi"  
  9.         android:layout_width="0dip"  
  10.         android:layout_weight="1"  
  11.         android:layout_height="wrap_content"  
  12.         android:clickable="true"  
  13.         android:focusable="true"  
  14.         android:orientation="vertical">  
  15.   
  16.         <TextView  
  17.             android:id="@+id/switch_text_wifi"  
  18.             android:layout_width="match_parent"  
  19.             android:layout_height="wrap_content"  
  20.             android:gravity="center"  
  21.             />  
  22.   
  23.         </LinearLayout>  
  24.   
  25.     <ImageView  
  26.         android:layout_width="2dip"  
  27.         android:layout_height="match_parent"  
  28.         android:background="@drawable/stat_switch_divider"  
  29.         />  
  30.     <LinearLayout  
  31.         android:id="@+id/switch_bluetooth"  
  32.         android:layout_width="0dip"  
  33.         android:layout_weight="1"  
  34.         android:layout_height="wrap_content"  
  35.         android:clickable="true"  
  36.         android:focusable="true"  
  37.         android:orientation="vertical">  
  38.   
  39.         <ImageView  
  40.             android:id="@+id/switch_img_bluetooth"  
  41.             android:layout_width="wrap_content"  
  42.             android:layout_height="0dip"  
  43.             android:layout_weight="1"  
  44.             android:scaleType="center"  
  45.             android:layout_gravity="center_horizontal"  
  46.             android:background="@drawable/stat_switch_bluetooth_on"  
  47.             />  
  48.         <TextView  
  49.             android:id="@+id/switch_text_bluetooth"  
  50.             android:layout_width="match_parent"  
  51.             android:layout_height="wrap_content"  
  52.             android:gravity="center"  
  53.             android:text="@string/switch_bluetooth_summary"  
  54.             />  
  55.   
  56.         <ImageView  
  57.             android:id="@+id/switch_ind_bluetooth"  
  58.             android:layout_width="match_parent"  
  59.             android:layout_height="wrap_content"  
  60.             android:scaleType="fitXY"  
  61.           android:layout_marginLeft="6dip"  
  62.             android:layout_marginRight="6dip"  
  63.             android:background="@drawable/stat_switch_ind_on"  
  64.             />  
  65.         </LinearLayout>  
  66. </LinearLayout></span>  


還有就是onTouch(返回false就不會覆蓋掉onClick()事件了,所以這樣既可以滑動也可以點擊。

其他的功能可以依照上麵的代碼繼續添加,也可以直接用LinearLayout等布局畫出來,不需要ViewFlipper,當然還要添加幾個小點來提示用戶有多少個視圖,這樣用戶體驗更加。

最後更新:2017-04-02 17:09:26

  上一篇:go Windows Server 2008 R2 中 Web 服務器 (IIS) 角色的新增功能
  下一篇:go 開源異步處項目Droid-Fu詳解 For Android: BetterActivity, BetterService And BetterAsyncTask