可滑動的係統狀態欄控製麵板(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