Android-快速设置-Quick settings tile

Android7.0的Quick settings tile

在Android7.0之后,任何程序都可以设置屏幕顶部下拉的设置了,为应用的快捷设置提供了极大的方便。

什么是优秀的快速设置

什么设置适合作为Quick settings tile,有两个关键要素:紧迫性高频

大家注意,因为这是一个常驻的设置,所以并不适合那些一次性的设置。

添加TileServuce

咱们首先需要定义一个继承TileService的服务,TileService是一个特殊的服务,在7.0系统中会自动识别并开启,这也就解决了低版本适配的问题。然后和其他的自定义服务一样,需要在manifest中配置:

<service
  android:name=".AwesomeTileService"
  android:icon="@drawable/ic_tile_default"
  android:label="快速设置"
  android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
  <intent-filter>
    <action
      android:name="android.service.quicksettings.action.QS_TILE"/>
  intent-filter>
service>

这里咱们需要配置Tile的名字,icon。以及对应的permission.
Tile多余18个字符会被截断,icon需要使用一张透明背景的白色矢量图,图片的着色是由当前系统决定的。

Tile生命周期

我们可以实现TileService的几个生命周期函数:

public class QuickSettingService extends TileService{
    //当用户从Edit栏添加到快速设置中调用
    @Override
    public void onTileAdded() {
        Log.d(LOG_TAG, "onTileAdded");
    }
    //当用户从快速设置栏中移除的时候调用
    @Override
    public void onTileRemoved() {
        Log.d(LOG_TAG, "onTileRemoved");
    }
    // 点击的时候
    @Override
    public void onClick() {
        Log.d(LOG_TAG, "onClick");
    }
    // 打开下拉菜单的时候调用,当快速设置按钮并没有在编辑栏拖到设置栏中不会调用
    //在TleAdded之后会调用一次
    @Override
    public void onStartListening () {
        Log.d(LOG_TAG, "onStartListening");
    }
    // 关闭下拉菜单的时候调用,当快速设置按钮并没有在编辑栏拖到设置栏中不会调用
    // 在onTileRemoved移除之前也会调用移除
    @Override
    public void onStopListening () {
        Log.d(LOG_TAG, "onStopListening");
    }
}

主动调用

如果咱们需要在非点击情况下改变Tile的状态,可以将Tile的Mode改为主动模式:

...
  "android.service.quicksettings.ACTIVE_TILE"
    android:value="true" />

可以在程序中的其他地方调用TileService.requestListeningState() 来触发 onStartListening函数

更新UI

如下代码:

public class QuickSettingService extends TileService {
    private final String LOG_TAG = "QuickSettingService";

    //当用户从Edit栏添加到快速设定中调用
    @Override
    public void onTileAdded() {
        Log.d(LOG_TAG, "onTileAdded");
    }

    //当用户从快速设定栏中移除的时候调用
    @Override
    public void onTileRemoved() {
        Log.d(LOG_TAG, "onTileRemoved");
    }

    // 点击的时候
    @Override
    public void onClick() {
        int state = getQsTile().getState();
        Log.d(LOG_TAG, "onClick state = " + Integer.toString(getQsTile().getState()));
        Icon icon;
        if (state == Tile.STATE_INACTIVE) {
            icon = Icon.createWithResource(getApplicationContext(), R.drawable.activeon);
            getQsTile().setState(Tile.STATE_INACTIVE);// 更改成非活跃状态
        } else {
            icon = Icon.createWithResource(getApplicationContext(), R.drawable.add_photo);
            getQsTile().setState(Tile.STATE_ACTIVE);//更改成活跃状态
        }

        getQsTile().setIcon(icon);//设置图标
        getQsTile().updateTile();//更新Tile
    }

    // 打开下拉菜单的时候调用,当快速设置按钮并没有在编辑栏拖到设置栏中不会调用
    //在TleAdded之后会调用一次
    @Override
    public void onStartListening() {
        Log.d(LOG_TAG, "onStartListening");
    }

    // 关闭下拉菜单的时候调用,当快速设置按钮并没有在编辑栏拖到设置栏中不会调用
    // 在onTileRemoved移除之前也会调用移除
    @Override
    public void onStopListening() {
        Log.d(LOG_TAG, "onStopListening");
    }
}

我们可以通过getQsTile来获得Tile对象,通过getState() 来获得Tile当前状态。
- STATE_ACTIVE 开启状态
- STATE_INACTIVE 关闭状态
- STATE_UNAVAILABLE 非可点击状态

最后必须调用updateTile() 来触发刷新。

事件处理

OnClick() 中,我们可以在UI线程上处理业务逻辑,耗时操作请交给另一个线程或IntentService执行。

其中我们可以开启Dialog或通过startActivityAndCollapse()开启一个Actvitiy

但是在锁屏,也就是isLocked()返回true时,将不能打开Dialog,而Activity则需要增加FLAG_SHOW_WHEN_LOCKED这个Flag。
我们也可以使用unlockAndRun(Runnable) 来异步设置用户解锁后的工作。

用户长按Tile会默认打开app的app info页面,我们可以给Activity加上ACTION_QS_TILE_PREFERENCES 来重载此行为。

参考文献

你可能感兴趣的:(UI)