阅读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