#anyway the cake is great, it's so delicious and moist#

This commit is contained in:
Mariotaku Lee 2015-06-26 17:00:05 +08:00
parent 86f3584139
commit 011301fcd3
12 changed files with 554 additions and 56 deletions

View File

@ -0,0 +1,132 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.sprite.library;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Shader;
import android.view.Gravity;
/**
* Created by mariotaku on 15/6/26.
*/
public class AnimatedBitmapLayer implements Layer {
private final Bitmap mBitmap;
private final int mFrames;
private final boolean mVerticalFrames;
private final Point mPosition = new Point();
private final Point mFrameSize = new Point(), mScaledSize = new Point();
private final Paint mPaint = new Paint();
private Rect mSource = new Rect(), mDestination = new Rect(), mDisplayBounds = new Rect();
private Rect mTempDestination = new Rect();
private int mGravity;
private int mCurrentFrame;
private Shader.TileMode mTileModeX, mTileModeY;
public AnimatedBitmapLayer(Resources resources, int bitmapRes, int frames, boolean verticalFrames) {
this(BitmapFactory.decodeResource(resources, bitmapRes), frames, verticalFrames);
}
public AnimatedBitmapLayer(Bitmap bitmap, int frames, boolean verticalFrames) {
mBitmap = bitmap;
mFrames = frames;
mVerticalFrames = verticalFrames;
final int bitmapWidth = bitmap.getWidth(), bitmapHeight = bitmap.getHeight();
mFrameSize.x = verticalFrames ? bitmapWidth : bitmapWidth / frames;
mFrameSize.y = verticalFrames ? bitmapHeight / frames : bitmapHeight;
setGravity(Gravity.NO_GRAVITY);
setAntiAlias(true);
setScale(1);
}
@Override
public void onDraw(final Canvas canvas) {
final int frame = mCurrentFrame++;
if (mVerticalFrames) {
final int top = mFrameSize.y * frame;
mSource.set(0, top, mFrameSize.x, top + mFrameSize.y);
} else {
final int left = mFrameSize.x * frame;
mSource.set(left, 0, left + mFrameSize.x, mFrameSize.y);
}
final int destWidth = mTileModeX == Shader.TileMode.REPEAT ? mScaledSize.x : mDestination.width();
final int destHeight = mTileModeY == Shader.TileMode.REPEAT ? mScaledSize.y : mDestination.height();
for (int l = mDestination.left, r = mDestination.right; l < r; l += destWidth) {
for (int t = mDestination.top, b = mDestination.bottom; t < b; t += destHeight) {
mTempDestination.left = l;
mTempDestination.right = l + destWidth;
mTempDestination.top = t;
mTempDestination.bottom = t + destHeight;
canvas.drawBitmap(mBitmap, mSource, mTempDestination, mPaint);
}
}
if (mCurrentFrame >= mFrames) {
mCurrentFrame = 0;
}
}
@Override
public void onSizeChanged(final int width, final int height) {
mDisplayBounds.set(0, 0, width, height);
updateDestination();
}
public void setGravity(int gravity) {
mGravity = gravity;
updateDestination();
}
public void setAntiAlias(boolean aa) {
mPaint.setAntiAlias(aa);
}
public void setTileMode(Shader.TileMode tileModeX, Shader.TileMode tileModeY) {
mTileModeX = tileModeX;
mTileModeY = tileModeY;
}
/**
* Set position relative to gravity
*/
public void setPosition(int x, int y) {
mPosition.set(x, y);
updateDestination();
}
public void setScale(int scale) {
mScaledSize.x = mFrameSize.x * scale;
mScaledSize.y = mFrameSize.y * scale;
updateDestination();
}
private void updateDestination() {
Gravity.apply(mGravity, mScaledSize.x, mScaledSize.y, mDisplayBounds, mPosition.x, mPosition.y, mDestination);
}
}

View File

@ -0,0 +1,32 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.sprite.library;
import android.graphics.Canvas;
/**
* Created by mariotaku on 15/6/26.
*/
public interface Layer {
void onDraw(Canvas canvas);
void onSizeChanged(int width, int height);
}

View File

@ -0,0 +1,88 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.sprite.library;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by mariotaku on 15/6/26.
*/
public class LayeredCanvasView extends View {
private Layer[] mLayers;
private Runnable mAnimateCallback;
public LayeredCanvasView(final Context context) {
super(context);
}
public LayeredCanvasView(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public LayeredCanvasView(final Context context, final AttributeSet attrs, final int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setLayers(Layer[] layers, int fps) {
mLayers = layers;
if (layers == null || fps <= 0) {
removeCallbacks(mAnimateCallback);
return;
}
notifySizeChanged();
final long delay = 1000 / fps;
post(mAnimateCallback = new Runnable() {
@Override
public void run() {
invalidate();
postDelayed(this, delay);
}
});
}
public Layer[] getLayers() {
return mLayers;
}
@Override
protected void onDraw(final Canvas canvas) {
if (mLayers == null) return;
for (Layer layer : mLayers) {
layer.onDraw(canvas);
}
}
@Override
protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
notifySizeChanged();
}
private void notifySizeChanged() {
if (mLayers == null) return;
final int width = getWidth(), height = getHeight();
for (Layer layer : mLayers) {
layer.onSizeChanged(width, height);
}
}
}

View File

@ -76,6 +76,7 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
@ -149,6 +150,7 @@ import org.mariotaku.twidere.view.TintedStatusFrameLayout;
import org.mariotaku.twidere.view.TwidereToolbar;
import org.mariotaku.twidere.view.iface.IExtendedView.OnSizeChangedListener;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
@ -173,7 +175,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
private static final String TAB_TYPE_MEDIA = "media";
private static final String TAB_TYPE_FAVORITES = "favorites";
private MediaLoaderWrapper mProfileImageLoader;
private MediaLoaderWrapper mMediaLoader;
private UserColorNameManager mUserColorNameManager;
private SharedPreferencesWrapper mPreferences;
@ -219,6 +221,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
private int mUiColor;
private boolean mNameFirst;
private int mPreviousTabItemIsDark, mPreviousActionBarItemIsDark;
private boolean mHideBirthdayView;
private final LoaderCallbacks<SingleResponse<Relationship>> mFriendshipLoaderCallbacks = new LoaderCallbacks<SingleResponse<Relationship>>() {
@ -544,7 +547,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
mFollowersCount.setText(Utils.getLocalizedNumber(mLocale, user.followers_count));
mFriendsCount.setText(Utils.getLocalizedNumber(mLocale, user.friends_count));
mProfileImageLoader.displayProfileImage(mProfileImageView, Utils.getOriginalTwitterProfileImage(user.profile_image_url));
mMediaLoader.displayProfileImage(mProfileImageView, Utils.getOriginalTwitterProfileImage(user.profile_image_url));
if (userColor != 0) {
setUiColor(userColor);
} else {
@ -552,13 +555,21 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
}
final int defWidth = resources.getDisplayMetrics().widthPixels;
final int width = mBannerWidth > 0 ? mBannerWidth : defWidth;
mProfileImageLoader.displayProfileBanner(mProfileBannerView, user.profile_banner_url, width);
mMediaLoader.displayProfileBanner(mProfileBannerView, user.profile_banner_url, width);
final Relationship relationship = mRelationship;
if (relationship == null || relationship.getTargetUserId() != user.id) {
getFriendship();
}
activity.setTitle(manager.getDisplayName(user, mNameFirst, true));
Calendar cal = Calendar.getInstance();
final int currentMonth = cal.get(Calendar.MONTH), currentDay = cal.get(Calendar.DAY_OF_MONTH);
cal.setTimeInMillis(user.created_at);
if (cal.get(Calendar.MONTH) == currentMonth && cal.get(Calendar.DAY_OF_MONTH) == currentDay && !mHideBirthdayView) {
mProfileBirthdayBannerView.setVisibility(View.VISIBLE);
} else {
mProfileBirthdayBannerView.setVisibility(View.GONE);
}
updateTitleAlpha();
invalidateOptionsMenu();
updateSubtitle();
@ -701,7 +712,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
ThemeUtils.getUserThemeBackgroundAlpha(activity));
mActionBarShadowColor = 0xA0000000;
final TwidereApplication app = TwidereApplication.getInstance(activity);
mProfileImageLoader = app.getMediaLoaderWrapper();
mMediaLoader = app.getMediaLoaderWrapper();
final Bundle args = getArguments();
long accountId = -1, userId = -1;
String screenName = null;
@ -778,6 +789,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
mFollowersContainer.setOnClickListener(this);
mFriendsContainer.setOnClickListener(this);
mHeaderErrorIcon.setOnClickListener(this);
mProfileBirthdayBannerView.setOnClickListener(this);
mProfileBannerView.setOnSizeChangedListener(this);
mProfileBannerSpace.setOnTouchListener(this);
@ -1244,6 +1256,12 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
Utils.openProfileEditor(getActivity(), user.account_id);
break;
}
case R.id.profile_birthday_banner: {
mHideBirthdayView = true;
mProfileBirthdayBannerView.startAnimation(AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out));
mProfileBirthdayBannerView.setVisibility(View.GONE);
break;
}
}
}
@ -1304,6 +1322,9 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
@Override
public boolean onTouch(final View v, final MotionEvent event) {
if (mProfileBirthdayBannerView.getVisibility() == View.VISIBLE) {
return mProfileBirthdayBannerView.dispatchTouchEvent(event);
}
return mProfileBannerView.dispatchTouchEvent(event);
}

View File

@ -28,8 +28,7 @@ import com.db.chart.model.BarSet;
import com.db.chart.model.ChartSet;
import org.mariotaku.querybuilder.Expression;
import org.mariotaku.twidere.preference.NetworkUsageSummaryPreferences;
import org.mariotaku.twidere.provider.TwidereDataStore;
import org.mariotaku.twidere.provider.TwidereDataStore.NetworkUsages;
import org.mariotaku.twidere.util.MathUtils;
import java.util.ArrayList;
@ -40,33 +39,39 @@ import java.util.concurrent.TimeUnit;
* Created by mariotaku on 15/6/25.
*/
public class NetworkUsageInfo {
private final double totalSent;
private final double totalReceived;
private final ArrayList<ChartSet> chartData;
private final double dayMax;
private final double[][] chartUsage;
private final double totalSent, totalReceived;
private final double[] usageTotal;
private final double dayUsageMax;
private final int dayMin;
private final int dayMax;
public NetworkUsageInfo(ArrayList<ChartSet> chartData, double totalReceived, double totalSent, double dayMax) {
this.chartData = chartData;
public NetworkUsageInfo(double[][] chartUsage, double[] usageTotal, double totalReceived, double totalSent, double dayUsageMax, int dayMin, int dayMax) {
this.chartUsage = chartUsage;
this.usageTotal = usageTotal;
this.totalReceived = totalReceived;
this.totalSent = totalSent;
this.dayUsageMax = dayUsageMax;
this.dayMin = dayMin;
this.dayMax = dayMax;
}
public static NetworkUsageInfo get(Context context, Date start, Date end) {
public static NetworkUsageInfo get(Context context, Date start, Date end, int dayMin, int dayMax) {
final ContentResolver cr = context.getContentResolver();
final long startTime = TimeUnit.HOURS.convert(start.getTime(), TimeUnit.MILLISECONDS);
final long endTime = TimeUnit.HOURS.convert(end.getTime(), TimeUnit.MILLISECONDS);
final Expression where = Expression.and(Expression.greaterEquals(TwidereDataStore.NetworkUsages.TIME_IN_HOURS, startTime),
Expression.lesserThan(TwidereDataStore.NetworkUsages.TIME_IN_HOURS, endTime));
final Expression where = Expression.and(Expression.greaterEquals(NetworkUsages.TIME_IN_HOURS, startTime),
Expression.lesserThan(NetworkUsages.TIME_IN_HOURS, endTime));
final int days = (int) TimeUnit.DAYS.convert(endTime - startTime, TimeUnit.HOURS);
final Cursor c = cr.query(TwidereDataStore.NetworkUsages.CONTENT_URI, TwidereDataStore.NetworkUsages.COLUMNS,
where.getSQL(), null, TwidereDataStore.NetworkUsages.TIME_IN_HOURS);
final int idxDate = c.getColumnIndex(TwidereDataStore.NetworkUsages.TIME_IN_HOURS);
final int idxSent = c.getColumnIndex(TwidereDataStore.NetworkUsages.KILOBYTES_SENT);
final int idxReceived = c.getColumnIndex(TwidereDataStore.NetworkUsages.KILOBYTES_RECEIVED);
final int idxType = c.getColumnIndex(TwidereDataStore.NetworkUsages.REQUEST_TYPE);
final double[][] usageArray = new double[days][RequestType.values().length];
final Cursor c = cr.query(NetworkUsages.CONTENT_URI, NetworkUsages.COLUMNS,
where.getSQL(), null, NetworkUsages.TIME_IN_HOURS);
final int idxDate = c.getColumnIndex(NetworkUsages.TIME_IN_HOURS);
final int idxSent = c.getColumnIndex(NetworkUsages.KILOBYTES_SENT);
final int idxReceived = c.getColumnIndex(NetworkUsages.KILOBYTES_RECEIVED);
final int idxType = c.getColumnIndex(NetworkUsages.REQUEST_TYPE);
final double[][] chartUsage = new double[days][RequestType.values().length];
double totalReceived = 0, totalSent = 0;
final double[] usageTotal = new double[RequestType.values().length];
c.moveToFirst();
while (!c.isAfterLast()) {
final long hours = c.getLong(idxDate);
@ -74,9 +79,12 @@ public class NetworkUsageInfo {
final double sent = c.getDouble(idxSent);
final double received = c.getDouble(idxReceived);
final String type = c.getString(idxType);
usageArray[idx][RequestType.getValue(type)] += (sent + received);
final double hourTypeTotal = sent + received;
final int typeIdx = RequestType.getValue(type);
chartUsage[idx][typeIdx] += hourTypeTotal;
totalReceived += received;
totalSent += sent;
usageTotal[typeIdx] += hourTypeTotal;
c.moveToNext();
}
c.close();
@ -85,14 +93,14 @@ public class NetworkUsageInfo {
final BarSet mediaSet = new BarSet();
final BarSet usageStatisticsSet = new BarSet();
double dayMax = 0;
double dayUsageMax = 0;
for (int i = 0; i < days; i++) {
String day = String.valueOf(i + 1);
final double[] dayUsage = usageArray[i];
final double[] dayUsage = chartUsage[i];
apiSet.addBar(day, (float) dayUsage[RequestType.API.getValue()]);
mediaSet.addBar(day, (float) dayUsage[RequestType.MEDIA.getValue()]);
usageStatisticsSet.addBar(day, (float) dayUsage[RequestType.USAGE_STATISTICS.getValue()]);
dayMax = Math.max(dayMax, MathUtils.sum(dayUsage));
dayUsageMax = Math.max(dayUsageMax, MathUtils.sum(dayUsage));
}
apiSet.setColor(Color.RED);
@ -103,22 +111,34 @@ public class NetworkUsageInfo {
data.add(apiSet);
data.add(mediaSet);
data.add(usageStatisticsSet);
return new NetworkUsageInfo(data, totalReceived, totalSent, dayMax);
return new NetworkUsageInfo(chartUsage, usageTotal, totalReceived, totalSent, dayUsageMax, dayMin, dayMax);
}
public double getDayMax() {
public int getDayMax() {
return dayMax;
}
public int getDayMin() {
return dayMin;
}
public double getDayUsageMax() {
return dayUsageMax;
}
public double getTotalSent() {
return totalSent;
}
public double[] getUsageTotal() {
return usageTotal;
}
public double getTotalReceived() {
return totalReceived;
}
public ArrayList<ChartSet> getChartData() {
return chartData;
public double[][] getChartUsage() {
return chartUsage;
}
}

View File

@ -20,6 +20,8 @@
package org.mariotaku.twidere.preference;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.preference.Preference;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
@ -27,15 +29,17 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.db.chart.model.BarSet;
import com.db.chart.model.ChartSet;
import com.db.chart.view.AxisController;
import com.db.chart.view.StackBarChartView;
import com.desmond.asyncmanager.AsyncManager;
import com.desmond.asyncmanager.TaskRunnable;
import org.apache.commons.lang3.tuple.Triple;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.model.NetworkUsageInfo;
import org.mariotaku.twidere.model.RequestType;
import org.mariotaku.twidere.util.MathUtils;
import org.mariotaku.twidere.util.Utils;
import java.util.ArrayList;
@ -50,6 +54,8 @@ public class NetworkUsageSummaryPreferences extends Preference {
private StackBarChartView mChartView;
private NetworkUsageInfo mUsage;
private TextView mTotalUsage;
private TextView mDayUsageMax;
private TextView mDayMin, mDayMid, mDayMax;
public NetworkUsageSummaryPreferences(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
@ -70,22 +76,37 @@ public class NetworkUsageSummaryPreferences extends Preference {
final View view = super.onCreateView(parent);
mChartView = (StackBarChartView) view.findViewById(R.id.chart);
mTotalUsage = (TextView) view.findViewById(R.id.total_usage);
mChartView.setXLabels(AxisController.LabelPosition.NONE);
mDayUsageMax = (TextView) view.findViewById(R.id.day_usage_max);
mDayMin = (TextView) view.findViewById(R.id.day_min);
mDayMid = (TextView) view.findViewById(R.id.day_mid);
mDayMax = (TextView) view.findViewById(R.id.day_max);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(0x20000000);
mChartView.setYLabels(AxisController.LabelPosition.NONE);
mChartView.setXLabels(AxisController.LabelPosition.NONE);
return view;
}
private void getUsageInfo() {
final Calendar now = Calendar.getInstance();
final Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, Calendar.getInstance().getActualMinimum(Calendar.DAY_OF_MONTH));
cal.clear();
cal.set(Calendar.YEAR, now.get(Calendar.YEAR));
cal.set(Calendar.MONTH, now.get(Calendar.MONTH));
final int dayMin = now.getActualMinimum(Calendar.DAY_OF_MONTH);
final int dayMax = now.getActualMaximum(Calendar.DAY_OF_MONTH);
cal.set(Calendar.DAY_OF_MONTH, dayMin);
cal.setTimeZone(now.getTimeZone());
final Date start = cal.getTime();
cal.set(Calendar.DAY_OF_MONTH, Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH));
cal.set(Calendar.DAY_OF_MONTH, dayMax);
cal.add(Calendar.DATE, 1);
final Date end = cal.getTime();
TaskRunnable<Triple<Context, Date, Date>, NetworkUsageInfo, NetworkUsageSummaryPreferences> task;
task = new TaskRunnable<Triple<Context, Date, Date>, NetworkUsageInfo, NetworkUsageSummaryPreferences>() {
final TaskRunnable<Object[], NetworkUsageInfo, NetworkUsageSummaryPreferences> task;
task = new TaskRunnable<Object[], NetworkUsageInfo, NetworkUsageSummaryPreferences>() {
@Override
public NetworkUsageInfo doLongOperation(Triple<Context, Date, Date> params) throws InterruptedException {
return NetworkUsageInfo.get(params.getLeft(), params.getMiddle(), params.getRight());
public NetworkUsageInfo doLongOperation(Object[] params) throws InterruptedException {
return NetworkUsageInfo.get((Context) params[0], (Date) params[1], (Date) params[2], dayMin, dayMax);
}
@Override
@ -94,7 +115,7 @@ public class NetworkUsageSummaryPreferences extends Preference {
}
};
task.setResultHandler(this);
task.setParams(Triple.of(getContext(), start, end));
task.setParams(new Object[]{getContext(), start, end});
AsyncManager.runBackgroundTask(task);
}
@ -108,12 +129,38 @@ public class NetworkUsageSummaryPreferences extends Preference {
super.onBindView(view);
final NetworkUsageInfo usage = mUsage;
if (usage == null) return;
final ArrayList<ChartSet> chartData = usage.getChartData();
if (mChartView.getData() != chartData) {
mChartView.addData(chartData);
mChartView.show();
final double[][] chartUsage = usage.getChartUsage();
final int days = chartUsage.length;
final BarSet apiSet = new BarSet();
final BarSet mediaSet = new BarSet();
final BarSet usageStatisticsSet = new BarSet();
double dayUsageMax = 0;
for (int i = 0; i < days; i++) {
String day = String.valueOf(i + 1);
final double[] dayUsage = chartUsage[i];
apiSet.addBar(day, (float) dayUsage[RequestType.API.getValue()]);
mediaSet.addBar(day, (float) dayUsage[RequestType.MEDIA.getValue()]);
usageStatisticsSet.addBar(day, (float) dayUsage[RequestType.USAGE_STATISTICS.getValue()]);
dayUsageMax = Math.max(dayUsageMax, MathUtils.sum(dayUsage));
}
apiSet.setColor(Color.RED);
mediaSet.setColor(Color.GREEN);
usageStatisticsSet.setColor(Color.BLUE);
final ArrayList<ChartSet> data = new ArrayList<>();
data.add(apiSet);
data.add(mediaSet);
data.add(usageStatisticsSet);
mChartView.addData(data);
mChartView.show();
mTotalUsage.setText(Utils.calculateProperSize((usage.getTotalSent() + usage.getTotalReceived()) * 1024));
mDayUsageMax.setText(Utils.calculateProperSize((usage.getDayUsageMax()) * 1024));
mDayMin.setText(String.valueOf(usage.getDayMin()));
mDayMid.setText(String.valueOf((usage.getDayMin() + usage.getDayMax()) / 2));
mDayMax.setText(String.valueOf(usage.getDayMax()));
}
}

View File

@ -0,0 +1,90 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.view;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.Shader;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.Gravity;
import org.mariotaku.sprite.library.AnimatedBitmapLayer;
import org.mariotaku.sprite.library.Layer;
import org.mariotaku.sprite.library.LayeredCanvasView;
import org.mariotaku.twidere.R;
import org.mariotaku.twidere.util.Utils;
/**
* Created by mariotaku on 15/6/26.
*/
public final class BirthdayView extends LayeredCanvasView {
public BirthdayView(final Context context) {
super(context);
init();
}
public BirthdayView(final Context context, final AttributeSet attrs) {
super(context, attrs);
init();
}
public BirthdayView(final Context context, final AttributeSet attrs, final int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
setBackgroundColor(0xFF203040);
final AnimatedBitmapLayer tableLayer = new AnimatedBitmapLayer(getResources(), R.drawable.sprite_birthday_table_frames, 4, true);
final AnimatedBitmapLayer cakeLayer = new AnimatedBitmapLayer(getResources(), R.drawable.sprite_birthday_cake_frames, 4, false);
final AnimatedBitmapLayer lightStripLayer = new AnimatedBitmapLayer(getResources(), R.drawable.sprite_birthday_light_strip_frames, 4, true);
tableLayer.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);
tableLayer.setAntiAlias(false);
cakeLayer.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);
cakeLayer.setAntiAlias(false);
lightStripLayer.setGravity(Gravity.TOP | Gravity.FILL_HORIZONTAL);
lightStripLayer.setAntiAlias(false);
lightStripLayer.setTileMode(Shader.TileMode.REPEAT, null);
super.setLayers(new Layer[]{tableLayer, cakeLayer, lightStripLayer}, 1);
}
@Override
public void setLayers(final Layer[] layers, final int fps) {
// No-op
}
@Override
protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
final Layer[] layers = getLayers();
((AnimatedBitmapLayer) layers[0]).setScale(Math.max(1, w / 160));
((AnimatedBitmapLayer) layers[1]).setScale(Math.max(1, w / 160));
((AnimatedBitmapLayer) layers[2]).setScale(Math.max(1, w / 160));
}
@Override
protected boolean fitSystemWindows(@NonNull Rect insets) {
final int stripTop = Utils.getInsetsTopWithoutActionBarHeight(getContext(), insets.top);
final Layer[] layers = getLayers();
((AnimatedBitmapLayer) layers[2]).setPosition(0, stripTop);
return super.fitSystemWindows(insets);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
<?xml version="1.0" encoding="utf-8"?><!--
~ Twidere - Twitter client for Android
~
~ Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
@ -18,8 +17,7 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -39,15 +37,19 @@
android:id="@+id/profile_banner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"/>
android:scaleType="centerCrop" />
<FrameLayout
android:id="@+id/profile_birthday_banner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/profile_banner"
android:layout_alignTop="@+id/profile_banner">
android:layout_alignTop="@+id/profile_banner"
android:visibility="gone">
<org.mariotaku.twidere.view.BirthdayView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</RelativeLayout>
@ -56,7 +58,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
app:hdl_contentLayout="@layout/fragment_content_pages"
app:hdl_headerLayout="@layout/header_user"/>
app:hdl_headerLayout="@layout/header_user" />
</org.mariotaku.twidere.view.ExtendedFrameLayout>
</FrameLayout>

View File

@ -22,19 +22,85 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:orientation="vertical"
android:padding="@dimen/element_spacing_normal">
<TextView
android:id="@+id/total_usage"
android:layout_marginTop="@dimen/element_spacing_large"
android:layout_marginBottom="@dimen/element_spacing_large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:textAppearanceLarge"
android:textColor="?android:textColorPrimary"
tools:text="124.50mb" />
<com.db.chart.view.StackBarChartView
android:id="@+id/chart"
<GridLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_below="@+id/total_usage"
app:chart_barSpacing="2dp" />
android:layout_height="wrap_content"
android:layout_below="@+id/total_usage">
<TextView
android:id="@+id/day_usage_max"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:layout_row="0"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorSecondary"
tools:text="10mb" />
<com.db.chart.view.StackBarChartView
android:id="@+id/chart"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:layout_column="1"
android:layout_gravity="fill"
android:layout_row="0"
app:chart_barSpacing="2dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="1"
android:layout_gravity="fill"
android:layout_row="1"
android:orientation="horizontal">
<TextView
android:id="@+id/day_min"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="left"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorSecondary"
tools:ignore="RtlHardcoded"
tools:text="1" />
<TextView
android:id="@+id/day_mid"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_horizontal"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorSecondary"
tools:text="15" />
<TextView
android:id="@+id/day_max"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:textAppearance="?android:textAppearanceSmall"
android:textColor="?android:textColorSecondary"
tools:ignore="RtlHardcoded"
tools:text="30" />
</LinearLayout>
</GridLayout>
</RelativeLayout>