Checkpoint of data usage UI, graphs and lists.
Chart of network usage over time, with draggable "sweep" bars for inspection region and warning/limits. Talks with NetworkStatsService for live data, and updates list of application usage as inspection region changes. Change-Id: I2a406e6776daf7d74143c07ec683c10fe711c277
This commit is contained in:
165
src/com/android/settings/widget/ChartSweepView.java
Normal file
165
src/com/android/settings/widget/ChartSweepView.java
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
/**
|
||||
* Sweep across a {@link ChartView} at a specific {@link ChartAxis} value, which
|
||||
* a user can drag.
|
||||
*/
|
||||
public class ChartSweepView extends View {
|
||||
|
||||
private final Paint mPaintSweep;
|
||||
private final Paint mPaintShadow;
|
||||
|
||||
private final ChartAxis mAxis;
|
||||
private long mValue;
|
||||
|
||||
public interface OnSweepListener {
|
||||
public void onSweep(ChartSweepView sweep, boolean sweepDone);
|
||||
}
|
||||
|
||||
private OnSweepListener mListener;
|
||||
|
||||
private boolean mHorizontal;
|
||||
private MotionEvent mTracking;
|
||||
|
||||
public ChartSweepView(Context context, ChartAxis axis, long value, int color) {
|
||||
super(context);
|
||||
|
||||
mAxis = Preconditions.checkNotNull(axis, "missing axis");
|
||||
mValue = value;
|
||||
|
||||
mPaintSweep = new Paint();
|
||||
mPaintSweep.setColor(color);
|
||||
mPaintSweep.setStrokeWidth(3.0f);
|
||||
mPaintSweep.setStyle(Style.FILL_AND_STROKE);
|
||||
mPaintSweep.setAntiAlias(true);
|
||||
|
||||
mPaintShadow = new Paint();
|
||||
mPaintShadow.setColor(Color.BLACK);
|
||||
mPaintShadow.setStrokeWidth(6.0f);
|
||||
mPaintShadow.setStyle(Style.FILL_AND_STROKE);
|
||||
mPaintShadow.setAntiAlias(true);
|
||||
|
||||
}
|
||||
|
||||
public void addOnSweepListener(OnSweepListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
private void dispatchOnSweep(boolean sweepDone) {
|
||||
if (mListener != null) {
|
||||
mListener.onSweep(this, sweepDone);
|
||||
}
|
||||
}
|
||||
|
||||
public ChartAxis getAxis() {
|
||||
return mAxis;
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
return mValue;
|
||||
}
|
||||
|
||||
public float getPoint() {
|
||||
return mAxis.convertToPoint(mValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
final View parent = (View) getParent();
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
mTracking = event.copy();
|
||||
return true;
|
||||
}
|
||||
case MotionEvent.ACTION_MOVE: {
|
||||
if (mHorizontal) {
|
||||
setTranslationY(event.getRawY() - mTracking.getRawY());
|
||||
final float point = (getTop() + getTranslationY() + (getHeight() / 2))
|
||||
- parent.getPaddingTop();
|
||||
mValue = mAxis.convertToValue(point);
|
||||
dispatchOnSweep(false);
|
||||
} else {
|
||||
setTranslationX(event.getRawX() - mTracking.getRawX());
|
||||
final float point = (getLeft() + getTranslationX() + (getWidth() / 2))
|
||||
- parent.getPaddingLeft();
|
||||
mValue = mAxis.convertToValue(point);
|
||||
dispatchOnSweep(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case MotionEvent.ACTION_UP: {
|
||||
mTracking = null;
|
||||
setTranslationX(0);
|
||||
setTranslationY(0);
|
||||
requestLayout();
|
||||
dispatchOnSweep(true);
|
||||
return true;
|
||||
}
|
||||
default: {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
// need at least 50px in each direction for grippies
|
||||
// TODO: provide this value through params
|
||||
setMeasuredDimension(50, 50);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
|
||||
// draw line across larger dimension
|
||||
final int width = getWidth();
|
||||
final int height = getHeight();
|
||||
|
||||
mHorizontal = width > height;
|
||||
|
||||
if (mHorizontal) {
|
||||
final int centerY = height / 2;
|
||||
final int endX = width - height;
|
||||
|
||||
canvas.drawLine(0, centerY, endX, centerY, mPaintShadow);
|
||||
canvas.drawLine(0, centerY, endX, centerY, mPaintSweep);
|
||||
canvas.drawCircle(endX, centerY, 4.0f, mPaintShadow);
|
||||
canvas.drawCircle(endX, centerY, 4.0f, mPaintSweep);
|
||||
} else {
|
||||
final int centerX = width / 2;
|
||||
final int endY = height - width;
|
||||
|
||||
canvas.drawLine(centerX, 0, centerX, endY, mPaintShadow);
|
||||
canvas.drawLine(centerX, 0, centerX, endY, mPaintSweep);
|
||||
canvas.drawCircle(centerX, endY, 4.0f, mPaintShadow);
|
||||
canvas.drawCircle(centerX, endY, 4.0f, mPaintSweep);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user