#anyway the cake is great, it's so delicious and moist#
This commit is contained in:
parent
86f3584139
commit
011301fcd3
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 |
|
@ -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>
|
|
@ -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>
|
Loading…
Reference in New Issue