QSCustomizer.java revision b53b6c566f8e4754406cd1c3fddfa16a27515a7e
1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package com.android.systemui.qs.customize; 17 18import android.animation.Animator; 19import android.animation.Animator.AnimatorListener; 20import android.animation.AnimatorListenerAdapter; 21import android.content.Context; 22import android.support.v7.widget.DefaultItemAnimator; 23import android.support.v7.widget.GridLayoutManager; 24import android.support.v7.widget.RecyclerView; 25import android.util.AttributeSet; 26import android.util.TypedValue; 27import android.view.ContextThemeWrapper; 28import android.view.Menu; 29import android.view.MenuItem; 30import android.view.View; 31import android.widget.LinearLayout; 32import android.widget.Toolbar; 33import android.widget.Toolbar.OnMenuItemClickListener; 34import com.android.systemui.R; 35import com.android.systemui.qs.QSDetailClipper; 36import com.android.systemui.qs.QSTile; 37import com.android.systemui.statusbar.phone.PhoneStatusBar; 38import com.android.systemui.statusbar.phone.QSTileHost; 39 40import java.util.ArrayList; 41import java.util.List; 42 43/** 44 * Allows full-screen customization of QS, through show() and hide(). 45 * 46 * This adds itself to the status bar window, so it can appear on top of quick settings and 47 * *someday* do fancy animations to get into/out of it. 48 */ 49public class QSCustomizer extends LinearLayout implements OnMenuItemClickListener { 50 51 private static final int MENU_RESET = Menu.FIRST; 52 53 private final QSDetailClipper mClipper; 54 55 private PhoneStatusBar mPhoneStatusBar; 56 57 private boolean isShown; 58 private QSTileHost mHost; 59 private RecyclerView mRecyclerView; 60 private TileAdapter mTileAdapter; 61 private Toolbar mToolbar; 62 63 public QSCustomizer(Context context, AttributeSet attrs) { 64 super(new ContextThemeWrapper(context, android.R.style.Theme_Material), attrs); 65 mClipper = new QSDetailClipper(this); 66 } 67 68 public void setHost(QSTileHost host) { 69 mHost = host; 70 mPhoneStatusBar = host.getPhoneStatusBar(); 71 } 72 73 @Override 74 protected void onFinishInflate() { 75 super.onFinishInflate(); 76 mToolbar = (Toolbar) findViewById(com.android.internal.R.id.action_bar); 77 TypedValue value = new TypedValue(); 78 mContext.getTheme().resolveAttribute(android.R.attr.homeAsUpIndicator, value, true); 79 mToolbar.setNavigationIcon( 80 getResources().getDrawable(R.drawable.ic_close_white, mContext.getTheme())); 81 mToolbar.setNavigationOnClickListener(new OnClickListener() { 82 @Override 83 public void onClick(View v) { 84 save(); 85 hide((int) v.getX() + v.getWidth() / 2, (int) v.getY() + v.getHeight() / 2); 86 } 87 }); 88 mToolbar.setOnMenuItemClickListener(this); 89 mToolbar.getMenu().add(Menu.NONE, MENU_RESET, 0, 90 mContext.getString(com.android.internal.R.string.reset)); 91 92 mRecyclerView = (RecyclerView) findViewById(android.R.id.list); 93 mTileAdapter = new TileAdapter(getContext()); 94 mRecyclerView.setAdapter(mTileAdapter); 95 mTileAdapter.getItemTouchHelper().attachToRecyclerView(mRecyclerView); 96 GridLayoutManager layout = new GridLayoutManager(getContext(), 3); 97 layout.setSpanSizeLookup(mTileAdapter.getSizeLookup()); 98 mRecyclerView.setLayoutManager(layout); 99 mRecyclerView.addItemDecoration(mTileAdapter.getItemDecoration()); 100 DefaultItemAnimator animator = new DefaultItemAnimator(); 101 animator.setMoveDuration(TileAdapter.MOVE_DURATION); 102 mRecyclerView.setItemAnimator(animator); 103 } 104 105 public void show(int x, int y) { 106 if (!isShown) { 107 isShown = true; 108 mPhoneStatusBar.getStatusBarWindow().addView(this); 109 setTileSpecs(); 110 mClipper.animateCircularClip(x, y, true, null); 111 new TileQueryHelper(mContext, mHost).setListener(mTileAdapter); 112 } 113 } 114 115 public void hide(int x, int y) { 116 if (isShown) { 117 isShown = false; 118 mClipper.animateCircularClip(x, y, false, mCollapseAnimationListener); 119 } 120 } 121 122 public boolean isCustomizing() { 123 return isShown; 124 } 125 126 @Override 127 public boolean onMenuItemClick(MenuItem item) { 128 switch (item.getItemId()) { 129 case MENU_RESET: 130 reset(); 131 break; 132 } 133 return false; 134 } 135 136 private void reset() { 137 ArrayList<String> tiles = new ArrayList<>(); 138 String defTiles = mContext.getString(R.string.quick_settings_tiles_default); 139 for (String tile : defTiles.split(",")) { 140 tiles.add(tile); 141 } 142 mTileAdapter.setTileSpecs(tiles); 143 } 144 145 private void setTileSpecs() { 146 List<String> specs = new ArrayList<>(); 147 for (QSTile tile : mHost.getTiles()) { 148 specs.add(tile.getTileSpec()); 149 } 150 mTileAdapter.setTileSpecs(specs); 151 } 152 153 private void save() { 154 mTileAdapter.saveSpecs(mHost); 155 } 156 157 private final AnimatorListener mCollapseAnimationListener = new AnimatorListenerAdapter() { 158 @Override 159 public void onAnimationEnd(Animator animation) { 160 if (!isShown) { 161 mPhoneStatusBar.getStatusBarWindow().removeView(QSCustomizer.this); 162 } 163 } 164 165 @Override 166 public void onAnimationCancel(Animator animation) { 167 if (!isShown) { 168 mPhoneStatusBar.getStatusBarWindow().removeView(QSCustomizer.this); 169 } 170 } 171 }; 172} 173