A lot of fixes and small changes

This commit is contained in:
Karim Abou Zeid 2015-05-29 21:24:11 +02:00
commit 865f72e5bb
33 changed files with 360 additions and 479 deletions

View file

@ -204,9 +204,9 @@ public class AlbumAdapter extends AbsMultiSelectAdapter<AlbumAdapter.ViewHolder,
public void onGenerated(Palette palette) {
final Palette.Swatch vibrantSwatch = palette.getVibrantSwatch();
if (vibrantSwatch != null) {
title.setTextColor(vibrantSwatch.getTitleTextColor());
artist.setTextColor(vibrantSwatch.getTitleTextColor());
ViewUtil.animateViewColor(footer, DialogUtils.resolveColor(activity, R.attr.default_bar_color), vibrantSwatch.getRgb());
title.setTextColor(Util.getColorWithoutAlpha(vibrantSwatch.getTitleTextColor()));
artist.setTextColor(Util.getColorWithoutAlpha(vibrantSwatch.getTitleTextColor()));
ViewUtil.animateViewColor(footer, footer.getDrawingCacheBackgroundColor(), vibrantSwatch.getRgb());
} else {
paletteBlackAndWhite(title, artist, footer);
}
@ -218,8 +218,8 @@ public class AlbumAdapter extends AbsMultiSelectAdapter<AlbumAdapter.ViewHolder,
}
private void paletteBlackAndWhite(final TextView title, final TextView artist, final View footer) {
title.setTextColor(DialogUtils.resolveColor(activity, R.attr.title_text_color));
artist.setTextColor(DialogUtils.resolveColor(activity, R.attr.caption_text_color));
title.setTextColor(Util.getColorWithoutAlpha(DialogUtils.resolveColor(activity, R.attr.title_text_color)));
artist.setTextColor(Util.getColorWithoutAlpha(DialogUtils.resolveColor(activity, R.attr.caption_text_color)));
int defaultBarColor = DialogUtils.resolveColor(activity, R.attr.default_bar_color);
ViewUtil.animateViewColor(footer, defaultBarColor, defaultBarColor);
}

View file

@ -80,7 +80,7 @@ public class ColorChooserDialog extends DialogFragment implements View.OnClickLi
if (getArguments().getInt("title", 0) == R.string.primary_color) {
getArguments().putInt("preselect", getResources().getColor(R.color.indigo_500));
} else if (getArguments().getInt("title", 0) == R.string.accent_color) {
getArguments().putInt("preselect", getResources().getColor(R.color.pink_500));
getArguments().putInt("preselect", getResources().getColor(R.color.pink_A200));
}
invalidateGrid();
}

View file

@ -362,6 +362,11 @@ public class DragSortRecycler extends RecyclerView.ItemDecoration implements Rec
rv.invalidateItemDecorations();// Redraw
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
private void setIsDragging(final boolean dragging) {
if (dragging != isDragging) {
isDragging = dragging;

View file

@ -3,9 +3,9 @@ package com.kabouzeid.gramophone.ui.activities;
import android.animation.Animator;
import android.annotation.TargetApi;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.os.Build;
import android.os.Bundle;
@ -16,10 +16,11 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
@ -27,7 +28,6 @@ import com.afollestad.materialdialogs.ThemeSingleton;
import com.afollestad.materialdialogs.util.DialogUtils;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.dialogs.AddToPlaylistDialog;
import com.kabouzeid.gramophone.dialogs.ColorChooserDialog;
import com.kabouzeid.gramophone.dialogs.SongDetailDialog;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.helper.bitmapblur.StackBlurManager;
@ -44,7 +44,7 @@ import com.kabouzeid.gramophone.util.NavigationUtil;
import com.kabouzeid.gramophone.util.PreferenceUtils;
import com.kabouzeid.gramophone.util.Util;
import com.kabouzeid.gramophone.util.ViewUtil;
import com.nineoldandroids.view.ViewPropertyAnimator;
import com.kabouzeid.gramophone.views.SquareIfPlaceImageView;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.FailReason;
@ -55,18 +55,16 @@ import java.io.File;
public class MusicControllerActivity extends AbsFabActivity {
public static final String TAG = MusicControllerActivity.class.getSimpleName();
private static final int DEFAULT_DELAY = 350;
private static final int DEFAULT_ANIMATION_TIME = 1000;
private static final int COLOR_TRANSITION_TIME = 400;
private Song song;
private ImageView albumArt;
private SquareIfPlaceImageView albumArt;
private ImageView albumArtBackground;
private TextView songTitle;
private TextView songArtist;
private TextView currentSongProgress;
private TextView totalSongDuration;
private View footer;
private View progressContainer;
private SeekBar progressSlider;
private ImageButton nextButton;
private ImageButton prevButton;
@ -75,8 +73,12 @@ public class MusicControllerActivity extends AbsFabActivity {
private View mediaControllerContainer;
private Toolbar toolbar;
private int lastFooterColor = -1;
private int lastTextColor = -2;
private boolean killThreads = false;
private boolean opaqueToolBar = PreferenceUtils.getInstance(this).opaqueToolbarNowPlaying();
private boolean forceSquareAlbumArt = PreferenceUtils.getInstance(this).forceAlbumArtSquared();
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -91,6 +93,9 @@ public class MusicControllerActivity extends AbsFabActivity {
setUpMusicControllers();
albumArt.forceSquare(forceSquareAlbumArt);
setToolbarOpaque(opaqueToolBar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(null);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
@ -113,8 +118,6 @@ public class MusicControllerActivity extends AbsFabActivity {
animator.setDuration(1000);
animator.start();
int i = footer.getHeight();
mediaControllerContainer.setVisibility(View.VISIBLE);
}
});
@ -143,11 +146,11 @@ public class MusicControllerActivity extends AbsFabActivity {
}
private void moveSeekBarIntoPlace() {
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) progressSlider.getLayoutParams();
progressSlider.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
final int seekBarMarginLeftRight = getResources().getDimensionPixelSize(R.dimen.seek_bar_margin_left_right);
lp.setMargins(seekBarMarginLeftRight, getResources().getDimensionPixelSize(R.dimen.progress_container_height) - (progressSlider.getMeasuredHeight() / 2), seekBarMarginLeftRight, 0);
progressSlider.setLayoutParams(lp);
// RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) progressSlider.getLayoutParams();
// progressSlider.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
// final int seekBarMarginLeftRight = getResources().getDimensionPixelSize(R.dimen.seek_bar_margin_left_right);
// lp.setMargins(seekBarMarginLeftRight, 0, seekBarMarginLeftRight, -(progressSlider.getMeasuredHeight() / 2));
// progressSlider.setLayoutParams(lp);
}
private void initViews() {
@ -155,7 +158,7 @@ public class MusicControllerActivity extends AbsFabActivity {
prevButton = (ImageButton) findViewById(R.id.prev_button);
repeatButton = (ImageButton) findViewById(R.id.repeat_button);
shuffleButton = (ImageButton) findViewById(R.id.shuffle_button);
albumArt = (ImageView) findViewById(R.id.album_art);
albumArt = (SquareIfPlaceImageView) findViewById(R.id.album_art);
albumArtBackground = (ImageView) findViewById(R.id.album_art_background);
songTitle = (TextView) findViewById(R.id.song_title);
songArtist = (TextView) findViewById(R.id.song_artist);
@ -165,7 +168,6 @@ public class MusicControllerActivity extends AbsFabActivity {
progressSlider = (SeekBar) findViewById(R.id.progress_slider);
mediaControllerContainer = findViewById(R.id.media_controller_container);
toolbar = (Toolbar) findViewById(R.id.toolbar);
progressContainer = findViewById(R.id.progress_container);
}
private void setUpMusicControllers() {
@ -176,20 +178,10 @@ public class MusicControllerActivity extends AbsFabActivity {
}
private static void setTint(SeekBar seekBar, int color) {
ColorStateList s1 = ColorStateList.valueOf(color);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
seekBar.setThumbTintList(s1);
seekBar.setProgressTintList(s1);
} else {
seekBar.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
seekBar.getThumb().setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
private void setUpProgressSlider() {
setTint(progressSlider, ThemeSingleton.get().positiveColor);
progressSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
@ -343,10 +335,7 @@ public class MusicControllerActivity extends AbsFabActivity {
if (vibrantSwatch != null) {
final int swatchRgb = vibrantSwatch.getRgb();
animateColorChange(swatchRgb);
songTitle.setTextColor(vibrantSwatch.getTitleTextColor());
songArtist.setTextColor(vibrantSwatch.getBodyTextColor());
currentSongProgress.setTextColor(vibrantSwatch.getTitleTextColor());
totalSongDuration.setTextColor(vibrantSwatch.getTitleTextColor());
animateTextColorChange(Util.getColorWithoutAlpha(vibrantSwatch.getTitleTextColor()));
notifyTaskColorChange(swatchRgb);
} else {
resetColors();
@ -359,16 +348,14 @@ public class MusicControllerActivity extends AbsFabActivity {
}
private void resetColors() {
final int songTitleTextColor = DialogUtils.resolveColor(this, R.attr.title_text_color);
final int artistNameTextColor = DialogUtils.resolveColor(this, R.attr.caption_text_color);
final int textColor = Util.getColorWithoutAlpha(DialogUtils.resolveColor(this, R.attr.title_text_color));
final int defaultBarColor = DialogUtils.resolveColor(this, R.attr.default_bar_color);
animateColorChange(defaultBarColor);
animateTextColorChange(textColor);
songTitle.setTextColor(songTitleTextColor);
songArtist.setTextColor(artistNameTextColor);
currentSongProgress.setTextColor(artistNameTextColor);
totalSongDuration.setTextColor(artistNameTextColor);
currentSongProgress.setTextColor(DialogUtils.resolveColor(MusicControllerActivity.this, R.attr.themed_drawable_color));
totalSongDuration.setTextColor(DialogUtils.resolveColor(MusicControllerActivity.this, R.attr.themed_drawable_color));
notifyTaskColorChange(defaultBarColor);
}
@ -376,20 +363,38 @@ public class MusicControllerActivity extends AbsFabActivity {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void animateColorChange(final int newColor) {
if (lastFooterColor != -1 && lastFooterColor != newColor) {
ViewUtil.animateViewColor(footer, lastFooterColor, newColor, 300);
ViewUtil.animateViewColor(progressContainer, ColorChooserDialog.shiftColorDown(lastFooterColor), ColorChooserDialog.shiftColorDown(newColor), 300);
ViewUtil.animateViewColor(toolbar, lastFooterColor, newColor, 300);
ViewUtil.animateViewColor(footer, lastFooterColor, newColor, COLOR_TRANSITION_TIME);
if (opaqueToolBar)
ViewUtil.animateViewColor(toolbar, lastFooterColor, newColor, COLOR_TRANSITION_TIME);
else toolbar.setBackgroundColor(Color.TRANSPARENT);
} else {
footer.setBackgroundColor(newColor);
progressContainer.setBackgroundColor(ColorChooserDialog.shiftColorDown(newColor));
toolbar.setBackgroundColor(newColor);
if (opaqueToolBar) toolbar.setBackgroundColor(newColor);
else toolbar.setBackgroundColor(Color.TRANSPARENT);
}
setStatusBarColor(newColor);
setTint(progressSlider, PreferenceUtils.getInstance(this).getThemeColorAccent());
if (opaqueToolBar) setStatusBarColor(newColor);
else setStatusBarColor(Color.TRANSPARENT);
if (Util.isAtLeastLollipop() && PreferenceUtils.getInstance(this).coloredNavigationBarCurrentPlayingEnabled())
setNavigationBarColor(newColor);
lastFooterColor = newColor;
}
private void animateTextColorChange(final int newColor) {
if (lastTextColor != -2 && lastTextColor != newColor) {
ViewUtil.animateTextColor(songTitle, lastTextColor, newColor, COLOR_TRANSITION_TIME);
ViewUtil.animateTextColor(songArtist, lastTextColor, newColor, COLOR_TRANSITION_TIME);
} else {
songTitle.setTextColor(newColor);
songArtist.setTextColor(newColor);
}
lastTextColor = newColor;
}
private void getCurrentSong() {
song = MusicPlayerRemote.getCurrentSong();
if (song.id == -1) {
@ -457,14 +462,6 @@ public class MusicControllerActivity extends AbsFabActivity {
killThreads = true;
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
animateActivityOpened(DEFAULT_DELAY);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_music_playing, menu);
@ -511,13 +508,16 @@ public class MusicControllerActivity extends AbsFabActivity {
return super.onOptionsItemSelected(item);
}
private void animateActivityOpened(int startDelay) {
ViewPropertyAnimator.animate(footer)
.scaleX(1)
.scaleY(1)
.setInterpolator(new DecelerateInterpolator(4))
.setDuration(DEFAULT_ANIMATION_TIME)
.setStartDelay(startDelay)
.start();
private void setToolbarOpaque(boolean toolbarOpaque) {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) findViewById(R.id.album_art_frame).getLayoutParams();
if (!toolbarOpaque) {
if (Build.VERSION.SDK_INT > 16) {
params.removeRule(RelativeLayout.BELOW);
} else {
params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
params.addRule(RelativeLayout.ABOVE, R.id.footer_frame);
}
} else params.addRule(RelativeLayout.BELOW, R.id.toolbar_frame);
}
}

View file

@ -3,6 +3,7 @@ package com.kabouzeid.gramophone.ui.activities.base;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.util.Pair;
import android.util.Log;
import android.view.GestureDetector;
@ -13,14 +14,12 @@ import android.widget.Toast;
import com.afollestad.materialdialogs.ThemeSingleton;
import com.kabouzeid.gramophone.App;
import com.kabouzeid.gramophone.R;
import com.kabouzeid.gramophone.dialogs.ColorChooserDialog;
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
import com.kabouzeid.gramophone.misc.SmallOnGestureListener;
import com.kabouzeid.gramophone.model.MusicRemoteEvent;
import com.kabouzeid.gramophone.model.Song;
import com.kabouzeid.gramophone.util.NavigationUtil;
import com.kabouzeid.gramophone.views.PlayPauseDrawable;
import com.melnykov.fab.FloatingActionButton;
import com.squareup.otto.Subscribe;
/**
@ -55,15 +54,10 @@ public abstract class AbsFabActivity extends AbsBaseActivity {
getFab().setImageDrawable(playPauseDrawable);
final int accentColor = ThemeSingleton.get().positiveColor;
getFab().setRippleColor(accentColor);
if (accentColor == Color.WHITE) {
getFab().setColorNormal(accentColor);
getFab().setColorPressed(ColorChooserDialog.shiftColorDown(accentColor));
getFab().setColorRipple(ColorChooserDialog.shiftColorUp(accentColor));
getFab().getDrawable().setColorFilter(Color.BLACK, PorterDuff.Mode.SRC_IN);
} else {
getFab().setColorNormal(accentColor);
getFab().setColorPressed(ColorChooserDialog.shiftColorUp(accentColor));
getFab().setColorRipple(ColorChooserDialog.shiftColorDown(accentColor));
getFab().getDrawable().clearColorFilter();
}

View file

@ -10,6 +10,7 @@ import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.graphics.Palette;
import android.support.v7.widget.Toolbar;
import android.util.Log;
@ -19,6 +20,7 @@ import android.view.animation.OvershootInterpolator;
import android.widget.ImageView;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.ThemeSingleton;
import com.afollestad.materialdialogs.util.DialogUtils;
import com.github.ksoichiro.android.observablescrollview.ObservableScrollView;
import com.kabouzeid.gramophone.App;
@ -32,7 +34,6 @@ import com.kabouzeid.gramophone.util.MusicUtil;
import com.kabouzeid.gramophone.util.PreferenceUtils;
import com.kabouzeid.gramophone.util.Util;
import com.kabouzeid.gramophone.util.ViewUtil;
import com.melnykov.fab.FloatingActionButton;
import com.nineoldandroids.view.ViewHelper;
import com.nineoldandroids.view.ViewPropertyAnimator;
import com.nostra13.universalimageloader.core.ImageLoader;
@ -207,6 +208,7 @@ public abstract class AbsTagEditorActivity extends AbsBaseActivity {
save();
}
});
fab.setRippleColor(ThemeSingleton.get().positiveColor);
}
protected abstract void save();

View file

@ -36,6 +36,8 @@ public final class PreferenceUtils {
public static final String TRANSPARENT_TOOLBAR = "transparent_toolbar";
public static final String ALBUM_GRID_COLUMNS = "album_grid_columns";
public static final String ALBUM_GRID_COLUMNS_LAND = "album_grid_columns_land";
public static final String OPAQUE_TOOLBAR_NOW_PLAYING = "opaque_toolbar_now_playing";
public static final String FORCE_SQUARE_ALBUM_ART = "force_square_album_art";
private static PreferenceUtils sInstance;
@ -79,7 +81,7 @@ public final class PreferenceUtils {
}
public int getThemeColorAccent() {
return mPreferences.getInt("accent_color", mContext.getResources().getColor(R.color.pink_500));
return mPreferences.getInt("accent_color", mContext.getResources().getColor(R.color.pink_A200));
}
@SuppressLint("CommitPrefEdits")
@ -163,6 +165,14 @@ public final class PreferenceUtils {
return mPreferences.getBoolean(TRANSPARENT_TOOLBAR, false);
}
public final boolean opaqueToolbarNowPlaying() {
return mPreferences.getBoolean(OPAQUE_TOOLBAR_NOW_PLAYING, false);
}
public final boolean forceAlbumArtSquared() {
return mPreferences.getBoolean(FORCE_SQUARE_ALBUM_ART, false);
}
// public final boolean downloadMissingArtistImages() {
// return mPreferences.getBoolean(DOWNLOAD_MISSING_ARTIST_IMAGES, true);
// }

View file

@ -8,6 +8,7 @@ import android.content.res.TypedArray;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.ColorInt;
import android.support.annotation.DrawableRes;
import android.support.v4.content.ContextCompat;
import android.util.TypedValue;
@ -201,4 +202,8 @@ public class Util {
}
return drawable;
}
public static int getColorWithoutAlpha(@ColorInt int color) {
return color | 0xFF000000;
}
}

View file

@ -13,12 +13,15 @@ import android.widget.CheckBox;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.TextView;
import com.afollestad.materialdialogs.ThemeSingleton;
import com.afollestad.materialdialogs.internal.MDTintHelper;
import java.lang.reflect.Field;
import hugo.weaving.DebugLog;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
@ -84,6 +87,22 @@ public class ViewUtil {
animator.start();
}
@DebugLog
public static void animateTextColor(final TextView v, final int startColor, final int endColor) {
animateTextColor(v, startColor, endColor, DEFAULT_COLOR_ANIMATION_DURATION);
}
public static void animateTextColor(final TextView v, final int startColor, final int endColor, final int duration) {
ObjectAnimator animator = ObjectAnimator.ofObject(v, "textColor",
new ArgbEvaluator(), startColor, endColor);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
animator.setInterpolator(new PathInterpolator(0.4f, 0f, 1f, 1f));
}
animator.setDuration(duration);
animator.start();
}
public static void setBackgroundAlpha(View view, float alpha, int baseColor) {
int a = Math.min(255, Math.max(0, (int) (alpha * 255))) << 24;
int rgb = 0x00ffffff & baseColor;

View file

@ -7,17 +7,17 @@ import android.widget.ImageView;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class HeightAndWidthFitSquarePlaceLeftRightImageView extends ImageView {
public class HeightWidthFitSquareImageView extends ImageView {
public HeightAndWidthFitSquarePlaceLeftRightImageView(Context context) {
public HeightWidthFitSquareImageView(Context context) {
super(context);
}
public HeightAndWidthFitSquarePlaceLeftRightImageView(Context context, AttributeSet attrs) {
public HeightWidthFitSquareImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public HeightAndWidthFitSquarePlaceLeftRightImageView(Context context, AttributeSet attrs, int defStyle) {
public HeightWidthFitSquareImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

View file

@ -44,8 +44,6 @@ public class PlayPauseDrawable extends Drawable {
private float width;
private float height;
private final float fallBackWidth;
private final float fallBackHeight;
private float progress;
private boolean isPlay;
@ -61,8 +59,6 @@ public class PlayPauseDrawable extends Drawable {
pauseBarWidth = res.getDimensionPixelSize(R.dimen.pause_bar_width);
pauseBarHeight = res.getDimensionPixelSize(R.dimen.pause_bar_height);
pauseBarDistance = res.getDimensionPixelSize(R.dimen.pause_bar_distance);
fallBackWidth = res.getDimensionPixelSize(R.dimen.fab_icon_bound_width);
fallBackHeight = res.getDimensionPixelSize(R.dimen.fab_icon_bound_height);
}
@Override
@ -71,9 +67,6 @@ public class PlayPauseDrawable extends Drawable {
if (bounds.width() > 0 && bounds.height() > 0) {
width = bounds.width();
height = bounds.height();
} else {
width = fallBackWidth;
height = fallBackHeight;
}
}

View file

@ -1,126 +0,0 @@
package com.kabouzeid.gramophone.views;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import com.kabouzeid.gramophone.R;
/**
* A layout that draws something in the insets passed to {@link #fitSystemWindows(Rect)}, i.e. the area above UI chrome
* (status and navigation bars, overlay action bars).
*/
public class ScrimInsetsFrameLayout extends FrameLayout {
private Drawable mInsetForeground;
private Rect mInsets;
private Rect mTempRect = new Rect();
private OnInsetsCallback mOnInsetsCallback;
public ScrimInsetsFrameLayout(Context context) {
super(context);
init(context, null, 0);
}
public ScrimInsetsFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public ScrimInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs, defStyle);
}
private void init(Context context, AttributeSet attrs, int defStyle) {
final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.ScrimInsetsView, defStyle, 0);
if (a == null) {
return;
}
mInsetForeground = a.getDrawable(R.styleable.ScrimInsetsView_insetForeground);
a.recycle();
setWillNotDraw(true);
}
@Override
protected boolean fitSystemWindows(Rect insets) {
mInsets = new Rect(insets);
setWillNotDraw(mInsetForeground == null);
ViewCompat.postInvalidateOnAnimation(this);
if (mOnInsetsCallback != null) {
mOnInsetsCallback.onInsetsChanged(insets);
}
return true; // consume insets
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
int width = getWidth();
int height = getHeight();
if (mInsets != null && mInsetForeground != null) {
int sc = canvas.save();
canvas.translate(getScrollX(), getScrollY());
// Top
mTempRect.set(0, 0, width, mInsets.top);
mInsetForeground.setBounds(mTempRect);
mInsetForeground.draw(canvas);
// Bottom
mTempRect.set(0, height - mInsets.bottom, width, height);
mInsetForeground.setBounds(mTempRect);
mInsetForeground.draw(canvas);
// Left
mTempRect.set(0, mInsets.top, mInsets.left, height - mInsets.bottom);
mInsetForeground.setBounds(mTempRect);
mInsetForeground.draw(canvas);
// Right
mTempRect.set(width - mInsets.right, mInsets.top, width, height - mInsets.bottom);
mInsetForeground.setBounds(mTempRect);
mInsetForeground.draw(canvas);
canvas.restoreToCount(sc);
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (mInsetForeground != null) {
mInsetForeground.setCallback(this);
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mInsetForeground != null) {
mInsetForeground.setCallback(null);
}
}
/**
* Allows the calling container to specify a callback for custom processing when insets change (i.e. when
* {@link #fitSystemWindows(Rect)} is called. This is useful for setting padding on UI elements based on
* UI chrome insets (e.g. a Google Map or a ListView). When using with ListView or GridView, remember to set
* clipToPadding to false.
*/
public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) {
mOnInsetsCallback = onInsetsCallback;
}
public static interface OnInsetsCallback {
public void onInsetsChanged(Rect insets);
}
}

View file

@ -8,17 +8,18 @@ import android.widget.ImageView;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class SquareIfPlaceLeftRightImageView extends ImageView {
public class SquareIfPlaceImageView extends ImageView {
private boolean forceSquare = false;
public SquareIfPlaceLeftRightImageView(Context context) {
public SquareIfPlaceImageView(Context context) {
super(context);
}
public SquareIfPlaceLeftRightImageView(Context context, AttributeSet attrs) {
public SquareIfPlaceImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareIfPlaceLeftRightImageView(Context context, AttributeSet attrs, int defStyle) {
public SquareIfPlaceImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@ -27,9 +28,17 @@ public class SquareIfPlaceLeftRightImageView extends ImageView {
final int small = Math.min(widthMeasureSpec, heightMeasureSpec);
final int large = Math.max(widthMeasureSpec, heightMeasureSpec);
if (View.MeasureSpec.getSize(large) > View.MeasureSpec.getSize(small) * 1.5)
if (forceSquare) super.onMeasure(small, small);
else if (View.MeasureSpec.getSize(large) > View.MeasureSpec.getSize(small) * 1.5)
super.onMeasure(small, small);
else super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void forceSquare(boolean force) {
if (forceSquare != force) {
forceSquare = force;
invalidate();
}
}
}