可滑动的系统状态栏控制面板(wifi,bluetooth,数据通信,声音,自动旋转)
https://blog.csdn.net/comkingfly/article/details/7013677
在系统状态栏里添加一些开关,便于用户操作一些常用的操作,比如开关Wifi,开关蓝牙,开关数据通信等,这些都是在设置里可以控制 的,但是用户要点击多次之后才能到达要去的区域,这个对用户体验不佳。所以在状态栏里添加些控制按钮很有必要,一般一个页面放3到5个开关布局比较好看,但是要是想放多个多个开关,则可以通过布局画或者用组件。
左右滑动可以使用ViewFlipper组件来实现视图之间的切换,然后添加手势控制类即可。
我为了方便修改项目,把控制面板的代码单独的提取出来,放到一个类里控制。
首先添加布局,在SystemUI的status_bar_expanded.xml里添加自定义的类。
- <span style="font-size:18px;color:#006600;"> <com.android.systemui.statusbar.SwitchControlPanel
- android:id="@+id/switch_control_panel"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"/></span>
然后要去SystemUI的StatusBarService.java里初始化这个类,这样系统启动时候就会发现这个类,进而进行操作了。
- <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>
- <span style="font-size:18px;color:#006600;">mPanel = (SwitchControlPanel)expanded.findViewById(R.id.switch_control_panel);</span>
然后就可以操作SwitchControlPanel.java这个类了,这个是继承于LinearyLayout,所以要在里面添加布局,需要用到inflate这个类,因为不是在Activity里使用,所以这里就与众不同点。
- <span style="font-size:18px;color:#006600;">package com.android.systemui.statusbar;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.net.wifi.WifiManager;
- import android.util.AttributeSet;
- import android.util.Log;
- import android.view.GestureDetector;
- import android.view.LayoutInflater;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.GestureDetector.OnGestureListener;
- import android.view.View.OnTouchListener;
- import android.view.animation.AccelerateInterpolator;
- import android.view.animation.Animation;
- import android.view.animation.TranslateAnimation;
- import android.view.animation.Animation.AnimationListener;
- import android.widget.AdapterView;
- import android.widget.LinearLayout;
- import android.widget.TextView;
- import android.widget.ViewFlipper;
- import android.widget.AdapterView.OnItemClickListener;
- import com.android.systemui.R;
- public class SwitchControlPanel extends LinearLayout implements OnItemClickListener, OnGestureListener, OnTouchListener,AnimationListener {
- private ViewFlipper mFlipper;
- GestureDetector mGestureDetector;
- private int mCurrentLayoutState;
- private static final int FLING_MIN_DISTANCE = 100;
- private static final int FLING_MIN_VELOCITY = 200;
- TextView wifiView;
- LinearLayout wifiLayout;
- private WifiManager mWifiManager;
- private IntentFilter mWifiStateFilter;
- public SwitchControlPanel(Context context) {
- super(context);
- }
- public SwitchControlPanel(Context context, AttributeSet attrs) {
- super(context, attrs);
- LayoutInflater inflater = LayoutInflater.from(context);
- inflater.inflate(R.layout.switch_control_panel, this);
- Log.e("kingfly", "kingfly SwitchControlPanel enter");
- }
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- }
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mFlipper=(ViewFlipper)findViewById(R.id.flipper);
- mGestureDetector=new GestureDetector(this);
- wifiLayout=(LinearLayout)mFlipper.findViewById(R.id.switch_wifi);
- wifiView=(TextView)mFlipper.findViewById(R.id.switch_text_wifi);
- wifiLayout.setOnClickListener(mChangeWifi);
- wifiLayout.setOnTouchListener(mOnTouch);
- wifiView.setOnTouchListener(mOnTouch);
- mWifiManager = (WifiManager) this.getContext().getSystemService(Context.WIFI_SERVICE);
- handleWifiStateChanged(mWifiManager.getWifiState());
- mWifiStateFilter = new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
- this.getContext().registerReceiver(mWifiReceiver, mWifiStateFilter);
- mGestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
- @Override
- public boolean onSingleTapConfirmed(MotionEvent e) {
- // TODO Auto-generated method stub
- return false;
- }
- @Override
- public boolean onDoubleTapEvent(MotionEvent e) {
- // TODO Auto-generated method stub
- return false;
- }
- @Override
- public boolean onDoubleTap(MotionEvent e) {
- // TODO Auto-generated method stub
- return false;
- }
- });
- mFlipper.setOnTouchListener(this);
- mCurrentLayoutState=0;
- mFlipper.setLongClickable(true);
- Log.e("kingfly", "kingfly onFinishInflate enter");
- }
- private View.OnClickListener mChangeWifi = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLED) {
- mWifiManager.setWifiEnabled(true);
- handleWifiStateChanged(mWifiManager.getWifiState());
- } else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {
- mWifiManager.setWifiEnabled(false);
- handleWifiStateChanged(mWifiManager.getWifiState());
- } else if (mWifiManager.getWifiState() == WifiManager.WIFI_STATE_UNKNOWN) {
- mWifiManager.setWifiEnabled(true);
- handleWifiStateChanged(mWifiManager.getWifiState());
- }
- }
- };
- private View.OnTouchListener mOnTouch=new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- Log.e("kingfly", "kingfly View.onTouch");
- mGestureDetector.onTouchEvent(event);
- return false;
- }
- };
- private void handleWifiStateChanged(int state) {
- switch (state) {
- case WifiManager.WIFI_STATE_ENABLING:
- wifiView.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(R.drawable.stat_switch_wifi_off), null, getResources().getDrawable(R.drawable.stat_switch_ind_off));
- wifiView.setText(R.string.switch_enabling);
- break;
- case WifiManager.WIFI_STATE_ENABLED:
- wifiView.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(R.drawable.stat_switch_wifi_on), null, getResources().getDrawable(R.drawable.stat_switch_ind_on));
- wifiView.setText(R.string.switch_wifi_summary);
- break;
- case WifiManager.WIFI_STATE_DISABLING:
- wifiView.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(R.drawable.stat_switch_wifi_on), null, getResources().getDrawable(R.drawable.stat_switch_ind_on));
- wifiView.setText(R.string.switch_closing);
- break;
- case WifiManager.WIFI_STATE_DISABLED:
- wifiView.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(R.drawable.stat_switch_wifi_off), null, getResources().getDrawable(R.drawable.stat_switch_ind_off));
- wifiView.setText(R.string.switch_wifi_summary);
- break;
- default:
- wifiView.setCompoundDrawablesWithIntrinsicBounds(null, getResources().getDrawable(R.drawable.stat_switch_wifi_off), null, getResources().getDrawable(R.drawable.stat_switch_ind_off));
- wifiView.setText(R.string.switch_wifi_summary);
- }
- }
- private final BroadcastReceiver mWifiReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
- handleWifiStateChanged(intent.getIntExtra(
- WifiManager.EXTRA_WIFI_STATE, mWifiManager
- .getWifiState()));
- }
- }
- };
- protected Animation inFromRightAnimation() {
- Animation inFromRight = new TranslateAnimation(
- Animation.RELATIVE_TO_PARENT, +1.0f,
- Animation.RELATIVE_TO_PARENT, 0.0f,
- Animation.RELATIVE_TO_PARENT, 0.0f,
- Animation.RELATIVE_TO_PARENT, 0.0f);
- inFromRight.setDuration(500);
- inFromRight.setInterpolator(new AccelerateInterpolator());
- return inFromRight;
- }
- protected Animation outToLeftAnimation() {
- Animation outtoLeft = new TranslateAnimation(
- Animation.RELATIVE_TO_PARENT, 0.0f,
- Animation.RELATIVE_TO_PARENT, -1.0f,
- Animation.RELATIVE_TO_PARENT, 0.0f,
- Animation.RELATIVE_TO_PARENT, 0.0f);
- outtoLeft.setDuration(500);
- outtoLeft.setInterpolator(new AccelerateInterpolator());
- return outtoLeft;
- }
- protected Animation inFromLeftAnimation() {
- Animation inFromLeft = new TranslateAnimation(
- Animation.RELATIVE_TO_PARENT, -1.0f,
- Animation.RELATIVE_TO_PARENT, 0.0f,
- Animation.RELATIVE_TO_PARENT, 0.0f,
- Animation.RELATIVE_TO_PARENT, 0.0f);
- inFromLeft.setDuration(500);
- inFromLeft.setInterpolator(new AccelerateInterpolator());
- return inFromLeft;
- }
- protected Animation outToRightAnimation() {
- Animation outtoRight = new TranslateAnimation(
- Animation.RELATIVE_TO_PARENT, 0.0f,
- Animation.RELATIVE_TO_PARENT, +1.0f,
- Animation.RELATIVE_TO_PARENT, 0.0f,
- Animation.RELATIVE_TO_PARENT, 0.0f);
- outtoRight.setDuration(500);
- outtoRight.setInterpolator(new AccelerateInterpolator());
- return outtoRight;
- }
- @Override
- public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
- // TODO Auto-generated method stub
- }
- @Override
- public boolean onDown(MotionEvent arg0) {
- // TODO Auto-generated method stub
- return true;
- }
- public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
- float velocityY) {
- Log.e("kingfly", "kingfly e1 :"+e1.getX()+" e2 :"+e2.getX());
- Log.e("kingfly", "Kingfly velocityX :"+velocityX+" velocityY :"+velocityY);
- if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE
- && Math.abs(velocityX) > FLING_MIN_VELOCITY) {
- mFlipper.setInAnimation(inFromRightAnimation());
- mFlipper.setOutAnimation(outToLeftAnimation());
- mFlipper.showNext();
- } else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE
- && Math.abs(velocityX) > FLING_MIN_VELOCITY) {
- mFlipper.setInAnimation(inFromLeftAnimation());
- mFlipper.setOutAnimation(outToRightAnimation());
- mFlipper.showPrevious();
- }
- return false;
- }
- @Override
- public void onLongPress(MotionEvent arg0) {
- // TODO Auto-generated method stub
- }
- @Override
- public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2,
- float arg3) {
- // TODO Auto-generated method stub
- return false;
- }
- @Override
- public void onShowPress(MotionEvent arg0) {
- // TODO Auto-generated method stub
- }
- @Override
- public boolean onSingleTapUp(MotionEvent arg0) {
- // TODO Auto-generated method stub
- return false;
- }
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- Log.e("kingfly", "kingfly onTouch");
- switch(event.getAction()){
- case MotionEvent.ACTION_MOVE:
- v.setAnimation(new Animation() {
- });
- break;
- }
- return mGestureDetector.onTouchEvent(event);
- }
- @Override
- public void onAnimationEnd(Animation arg0) {
- // TODO Auto-generated method stub
- }
- @Override
- public void onAnimationRepeat(Animation arg0) {
- // TODO Auto-generated method stub
- }
- @Override
- public void onAnimationStart(Animation arg0) {
- // TODO Auto-generated method stub
- }
- }
- </span>
里面引用的布局文件switch_control_panel.xml
- <span style="font-size:18px;color:#006600;"><?xml version="1.0" encoding="utf-8"?>
- <LinearLayout
- xmlns:android="https://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/stat_switch_bg" >
- <ViewFlipper
- android:id="@+id/flipper"
- android:layout_below="@+id/CockpitLayout"
- android:layout_height="fill_parent"
- android:layout_width="fill_parent">
- <include android:id="@+id/firstlayout" layout="@layout/statusbarfirst"></include>
- <include android:id="@+id/secondlayout" layout="@layout/statusbarsecond"></include>
- </ViewFlipper>
- </LinearLayout>
- </span>
include里的两个都是布局文件,statusbarfirst.xml
- <span style="font-size:18px;color:#006600;"><?xml version="1.0" encoding="UTF-8"?>
- <LinearLayout
- xmlns:android="https://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content">
- <LinearLayout
- android:id="@+id/switch_wifi"
- android:layout_width="0dip"
- android:layout_weight="1"
- android:layout_height="wrap_content"
- android:clickable="true"
- android:focusable="true"
- android:orientation="vertical">
- <TextView
- android:id="@+id/switch_text_wifi"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- />
- </LinearLayout>
- <ImageView
- android:layout_width="2dip"
- android:layout_height="match_parent"
- android:background="@drawable/stat_switch_divider"
- />
- <LinearLayout
- android:id="@+id/switch_bluetooth"
- android:layout_width="0dip"
- android:layout_weight="1"
- android:layout_height="wrap_content"
- android:clickable="true"
- android:focusable="true"
- android:orientation="vertical">
- <ImageView
- android:id="@+id/switch_img_bluetooth"
- android:layout_width="wrap_content"
- android:layout_height="0dip"
- android:layout_weight="1"
- android:scaleType="center"
- android:layout_gravity="center_horizontal"
- android:background="@drawable/stat_switch_bluetooth_on"
- />
- <TextView
- android:id="@+id/switch_text_bluetooth"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:text="@string/switch_bluetooth_summary"
- />
- <ImageView
- android:id="@+id/switch_ind_bluetooth"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:scaleType="fitXY"
- android:layout_marginLeft="6dip"
- android:layout_marginRight="6dip"
- android:background="@drawable/stat_switch_ind_on"
- />
- </LinearLayout>
- </LinearLayout></span>
还有就是onTouch(返回false就不会覆盖掉onClick()事件了,所以这样既可以滑动也可以点击。
其他的功能可以依照上面的代码继续添加,也可以直接用LinearLayout等布局画出来,不需要ViewFlipper,当然还要添加几个小点来提示用户有多少个视图,这样用户体验更加。
最后更新:2017-04-02 17:09:26