New now playing screen. Work in progress!
This commit is contained in:
parent
479a7d81cd
commit
1cde43af07
27 changed files with 889 additions and 571 deletions
|
|
@ -86,8 +86,6 @@ android {
|
||||||
disable 'MissingTranslation'
|
disable 'MissingTranslation'
|
||||||
disable 'InvalidPackage'
|
disable 'InvalidPackage'
|
||||||
abortOnError false
|
abortOnError false
|
||||||
// remove as soon as it has been fixed
|
|
||||||
disable 'PrivateResource'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,26 +94,6 @@ dependencies {
|
||||||
compile('com.crashlytics.sdk.android:crashlytics:2.5.3@aar') {
|
compile('com.crashlytics.sdk.android:crashlytics:2.5.3@aar') {
|
||||||
transitive = true;
|
transitive = true;
|
||||||
}
|
}
|
||||||
compile 'com.android.support:support-v4:23.1.1'
|
|
||||||
compile 'com.android.support:support-v13:23.1.1'
|
|
||||||
compile 'com.android.support:appcompat-v7:23.1.1'
|
|
||||||
compile 'com.android.support:recyclerview-v7:23.1.1'
|
|
||||||
compile 'com.android.support:gridlayout-v7:23.1.1'
|
|
||||||
compile 'com.android.support:cardview-v7:23.1.1'
|
|
||||||
compile 'com.android.support:palette-v7:23.1.1'
|
|
||||||
compile 'com.android.support:design:23.1.1'
|
|
||||||
compile 'com.android.support:support-annotations:23.1.1'
|
|
||||||
|
|
||||||
compile 'com.github.ksoichiro:android-observablescrollview:1.6.0'
|
|
||||||
compile 'asia.ivity.android:drag-sort-listview:1.0'
|
|
||||||
compile 'com.github.semoncat.seekarc:library:0.1'
|
|
||||||
compile 'com.sothree.slidinguppanel:library:3.2.0'
|
|
||||||
|
|
||||||
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
|
|
||||||
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
|
|
||||||
compile 'com.squareup.okhttp:okhttp:2.5.0'
|
|
||||||
|
|
||||||
compile 'com.github.kabouzeid:Android-Universal-Image-Loader:8ffb5d4afa'
|
|
||||||
|
|
||||||
compile('com.afollestad.material-dialogs:core:0.8.5.1@aar') {
|
compile('com.afollestad.material-dialogs:core:0.8.5.1@aar') {
|
||||||
transitive = true
|
transitive = true
|
||||||
|
|
@ -127,11 +105,27 @@ dependencies {
|
||||||
transitive = true
|
transitive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
compile 'com.jakewharton:butterknife:7.0.1'
|
|
||||||
|
|
||||||
//noinspection GradleDynamicVersion
|
|
||||||
compile 'com.anjlab.android.iab.v3:library:1.0.+@aar'
|
|
||||||
|
|
||||||
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
|
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
|
||||||
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
|
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
|
||||||
|
compile 'com.android.support:support-v4:23.1.1'
|
||||||
|
compile 'com.android.support:support-v13:23.1.1'
|
||||||
|
compile 'com.android.support:appcompat-v7:23.1.1'
|
||||||
|
compile 'com.android.support:recyclerview-v7:23.1.1'
|
||||||
|
compile 'com.android.support:gridlayout-v7:23.1.1'
|
||||||
|
compile 'com.android.support:cardview-v7:23.1.1'
|
||||||
|
compile 'com.android.support:palette-v7:23.1.1'
|
||||||
|
compile 'com.android.support:design:23.1.1'
|
||||||
|
compile 'com.android.support:support-annotations:23.1.1'
|
||||||
|
compile 'com.android.support:percent:23.1.1'
|
||||||
|
compile 'com.github.ksoichiro:android-observablescrollview:1.6.0'
|
||||||
|
compile 'asia.ivity.android:drag-sort-listview:1.0'
|
||||||
|
compile 'com.github.semoncat.seekarc:library:0.1'
|
||||||
|
compile 'com.sothree.slidinguppanel:library:3.2.0'
|
||||||
|
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
|
||||||
|
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
|
||||||
|
compile 'com.squareup.okhttp:okhttp:2.5.0'
|
||||||
|
compile 'com.github.kabouzeid:Android-Universal-Image-Loader:c2894ad9f1'
|
||||||
|
compile 'com.jakewharton:butterknife:7.0.1'
|
||||||
|
//noinspection GradleDynamicVersion
|
||||||
|
compile 'com.anjlab.android.iab.v3:library:1.0.+@aar'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
333
app/src/main/java/com/kabouzeid/gramophone/helper/StackBlur.java
Normal file
333
app/src/main/java/com/kabouzeid/gramophone/helper/StackBlur.java
Normal file
|
|
@ -0,0 +1,333 @@
|
||||||
|
package com.kabouzeid.gramophone.helper;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blur using Java code.
|
||||||
|
* <p/>
|
||||||
|
* This is a compromise between Gaussian Blur and Box blur
|
||||||
|
* It creates much better looking blurs than Box Blur, but is
|
||||||
|
* 7x faster than my Gaussian Blur implementation.
|
||||||
|
* <p/>
|
||||||
|
* I called it Stack Blur because this describes best how this
|
||||||
|
* filter works internally: it creates a kind of moving stack
|
||||||
|
* of colors whilst scanning through the image. Thereby it
|
||||||
|
* just has to add one new block of color to the right side
|
||||||
|
* of the stack and remove the leftmost color. The remaining
|
||||||
|
* colors on the topmost layer of the stack are either added on
|
||||||
|
* or reduced by one, depending on if they are on the right or
|
||||||
|
* on the left side of the stack.
|
||||||
|
*
|
||||||
|
* @author Enrique López Mañas <eenriquelopez@gmail.com>
|
||||||
|
* http://www.neo-tech.es
|
||||||
|
* <p/>
|
||||||
|
* Author of the original algorithm: Mario Klingemann <mario.quasimondo.com>
|
||||||
|
* <p/>
|
||||||
|
* Based heavily on http://vitiy.info/Code/stackblur.cpp
|
||||||
|
* See http://vitiy.info/stackblur-algorithm-multi-threaded-blur-for-cpp/
|
||||||
|
* @copyright: Enrique López Mañas
|
||||||
|
* @license: Apache License 2.0
|
||||||
|
*/
|
||||||
|
public class StackBlur {
|
||||||
|
|
||||||
|
static final int EXECUTOR_THREADS = Runtime.getRuntime().availableProcessors();
|
||||||
|
static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(EXECUTOR_THREADS);
|
||||||
|
|
||||||
|
private static final short[] stackblur_mul = {
|
||||||
|
512, 512, 456, 512, 328, 456, 335, 512, 405, 328, 271, 456, 388, 335, 292, 512,
|
||||||
|
454, 405, 364, 328, 298, 271, 496, 456, 420, 388, 360, 335, 312, 292, 273, 512,
|
||||||
|
482, 454, 428, 405, 383, 364, 345, 328, 312, 298, 284, 271, 259, 496, 475, 456,
|
||||||
|
437, 420, 404, 388, 374, 360, 347, 335, 323, 312, 302, 292, 282, 273, 265, 512,
|
||||||
|
497, 482, 468, 454, 441, 428, 417, 405, 394, 383, 373, 364, 354, 345, 337, 328,
|
||||||
|
320, 312, 305, 298, 291, 284, 278, 271, 265, 259, 507, 496, 485, 475, 465, 456,
|
||||||
|
446, 437, 428, 420, 412, 404, 396, 388, 381, 374, 367, 360, 354, 347, 341, 335,
|
||||||
|
329, 323, 318, 312, 307, 302, 297, 292, 287, 282, 278, 273, 269, 265, 261, 512,
|
||||||
|
505, 497, 489, 482, 475, 468, 461, 454, 447, 441, 435, 428, 422, 417, 411, 405,
|
||||||
|
399, 394, 389, 383, 378, 373, 368, 364, 359, 354, 350, 345, 341, 337, 332, 328,
|
||||||
|
324, 320, 316, 312, 309, 305, 301, 298, 294, 291, 287, 284, 281, 278, 274, 271,
|
||||||
|
268, 265, 262, 259, 257, 507, 501, 496, 491, 485, 480, 475, 470, 465, 460, 456,
|
||||||
|
451, 446, 442, 437, 433, 428, 424, 420, 416, 412, 408, 404, 400, 396, 392, 388,
|
||||||
|
385, 381, 377, 374, 370, 367, 363, 360, 357, 354, 350, 347, 344, 341, 338, 335,
|
||||||
|
332, 329, 326, 323, 320, 318, 315, 312, 310, 307, 304, 302, 299, 297, 294, 292,
|
||||||
|
289, 287, 285, 282, 280, 278, 275, 273, 271, 269, 267, 265, 263, 261, 259
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final byte[] stackblur_shr = {
|
||||||
|
9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17,
|
||||||
|
17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19,
|
||||||
|
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20,
|
||||||
|
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,
|
||||||
|
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||||
|
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22,
|
||||||
|
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||||
|
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23,
|
||||||
|
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||||
|
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||||
|
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||||
|
23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||||
|
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||||
|
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||||
|
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||||
|
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24
|
||||||
|
};
|
||||||
|
|
||||||
|
public static Bitmap blur(Bitmap original, float radius) {
|
||||||
|
int w = original.getWidth();
|
||||||
|
int h = original.getHeight();
|
||||||
|
int[] currentPixels = new int[w * h];
|
||||||
|
original.getPixels(currentPixels, 0, w, 0, 0, w, h);
|
||||||
|
int cores = EXECUTOR_THREADS;
|
||||||
|
|
||||||
|
ArrayList<BlurTask> horizontal = new ArrayList<BlurTask>(cores);
|
||||||
|
ArrayList<BlurTask> vertical = new ArrayList<BlurTask>(cores);
|
||||||
|
for (int i = 0; i < cores; i++) {
|
||||||
|
horizontal.add(new BlurTask(currentPixels, w, h, (int) radius, cores, i, 1));
|
||||||
|
vertical.add(new BlurTask(currentPixels, w, h, (int) radius, cores, i, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
EXECUTOR.invokeAll(horizontal);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
EXECUTOR.invokeAll(vertical);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Bitmap.createBitmap(currentPixels, w, h, Bitmap.Config.ARGB_8888);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void blurIteration(int[] src, int w, int h, int radius, int cores, int core, int step) {
|
||||||
|
int x, y, xp, yp, i;
|
||||||
|
int sp;
|
||||||
|
int stack_start;
|
||||||
|
int stack_i;
|
||||||
|
|
||||||
|
int src_i;
|
||||||
|
int dst_i;
|
||||||
|
|
||||||
|
long sum_r, sum_g, sum_b,
|
||||||
|
sum_in_r, sum_in_g, sum_in_b,
|
||||||
|
sum_out_r, sum_out_g, sum_out_b;
|
||||||
|
|
||||||
|
int wm = w - 1;
|
||||||
|
int hm = h - 1;
|
||||||
|
int div = (radius * 2) + 1;
|
||||||
|
int mul_sum = stackblur_mul[radius];
|
||||||
|
byte shr_sum = stackblur_shr[radius];
|
||||||
|
int[] stack = new int[div];
|
||||||
|
|
||||||
|
if (step == 1) {
|
||||||
|
int minY = core * h / cores;
|
||||||
|
int maxY = (core + 1) * h / cores;
|
||||||
|
|
||||||
|
for (y = minY; y < maxY; y++) {
|
||||||
|
sum_r = sum_g = sum_b =
|
||||||
|
sum_in_r = sum_in_g = sum_in_b =
|
||||||
|
sum_out_r = sum_out_g = sum_out_b = 0;
|
||||||
|
|
||||||
|
src_i = w * y; // start of line (0,y)
|
||||||
|
|
||||||
|
for (i = 0; i <= radius; i++) {
|
||||||
|
stack_i = i;
|
||||||
|
stack[stack_i] = src[src_i];
|
||||||
|
sum_r += ((src[src_i] >>> 16) & 0xff) * (i + 1);
|
||||||
|
sum_g += ((src[src_i] >>> 8) & 0xff) * (i + 1);
|
||||||
|
sum_b += (src[src_i] & 0xff) * (i + 1);
|
||||||
|
sum_out_r += ((src[src_i] >>> 16) & 0xff);
|
||||||
|
sum_out_g += ((src[src_i] >>> 8) & 0xff);
|
||||||
|
sum_out_b += (src[src_i] & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 1; i <= radius; i++) {
|
||||||
|
if (i <= wm) src_i += 1;
|
||||||
|
stack_i = i + radius;
|
||||||
|
stack[stack_i] = src[src_i];
|
||||||
|
sum_r += ((src[src_i] >>> 16) & 0xff) * (radius + 1 - i);
|
||||||
|
sum_g += ((src[src_i] >>> 8) & 0xff) * (radius + 1 - i);
|
||||||
|
sum_b += (src[src_i] & 0xff) * (radius + 1 - i);
|
||||||
|
sum_in_r += ((src[src_i] >>> 16) & 0xff);
|
||||||
|
sum_in_g += ((src[src_i] >>> 8) & 0xff);
|
||||||
|
sum_in_b += (src[src_i] & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sp = radius;
|
||||||
|
xp = radius;
|
||||||
|
if (xp > wm) xp = wm;
|
||||||
|
src_i = xp + y * w; // img.pix_ptr(xp, y);
|
||||||
|
dst_i = y * w; // img.pix_ptr(0, y);
|
||||||
|
for (x = 0; x < w; x++) {
|
||||||
|
src[dst_i] = (int)
|
||||||
|
((src[dst_i] & 0xff000000) |
|
||||||
|
((((sum_r * mul_sum) >>> shr_sum) & 0xff) << 16) |
|
||||||
|
((((sum_g * mul_sum) >>> shr_sum) & 0xff) << 8) |
|
||||||
|
((((sum_b * mul_sum) >>> shr_sum) & 0xff)));
|
||||||
|
dst_i += 1;
|
||||||
|
|
||||||
|
sum_r -= sum_out_r;
|
||||||
|
sum_g -= sum_out_g;
|
||||||
|
sum_b -= sum_out_b;
|
||||||
|
|
||||||
|
stack_start = sp + div - radius;
|
||||||
|
if (stack_start >= div) stack_start -= div;
|
||||||
|
stack_i = stack_start;
|
||||||
|
|
||||||
|
sum_out_r -= ((stack[stack_i] >>> 16) & 0xff);
|
||||||
|
sum_out_g -= ((stack[stack_i] >>> 8) & 0xff);
|
||||||
|
sum_out_b -= (stack[stack_i] & 0xff);
|
||||||
|
|
||||||
|
if (xp < wm) {
|
||||||
|
src_i += 1;
|
||||||
|
++xp;
|
||||||
|
}
|
||||||
|
|
||||||
|
stack[stack_i] = src[src_i];
|
||||||
|
|
||||||
|
sum_in_r += ((src[src_i] >>> 16) & 0xff);
|
||||||
|
sum_in_g += ((src[src_i] >>> 8) & 0xff);
|
||||||
|
sum_in_b += (src[src_i] & 0xff);
|
||||||
|
sum_r += sum_in_r;
|
||||||
|
sum_g += sum_in_g;
|
||||||
|
sum_b += sum_in_b;
|
||||||
|
|
||||||
|
++sp;
|
||||||
|
if (sp >= div) sp = 0;
|
||||||
|
stack_i = sp;
|
||||||
|
|
||||||
|
sum_out_r += ((stack[stack_i] >>> 16) & 0xff);
|
||||||
|
sum_out_g += ((stack[stack_i] >>> 8) & 0xff);
|
||||||
|
sum_out_b += (stack[stack_i] & 0xff);
|
||||||
|
sum_in_r -= ((stack[stack_i] >>> 16) & 0xff);
|
||||||
|
sum_in_g -= ((stack[stack_i] >>> 8) & 0xff);
|
||||||
|
sum_in_b -= (stack[stack_i] & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 2
|
||||||
|
else if (step == 2) {
|
||||||
|
int minX = core * w / cores;
|
||||||
|
int maxX = (core + 1) * w / cores;
|
||||||
|
|
||||||
|
for (x = minX; x < maxX; x++) {
|
||||||
|
sum_r = sum_g = sum_b =
|
||||||
|
sum_in_r = sum_in_g = sum_in_b =
|
||||||
|
sum_out_r = sum_out_g = sum_out_b = 0;
|
||||||
|
|
||||||
|
src_i = x; // x,0
|
||||||
|
for (i = 0; i <= radius; i++) {
|
||||||
|
stack_i = i;
|
||||||
|
stack[stack_i] = src[src_i];
|
||||||
|
sum_r += ((src[src_i] >>> 16) & 0xff) * (i + 1);
|
||||||
|
sum_g += ((src[src_i] >>> 8) & 0xff) * (i + 1);
|
||||||
|
sum_b += (src[src_i] & 0xff) * (i + 1);
|
||||||
|
sum_out_r += ((src[src_i] >>> 16) & 0xff);
|
||||||
|
sum_out_g += ((src[src_i] >>> 8) & 0xff);
|
||||||
|
sum_out_b += (src[src_i] & 0xff);
|
||||||
|
}
|
||||||
|
for (i = 1; i <= radius; i++) {
|
||||||
|
if (i <= hm) src_i += w; // +stride
|
||||||
|
|
||||||
|
stack_i = i + radius;
|
||||||
|
stack[stack_i] = src[src_i];
|
||||||
|
sum_r += ((src[src_i] >>> 16) & 0xff) * (radius + 1 - i);
|
||||||
|
sum_g += ((src[src_i] >>> 8) & 0xff) * (radius + 1 - i);
|
||||||
|
sum_b += (src[src_i] & 0xff) * (radius + 1 - i);
|
||||||
|
sum_in_r += ((src[src_i] >>> 16) & 0xff);
|
||||||
|
sum_in_g += ((src[src_i] >>> 8) & 0xff);
|
||||||
|
sum_in_b += (src[src_i] & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
sp = radius;
|
||||||
|
yp = radius;
|
||||||
|
if (yp > hm) yp = hm;
|
||||||
|
src_i = x + yp * w; // img.pix_ptr(x, yp);
|
||||||
|
dst_i = x; // img.pix_ptr(x, 0);
|
||||||
|
for (y = 0; y < h; y++) {
|
||||||
|
src[dst_i] = (int)
|
||||||
|
((src[dst_i] & 0xff000000) |
|
||||||
|
((((sum_r * mul_sum) >>> shr_sum) & 0xff) << 16) |
|
||||||
|
((((sum_g * mul_sum) >>> shr_sum) & 0xff) << 8) |
|
||||||
|
((((sum_b * mul_sum) >>> shr_sum) & 0xff)));
|
||||||
|
dst_i += w;
|
||||||
|
|
||||||
|
sum_r -= sum_out_r;
|
||||||
|
sum_g -= sum_out_g;
|
||||||
|
sum_b -= sum_out_b;
|
||||||
|
|
||||||
|
stack_start = sp + div - radius;
|
||||||
|
if (stack_start >= div) stack_start -= div;
|
||||||
|
stack_i = stack_start;
|
||||||
|
|
||||||
|
sum_out_r -= ((stack[stack_i] >>> 16) & 0xff);
|
||||||
|
sum_out_g -= ((stack[stack_i] >>> 8) & 0xff);
|
||||||
|
sum_out_b -= (stack[stack_i] & 0xff);
|
||||||
|
|
||||||
|
if (yp < hm) {
|
||||||
|
src_i += w; // stride
|
||||||
|
++yp;
|
||||||
|
}
|
||||||
|
|
||||||
|
stack[stack_i] = src[src_i];
|
||||||
|
|
||||||
|
sum_in_r += ((src[src_i] >>> 16) & 0xff);
|
||||||
|
sum_in_g += ((src[src_i] >>> 8) & 0xff);
|
||||||
|
sum_in_b += (src[src_i] & 0xff);
|
||||||
|
sum_r += sum_in_r;
|
||||||
|
sum_g += sum_in_g;
|
||||||
|
sum_b += sum_in_b;
|
||||||
|
|
||||||
|
++sp;
|
||||||
|
if (sp >= div) sp = 0;
|
||||||
|
stack_i = sp;
|
||||||
|
|
||||||
|
sum_out_r += ((stack[stack_i] >>> 16) & 0xff);
|
||||||
|
sum_out_g += ((stack[stack_i] >>> 8) & 0xff);
|
||||||
|
sum_out_b += (stack[stack_i] & 0xff);
|
||||||
|
sum_in_r -= ((stack[stack_i] >>> 16) & 0xff);
|
||||||
|
sum_in_g -= ((stack[stack_i] >>> 8) & 0xff);
|
||||||
|
sum_in_b -= (stack[stack_i] & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class BlurTask implements Callable<Void> {
|
||||||
|
private final int[] _src;
|
||||||
|
private final int _w;
|
||||||
|
private final int _h;
|
||||||
|
private final int _radius;
|
||||||
|
private final int _totalCores;
|
||||||
|
private final int _coreIndex;
|
||||||
|
private final int _round;
|
||||||
|
|
||||||
|
public BlurTask(int[] src, int w, int h, int radius, int totalCores, int coreIndex, int round) {
|
||||||
|
_src = src;
|
||||||
|
_w = w;
|
||||||
|
_h = h;
|
||||||
|
_radius = radius;
|
||||||
|
_totalCores = totalCores;
|
||||||
|
_coreIndex = coreIndex;
|
||||||
|
_round = round;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void call() throws Exception {
|
||||||
|
blurIteration(_src, _w, _h, _radius, _totalCores, _coreIndex, _round);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
package com.kabouzeid.gramophone.imageloader;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.support.annotation.FloatRange;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v8.renderscript.Allocation;
|
||||||
|
import android.support.v8.renderscript.Element;
|
||||||
|
import android.support.v8.renderscript.RSRuntimeException;
|
||||||
|
import android.support.v8.renderscript.RenderScript;
|
||||||
|
import android.support.v8.renderscript.ScriptIntrinsicBlur;
|
||||||
|
|
||||||
|
import com.kabouzeid.gramophone.BuildConfig;
|
||||||
|
import com.kabouzeid.gramophone.helper.StackBlur;
|
||||||
|
import com.kabouzeid.gramophone.util.ImageUtil;
|
||||||
|
import com.nostra13.universalimageloader.core.process.BitmapProcessor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
|
*/
|
||||||
|
public class BlurProcessor implements BitmapProcessor {
|
||||||
|
public static final float DEFAULT_BLUR_RADIUS = 5f;
|
||||||
|
|
||||||
|
private Context context;
|
||||||
|
private final float blurRadius;
|
||||||
|
private final int sampling;
|
||||||
|
|
||||||
|
private BlurProcessor(Builder builder) {
|
||||||
|
this.context = builder.context;
|
||||||
|
this.blurRadius = builder.blurRadius;
|
||||||
|
this.sampling = builder.sampling;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Something here seems to cause a memory leak... Go into LeakCanary for more details.
|
||||||
|
@Override
|
||||||
|
public Bitmap process(Bitmap bitmap) {
|
||||||
|
int sampling;
|
||||||
|
if (this.sampling == 0) {
|
||||||
|
sampling = ImageUtil.calculateInSampleSize(bitmap.getWidth(), bitmap.getHeight(), 100);
|
||||||
|
} else {
|
||||||
|
sampling = this.sampling;
|
||||||
|
}
|
||||||
|
|
||||||
|
int width = bitmap.getWidth();
|
||||||
|
int height = bitmap.getHeight();
|
||||||
|
int scaledWidth = width / sampling;
|
||||||
|
int scaledHeight = height / sampling;
|
||||||
|
|
||||||
|
Bitmap out = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);
|
||||||
|
|
||||||
|
Canvas canvas = new Canvas(out);
|
||||||
|
canvas.scale(1 / (float) sampling, 1 / (float) sampling);
|
||||||
|
Paint paint = new Paint();
|
||||||
|
paint.setFlags(Paint.FILTER_BITMAP_FLAG);
|
||||||
|
canvas.drawBitmap(bitmap, 0, 0, paint);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final RenderScript rs = RenderScript.create(context.getApplicationContext());
|
||||||
|
final Allocation input = Allocation.createFromBitmap(rs, out, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
|
||||||
|
final Allocation output = Allocation.createTyped(rs, input.getType());
|
||||||
|
final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
|
||||||
|
|
||||||
|
script.setRadius(blurRadius);
|
||||||
|
script.setInput(input);
|
||||||
|
script.forEach(output);
|
||||||
|
|
||||||
|
output.copyTo(out);
|
||||||
|
|
||||||
|
rs.destroy();
|
||||||
|
|
||||||
|
return out;
|
||||||
|
|
||||||
|
} catch (RSRuntimeException e) {
|
||||||
|
// on some devices RenderScript.create() throws: android.support.v8.renderscript.RSRuntimeException: Error loading libRSSupport library
|
||||||
|
if (BuildConfig.DEBUG) e.printStackTrace();
|
||||||
|
|
||||||
|
return StackBlur.blur(out, blurRadius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
private Context context;
|
||||||
|
private float blurRadius = DEFAULT_BLUR_RADIUS;
|
||||||
|
private int sampling;
|
||||||
|
|
||||||
|
public Builder(@NonNull Context context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param blurRadius The radius to use. Must be between 0 and 25. Default is 5.
|
||||||
|
* @return the same Builder
|
||||||
|
*/
|
||||||
|
public Builder blurRadius(@FloatRange(from = 0.0f, to = 25.0f) float blurRadius) {
|
||||||
|
this.blurRadius = blurRadius;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param sampling The inSampleSize to use. Must be a power of 2, or 1 for no down sampling or 0 for auto detect sampling. Default is 0.
|
||||||
|
* @return the same Builder
|
||||||
|
*/
|
||||||
|
public Builder sampling(int sampling) {
|
||||||
|
this.sampling = sampling;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder fromPrototype(BlurProcessor prototype) {
|
||||||
|
context = prototype.context;
|
||||||
|
blurRadius = prototype.blurRadius;
|
||||||
|
sampling = prototype.sampling;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlurProcessor build() {
|
||||||
|
return new BlurProcessor(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -31,12 +31,12 @@ import android.support.annotation.Nullable;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.kabouzeid.gramophone.BuildConfig;
|
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.appwidget.WidgetMedium;
|
import com.kabouzeid.gramophone.appwidget.WidgetMedium;
|
||||||
import com.kabouzeid.gramophone.helper.PlayingNotificationHelper;
|
import com.kabouzeid.gramophone.helper.PlayingNotificationHelper;
|
||||||
import com.kabouzeid.gramophone.helper.ShuffleHelper;
|
import com.kabouzeid.gramophone.helper.ShuffleHelper;
|
||||||
import com.kabouzeid.gramophone.helper.StopWatch;
|
import com.kabouzeid.gramophone.helper.StopWatch;
|
||||||
|
import com.kabouzeid.gramophone.imageloader.BlurProcessor;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
import com.kabouzeid.gramophone.model.Song;
|
||||||
import com.kabouzeid.gramophone.provider.HistoryStore;
|
import com.kabouzeid.gramophone.provider.HistoryStore;
|
||||||
import com.kabouzeid.gramophone.provider.MusicPlaybackQueueStore;
|
import com.kabouzeid.gramophone.provider.MusicPlaybackQueueStore;
|
||||||
|
|
@ -51,7 +51,6 @@ import com.nostra13.universalimageloader.core.assist.ImageSize;
|
||||||
import com.nostra13.universalimageloader.core.assist.ViewScaleType;
|
import com.nostra13.universalimageloader.core.assist.ViewScaleType;
|
||||||
import com.nostra13.universalimageloader.core.imageaware.NonViewAware;
|
import com.nostra13.universalimageloader.core.imageaware.NonViewAware;
|
||||||
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
||||||
import com.nostra13.universalimageloader.core.process.BitmapProcessor;
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
@ -447,22 +446,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
ImageLoader.getInstance().displayImage(
|
ImageLoader.getInstance().displayImage(
|
||||||
currentAlbumArtUri,
|
currentAlbumArtUri,
|
||||||
new NonViewAware(new ImageSize(screenSize.x, screenSize.y), ViewScaleType.CROP),
|
new NonViewAware(new ImageSize(screenSize.x, screenSize.y), ViewScaleType.CROP),
|
||||||
new DisplayImageOptions.Builder()
|
new DisplayImageOptions.Builder().postProcessor(new BlurProcessor.Builder(this).build()).build(),
|
||||||
.postProcessor(new BitmapProcessor() {
|
|
||||||
@Override
|
|
||||||
public Bitmap process(Bitmap bitmap) {
|
|
||||||
Bitmap.Config config = bitmap.getConfig();
|
|
||||||
if (config == null) {
|
|
||||||
config = Bitmap.Config.ARGB_8888;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return bitmap.copy(config, false);
|
|
||||||
} catch (OutOfMemoryError e) {
|
|
||||||
if (BuildConfig.DEBUG) e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).build(),
|
|
||||||
new SimpleImageLoadingListener() {
|
new SimpleImageLoadingListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onLoadingComplete(String imageUri, View view, @Nullable Bitmap loadedImage) {
|
public void onLoadingComplete(String imageUri, View view, @Nullable Bitmap loadedImage) {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
|
@ -43,7 +44,6 @@ import com.kabouzeid.gramophone.util.ColorUtil;
|
||||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||||
import com.kabouzeid.gramophone.util.NavigationUtil;
|
import com.kabouzeid.gramophone.util.NavigationUtil;
|
||||||
import com.kabouzeid.gramophone.util.Util;
|
import com.kabouzeid.gramophone.util.Util;
|
||||||
import com.kabouzeid.gramophone.views.SquareIfPlaceImageView;
|
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||||
|
|
@ -68,7 +68,7 @@ public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implement
|
||||||
public static final String EXTRA_ARTIST_ID = "extra_artist_id";
|
public static final String EXTRA_ARTIST_ID = "extra_artist_id";
|
||||||
|
|
||||||
@Bind(R.id.image)
|
@Bind(R.id.image)
|
||||||
SquareIfPlaceImageView artistImage;
|
ImageView artistImage;
|
||||||
@Bind(R.id.list_background)
|
@Bind(R.id.list_background)
|
||||||
View songListBackground;
|
View songListBackground;
|
||||||
@Bind(R.id.list)
|
@Bind(R.id.list)
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,31 @@
|
||||||
package com.kabouzeid.gramophone.ui.fragments;
|
package com.kabouzeid.gramophone.ui.fragments;
|
||||||
|
|
||||||
import android.animation.Animator;
|
|
||||||
import android.animation.AnimatorSet;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Build;
|
import android.graphics.PorterDuff;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.design.widget.FloatingActionButton;
|
import android.support.design.widget.FloatingActionButton;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v7.widget.CardView;
|
|
||||||
import android.util.TypedValue;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewAnimationUtils;
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.animation.DecelerateInterpolator;
|
import android.view.animation.DecelerateInterpolator;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.SeekBar;
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.afollestad.materialdialogs.internal.ThemeSingleton;
|
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
import com.kabouzeid.gramophone.helper.MusicPlayerRemote;
|
||||||
|
import com.kabouzeid.gramophone.helper.MusicProgressViewUpdateHelper;
|
||||||
import com.kabouzeid.gramophone.helper.PlayPauseButtonOnClickHandler;
|
import com.kabouzeid.gramophone.helper.PlayPauseButtonOnClickHandler;
|
||||||
import com.kabouzeid.gramophone.interfaces.MusicServiceEventListener;
|
import com.kabouzeid.gramophone.interfaces.MusicServiceEventListener;
|
||||||
import com.kabouzeid.gramophone.misc.FloatingActionButtonProperties;
|
import com.kabouzeid.gramophone.misc.FloatingActionButtonProperties;
|
||||||
import com.kabouzeid.gramophone.misc.SimpleAnimatorListener;
|
import com.kabouzeid.gramophone.misc.SimpleOnSeekbarChangeListener;
|
||||||
import com.kabouzeid.gramophone.model.Song;
|
|
||||||
import com.kabouzeid.gramophone.service.MusicService;
|
import com.kabouzeid.gramophone.service.MusicService;
|
||||||
import com.kabouzeid.gramophone.ui.activities.base.AbsMusicServiceActivity;
|
import com.kabouzeid.gramophone.ui.activities.base.AbsMusicServiceActivity;
|
||||||
import com.kabouzeid.gramophone.util.ColorUtil;
|
import com.kabouzeid.gramophone.util.ColorUtil;
|
||||||
import com.kabouzeid.gramophone.util.PreferenceUtil;
|
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||||
import com.kabouzeid.gramophone.util.Util;
|
import com.kabouzeid.gramophone.util.Util;
|
||||||
import com.kabouzeid.gramophone.util.ViewUtil;
|
|
||||||
import com.kabouzeid.gramophone.views.PlayPauseDrawable;
|
import com.kabouzeid.gramophone.views.PlayPauseDrawable;
|
||||||
|
|
||||||
import butterknife.Bind;
|
import butterknife.Bind;
|
||||||
|
|
@ -43,20 +34,10 @@ import butterknife.ButterKnife;
|
||||||
/**
|
/**
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
*/
|
*/
|
||||||
public class PlaybackControlsFragment extends Fragment implements MusicServiceEventListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
public class PlaybackControlsFragment extends Fragment implements MusicServiceEventListener, MusicProgressViewUpdateHelper.Callback {
|
||||||
private static final int FAB_CIRCULAR_REVEAL_ANIMATION_TIME = 1000;
|
|
||||||
|
|
||||||
@Bind(R.id.player_play_pause_fab)
|
@Bind(R.id.player_play_pause_fab)
|
||||||
FloatingActionButton playPauseFab;
|
FloatingActionButton playPauseFab;
|
||||||
|
|
||||||
@Bind(R.id.player_title)
|
|
||||||
TextView songTitle;
|
|
||||||
@Bind(R.id.player_text)
|
|
||||||
TextView songText;
|
|
||||||
@Bind(R.id.player_footer)
|
|
||||||
LinearLayout footer;
|
|
||||||
@Bind(R.id.player_playback_controller_card)
|
|
||||||
CardView playbackControllerCard;
|
|
||||||
@Bind(R.id.player_prev_button)
|
@Bind(R.id.player_prev_button)
|
||||||
ImageButton prevButton;
|
ImageButton prevButton;
|
||||||
@Bind(R.id.player_next_button)
|
@Bind(R.id.player_next_button)
|
||||||
|
|
@ -65,20 +46,20 @@ public class PlaybackControlsFragment extends Fragment implements MusicServiceEv
|
||||||
ImageButton repeatButton;
|
ImageButton repeatButton;
|
||||||
@Bind(R.id.player_shuffle_button)
|
@Bind(R.id.player_shuffle_button)
|
||||||
ImageButton shuffleButton;
|
ImageButton shuffleButton;
|
||||||
@Bind(R.id.player_media_controller_container)
|
|
||||||
RelativeLayout mediaControllerContainer;
|
|
||||||
@Bind(R.id.player_media_controller_container_background)
|
|
||||||
View mediaControllerContainerBackground;
|
|
||||||
|
|
||||||
private int lastFooterColor;
|
@Bind(R.id.player_progress_slider)
|
||||||
private int lastPlaybackControlsColor;
|
SeekBar progressSlider;
|
||||||
private int lastTitleTextColor;
|
@Bind(R.id.player_song_total_time)
|
||||||
private int lastCaptionTextColor;
|
TextView songTotalTime;
|
||||||
|
@Bind(R.id.player_song_current_progress)
|
||||||
|
TextView songCurrentProgress;
|
||||||
|
|
||||||
private PlayPauseDrawable playerFabPlayPauseDrawable;
|
private PlayPauseDrawable playerFabPlayPauseDrawable;
|
||||||
private AnimatorSet colorTransitionAnimator;
|
|
||||||
|
|
||||||
private AbsMusicServiceActivity activity;
|
private AbsMusicServiceActivity activity;
|
||||||
|
private int lastPlaybackControlsColor;
|
||||||
|
|
||||||
|
private MusicProgressViewUpdateHelper progressViewUpdateHelper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(Context context) {
|
||||||
|
|
@ -96,6 +77,12 @@ public class PlaybackControlsFragment extends Fragment implements MusicServiceEv
|
||||||
activity = null;
|
activity = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
progressViewUpdateHelper = new MusicProgressViewUpdateHelper(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
|
|
@ -106,23 +93,32 @@ public class PlaybackControlsFragment extends Fragment implements MusicServiceEv
|
||||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
ButterKnife.bind(this, view);
|
ButterKnife.bind(this, view);
|
||||||
PreferenceUtil.getInstance(getContext()).registerOnSharedPreferenceChangedListener(this);
|
|
||||||
activity.addMusicServiceEventListener(this);
|
activity.addMusicServiceEventListener(this);
|
||||||
|
|
||||||
setUpMusicControllers();
|
setUpMusicControllers();
|
||||||
|
updateProgressTextColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroyView() {
|
public void onDestroyView() {
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
activity.removeMusicServiceEventListener(this);
|
activity.removeMusicServiceEventListener(this);
|
||||||
PreferenceUtil.getInstance(activity).unregisterOnSharedPreferenceChangedListener(this);
|
|
||||||
ButterKnife.unbind(this);
|
ButterKnife.unbind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
progressViewUpdateHelper.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
progressViewUpdateHelper.stop();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPlayingMetaChanged() {
|
public void onPlayingMetaChanged() {
|
||||||
updateMetaTexts();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -145,31 +141,19 @@ public class PlaybackControlsFragment extends Fragment implements MusicServiceEv
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
|
||||||
switch (key) {
|
|
||||||
case PreferenceUtil.PLAYBACK_CONTROLLER_CARD_NOW_PLAYING:
|
|
||||||
updatePlaybackControllerCardVisibility();
|
|
||||||
break;
|
|
||||||
case PreferenceUtil.COLOR_PLAYBACK_CONTROLS_NOW_PLAYING:
|
|
||||||
updateRepeatState();
|
|
||||||
updateShuffleState();
|
|
||||||
updatePlayPauseFabTint();
|
|
||||||
break;
|
|
||||||
case PreferenceUtil.LARGER_TITLE_BOX_NOW_PLAYING:
|
|
||||||
updateTitleBoxSize();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setColor(int color) {
|
public void setColor(int color) {
|
||||||
animateColorChange(color);
|
lastPlaybackControlsColor = ColorUtil.getOpaqueColor(ColorUtil.getSecondaryTextColorForBackground(getContext(), color));
|
||||||
|
updateRepeatState();
|
||||||
|
updateShuffleState();
|
||||||
|
updatePrevNextColor();
|
||||||
|
updateProgressSliderTint();
|
||||||
|
updateProgressTextColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpPlayPauseFab() {
|
private void setUpPlayPauseFab() {
|
||||||
updatePlayPauseDrawableState(false);
|
updatePlayPauseDrawableState(false);
|
||||||
playPauseFab.setImageDrawable(playerFabPlayPauseDrawable);
|
playPauseFab.setImageDrawable(playerFabPlayPauseDrawable);
|
||||||
updatePlayPauseFabTint();
|
FloatingActionButtonProperties.COLOR.set(playPauseFab, Color.WHITE);
|
||||||
playPauseFab.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
playPauseFab.setOnClickListener(new PlayPauseButtonOnClickHandler());
|
||||||
playPauseFab.post(new Runnable() {
|
playPauseFab.post(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -180,11 +164,6 @@ public class PlaybackControlsFragment extends Fragment implements MusicServiceEv
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updatePlayPauseFabTint() {
|
|
||||||
int fabColor = PreferenceUtil.getInstance(activity).colorPlaybackControlsNowPlaying() ? lastPlaybackControlsColor : activity.getThemeColorAccent();
|
|
||||||
FloatingActionButtonProperties.COLOR.set(playPauseFab, fabColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void updatePlayPauseDrawableState(boolean animate) {
|
protected void updatePlayPauseDrawableState(boolean animate) {
|
||||||
if (playerFabPlayPauseDrawable == null) {
|
if (playerFabPlayPauseDrawable == null) {
|
||||||
playerFabPlayPauseDrawable = new PlayPauseDrawable(activity);
|
playerFabPlayPauseDrawable = new PlayPauseDrawable(activity);
|
||||||
|
|
@ -196,37 +175,16 @@ public class PlaybackControlsFragment extends Fragment implements MusicServiceEv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTitleBoxSize() {
|
|
||||||
boolean largerTitleBox = PreferenceUtil.getInstance(activity).largerTitleBoxNowPlaying();
|
|
||||||
int paddingTopBottom = largerTitleBox ? getResources().getDimensionPixelSize(R.dimen.title_box_padding_large) : getResources().getDimensionPixelSize(R.dimen.title_box_padding_small);
|
|
||||||
footer.setPadding(footer.getPaddingLeft(), paddingTopBottom, footer.getPaddingRight(), paddingTopBottom);
|
|
||||||
|
|
||||||
songTitle.setPadding(songTitle.getPaddingLeft(), songTitle.getPaddingTop(), songTitle.getPaddingRight(), largerTitleBox ? getResources().getDimensionPixelSize(R.dimen.title_box_text_spacing_large) : getResources().getDimensionPixelSize(R.dimen.title_box_text_spacing_small));
|
|
||||||
songText.setPadding(songText.getPaddingLeft(), largerTitleBox ? getResources().getDimensionPixelSize(R.dimen.title_box_text_spacing_large) : getResources().getDimensionPixelSize(R.dimen.title_box_text_spacing_small), songText.getPaddingRight(), songText.getPaddingBottom());
|
|
||||||
|
|
||||||
songTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, largerTitleBox ? getResources().getDimensionPixelSize(R.dimen.title_box_title_text_size_large) : getResources().getDimensionPixelSize(R.dimen.title_box_title_text_size_small));
|
|
||||||
songText.setTextSize(TypedValue.COMPLEX_UNIT_PX, largerTitleBox ? getResources().getDimensionPixelSize(R.dimen.title_box_caption_text_size_large) : getResources().getDimensionPixelSize(R.dimen.title_box_caption_text_size_small));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updatePlaybackControllerCardVisibility() {
|
|
||||||
boolean showPlaybackControllerCard = PreferenceUtil.getInstance(activity).playbackControllerCardNowPlaying();
|
|
||||||
playbackControllerCard.setVisibility(showPlaybackControllerCard ? View.VISIBLE : View.GONE);
|
|
||||||
mediaControllerContainerBackground.setVisibility(showPlaybackControllerCard ? View.GONE : View.VISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setUpMusicControllers() {
|
private void setUpMusicControllers() {
|
||||||
setUpPlayPauseFab();
|
setUpPlayPauseFab();
|
||||||
setUpPrevNext();
|
setUpPrevNext();
|
||||||
setUpRepeatButton();
|
setUpRepeatButton();
|
||||||
setUpShuffleButton();
|
setUpShuffleButton();
|
||||||
|
setUpProgressSlider();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpPrevNext() {
|
private void setUpPrevNext() {
|
||||||
int themedDrawableColor = ColorUtil.resolveColor(activity, android.R.attr.textColorSecondary);
|
updatePrevNextColor();
|
||||||
nextButton.setImageDrawable(Util.getTintedDrawable(activity,
|
|
||||||
R.drawable.ic_skip_next_white_36dp, themedDrawableColor));
|
|
||||||
prevButton.setImageDrawable(Util.getTintedDrawable(activity,
|
|
||||||
R.drawable.ic_skip_previous_white_36dp, themedDrawableColor));
|
|
||||||
nextButton.setOnClickListener(new View.OnClickListener() {
|
nextButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
|
@ -241,6 +199,19 @@ public class PlaybackControlsFragment extends Fragment implements MusicServiceEv
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateProgressTextColor() {
|
||||||
|
int color = ColorUtil.getPrimaryTextColor(getContext(), false);
|
||||||
|
songTotalTime.setTextColor(color);
|
||||||
|
songCurrentProgress.setTextColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updatePrevNextColor() {
|
||||||
|
nextButton.setImageDrawable(Util.getTintedDrawable(activity,
|
||||||
|
R.drawable.ic_skip_next_white_36dp, lastPlaybackControlsColor));
|
||||||
|
prevButton.setImageDrawable(Util.getTintedDrawable(activity,
|
||||||
|
R.drawable.ic_skip_previous_white_36dp, lastPlaybackControlsColor));
|
||||||
|
}
|
||||||
|
|
||||||
private void setUpShuffleButton() {
|
private void setUpShuffleButton() {
|
||||||
updateShuffleState();
|
updateShuffleState();
|
||||||
shuffleButton.setOnClickListener(new View.OnClickListener() {
|
shuffleButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
@ -255,11 +226,11 @@ public class PlaybackControlsFragment extends Fragment implements MusicServiceEv
|
||||||
switch (MusicPlayerRemote.getShuffleMode()) {
|
switch (MusicPlayerRemote.getShuffleMode()) {
|
||||||
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
case MusicService.SHUFFLE_MODE_SHUFFLE:
|
||||||
shuffleButton.setImageDrawable(Util.getTintedDrawable(activity, R.drawable.ic_shuffle_white_36dp,
|
shuffleButton.setImageDrawable(Util.getTintedDrawable(activity, R.drawable.ic_shuffle_white_36dp,
|
||||||
getActivatedIconColor()));
|
lastPlaybackControlsColor));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
shuffleButton.setImageDrawable(Util.getTintedDrawable(activity, R.drawable.ic_shuffle_white_36dp,
|
shuffleButton.setImageDrawable(Util.getTintedDrawable(activity, R.drawable.ic_shuffle_white_36dp,
|
||||||
getDeactivatedIconColor()));
|
lastPlaybackControlsColor));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -278,84 +249,19 @@ public class PlaybackControlsFragment extends Fragment implements MusicServiceEv
|
||||||
switch (MusicPlayerRemote.getRepeatMode()) {
|
switch (MusicPlayerRemote.getRepeatMode()) {
|
||||||
case MusicService.REPEAT_MODE_ALL:
|
case MusicService.REPEAT_MODE_ALL:
|
||||||
repeatButton.setImageDrawable(Util.getTintedDrawable(activity, R.drawable.ic_repeat_white_36dp,
|
repeatButton.setImageDrawable(Util.getTintedDrawable(activity, R.drawable.ic_repeat_white_36dp,
|
||||||
getActivatedIconColor()));
|
lastPlaybackControlsColor));
|
||||||
break;
|
break;
|
||||||
case MusicService.REPEAT_MODE_THIS:
|
case MusicService.REPEAT_MODE_THIS:
|
||||||
repeatButton.setImageDrawable(Util.getTintedDrawable(activity, R.drawable.ic_repeat_one_white_36dp,
|
repeatButton.setImageDrawable(Util.getTintedDrawable(activity, R.drawable.ic_repeat_one_white_36dp,
|
||||||
getActivatedIconColor()));
|
lastPlaybackControlsColor));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
repeatButton.setImageDrawable(Util.getTintedDrawable(activity, R.drawable.ic_repeat_white_36dp,
|
repeatButton.setImageDrawable(Util.getTintedDrawable(activity, R.drawable.ic_repeat_white_36dp,
|
||||||
getDeactivatedIconColor()));
|
lastPlaybackControlsColor));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getActivatedIconColor() {
|
|
||||||
if (PreferenceUtil.getInstance(activity).colorPlaybackControlsNowPlaying()) {
|
|
||||||
return ensureActivatedColorVisibleIfNecessary(lastPlaybackControlsColor);
|
|
||||||
} else {
|
|
||||||
return ThemeSingleton.get().positiveColor.getDefaultColor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getDeactivatedIconColor() {
|
|
||||||
return ColorUtil.resolveColor(activity, android.R.attr.textColorSecondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return If the activated color wont have enough difference to the deactivated color Color.WHITE / Color.BLACK (depending on the theme),
|
|
||||||
* else the unmodified accentColor.
|
|
||||||
*/
|
|
||||||
private int ensureActivatedColorVisibleIfNecessary(int activatedColor) {
|
|
||||||
// Not optimal, but much easier then computing the opaque deactivated color on the background color every time.
|
|
||||||
int preBlendedDeactivatedIconColor = ThemeSingleton.get().darkTheme ? Color.argb(255, 188, 188, 188) : Color.argb(255, 115, 115, 115);
|
|
||||||
if (ColorUtil.getColorDifference(activatedColor, preBlendedDeactivatedIconColor) <= 30d) {
|
|
||||||
return ThemeSingleton.get().darkTheme ? Color.WHITE : Color.BLACK;
|
|
||||||
}
|
|
||||||
return activatedColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateMetaTexts() {
|
|
||||||
final Song song = MusicPlayerRemote.getCurrentSong();
|
|
||||||
songTitle.setText(song.title);
|
|
||||||
songText.setText(song.artistName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void animateColorChange(final int newColor) {
|
|
||||||
if (colorTransitionAnimator != null && colorTransitionAnimator.isStarted()) {
|
|
||||||
colorTransitionAnimator.cancel();
|
|
||||||
}
|
|
||||||
colorTransitionAnimator = new AnimatorSet();
|
|
||||||
AnimatorSet.Builder animatorSetBuilder = colorTransitionAnimator.play(ViewUtil.createBackgroundColorTransition(footer, lastFooterColor, newColor));
|
|
||||||
|
|
||||||
int titleTextColor = ColorUtil.getPrimaryTextColorForBackground(activity, newColor);
|
|
||||||
int captionTextColor = ColorUtil.getSecondaryTextColorForBackground(activity, newColor);
|
|
||||||
|
|
||||||
animatorSetBuilder.with(ViewUtil.createTextColorTransition(songTitle, lastTitleTextColor, titleTextColor));
|
|
||||||
animatorSetBuilder.with(ViewUtil.createTextColorTransition(songText, lastCaptionTextColor, captionTextColor));
|
|
||||||
|
|
||||||
colorTransitionAnimator.addListener(new SimpleAnimatorListener() {
|
|
||||||
@Override
|
|
||||||
public void onAnimationStart(Animator animation) {
|
|
||||||
if (newColor == ColorUtil.resolveColor(activity, R.attr.default_bar_color) && ThemeSingleton.get().darkTheme) {
|
|
||||||
lastPlaybackControlsColor = Color.WHITE;
|
|
||||||
} else {
|
|
||||||
lastPlaybackControlsColor = newColor;
|
|
||||||
}
|
|
||||||
updateRepeatState();
|
|
||||||
updateShuffleState();
|
|
||||||
updatePlayPauseFabTint();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
colorTransitionAnimator.start();
|
|
||||||
|
|
||||||
lastFooterColor = newColor;
|
|
||||||
lastTitleTextColor = titleTextColor;
|
|
||||||
lastCaptionTextColor = captionTextColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showControls() {
|
public void showControls() {
|
||||||
playPauseFab.animate()
|
playPauseFab.animate()
|
||||||
.scaleX(1f)
|
.scaleX(1f)
|
||||||
|
|
@ -363,28 +269,38 @@ public class PlaybackControlsFragment extends Fragment implements MusicServiceEv
|
||||||
.rotation(360f)
|
.rotation(360f)
|
||||||
.setInterpolator(new DecelerateInterpolator())
|
.setInterpolator(new DecelerateInterpolator())
|
||||||
.start();
|
.start();
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
if (mediaControllerContainer.getVisibility() == View.INVISIBLE) {
|
|
||||||
int cx = (playPauseFab.getLeft() + playPauseFab.getRight()) / 2;
|
|
||||||
int cy = (playPauseFab.getTop() + playPauseFab.getBottom()) / 2;
|
|
||||||
int finalRadius = Math.max(mediaControllerContainer.getWidth(), mediaControllerContainer.getHeight());
|
|
||||||
|
|
||||||
final Animator animator = ViewAnimationUtils.createCircularReveal(mediaControllerContainer, cx, cy, 0, finalRadius);
|
|
||||||
animator.setInterpolator(new DecelerateInterpolator());
|
|
||||||
animator.setDuration(FAB_CIRCULAR_REVEAL_ANIMATION_TIME);
|
|
||||||
animator.start();
|
|
||||||
mediaControllerContainer.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetShowControlsAnimation() {
|
public void resetShowControlsAnimation() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
mediaControllerContainer.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
|
||||||
playPauseFab.setScaleX(0f);
|
playPauseFab.setScaleX(0f);
|
||||||
playPauseFab.setScaleY(0f);
|
playPauseFab.setScaleY(0f);
|
||||||
playPauseFab.setRotation(0f);
|
playPauseFab.setRotation(0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateProgressSliderTint() {
|
||||||
|
int color = ColorUtil.getPrimaryTextColor(getContext(), false);
|
||||||
|
progressSlider.getThumb().mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||||
|
progressSlider.getProgressDrawable().mutate().setColorFilter(Color.TRANSPARENT, PorterDuff.Mode.SRC_IN);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpProgressSlider() {
|
||||||
|
updateProgressSliderTint();
|
||||||
|
progressSlider.setOnSeekBarChangeListener(new SimpleOnSeekbarChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||||
|
if (fromUser) {
|
||||||
|
MusicPlayerRemote.seekTo(progress);
|
||||||
|
onUpdateProgressViews(MusicPlayerRemote.getSongProgressMillis(), MusicPlayerRemote.getSongDurationMillis());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpdateProgressViews(int progress, int total) {
|
||||||
|
progressSlider.setMax(total);
|
||||||
|
progressSlider.setProgress(progress);
|
||||||
|
songTotalTime.setText(MusicUtil.getReadableDurationString(total));
|
||||||
|
songCurrentProgress.setText(MusicUtil.getReadableDurationString(progress));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.animation.DecelerateInterpolator;
|
import android.view.animation.DecelerateInterpolator;
|
||||||
import android.view.animation.OvershootInterpolator;
|
import android.view.animation.OvershootInterpolator;
|
||||||
import android.widget.FrameLayout;
|
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
||||||
import com.kabouzeid.gramophone.R;
|
import com.kabouzeid.gramophone.R;
|
||||||
|
|
@ -25,13 +24,10 @@ import com.kabouzeid.gramophone.util.ColorUtil;
|
||||||
import com.kabouzeid.gramophone.util.MusicUtil;
|
import com.kabouzeid.gramophone.util.MusicUtil;
|
||||||
import com.kabouzeid.gramophone.util.PreferenceUtil;
|
import com.kabouzeid.gramophone.util.PreferenceUtil;
|
||||||
import com.kabouzeid.gramophone.util.ViewUtil;
|
import com.kabouzeid.gramophone.util.ViewUtil;
|
||||||
import com.kabouzeid.gramophone.views.SquareIfPlaceImageView;
|
|
||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||||
import com.nostra13.universalimageloader.core.assist.LoadedFrom;
|
|
||||||
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
|
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
|
||||||
import com.nostra13.universalimageloader.core.imageaware.ImageAware;
|
|
||||||
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;
|
||||||
import com.nostra13.universalimageloader.core.process.BitmapProcessor;
|
import com.nostra13.universalimageloader.core.process.BitmapProcessor;
|
||||||
|
|
||||||
|
|
@ -44,13 +40,9 @@ import butterknife.ButterKnife;
|
||||||
public class PlayerAlbumCoverFragment extends Fragment implements MusicServiceEventListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
public class PlayerAlbumCoverFragment extends Fragment implements MusicServiceEventListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
@Bind(R.id.player_image)
|
@Bind(R.id.player_image)
|
||||||
SquareIfPlaceImageView albumArt;
|
ImageView albumCover;
|
||||||
@Bind(R.id.player_favorite_icon)
|
@Bind(R.id.player_favorite_icon)
|
||||||
ImageView favoriteIcon;
|
ImageView favoriteIcon;
|
||||||
@Bind(R.id.player_album_art_frame)
|
|
||||||
FrameLayout albumArtFrame;
|
|
||||||
|
|
||||||
private boolean forceSquareAlbumArt;
|
|
||||||
|
|
||||||
private AbsMusicServiceActivity activity;
|
private AbsMusicServiceActivity activity;
|
||||||
private OnColorChangedListener onColorChangedListener;
|
private OnColorChangedListener onColorChangedListener;
|
||||||
|
|
@ -82,7 +74,7 @@ public class PlayerAlbumCoverFragment extends Fragment implements MusicServiceEv
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
ButterKnife.bind(this, view);
|
ButterKnife.bind(this, view);
|
||||||
|
|
||||||
albumArt.forceSquare(forceSquareAlbumArt);
|
forceSquareAlbumCover(PreferenceUtil.getInstance(getContext()).forceSquareAlbumCover());
|
||||||
|
|
||||||
PreferenceUtil.getInstance(getContext()).registerOnSharedPreferenceChangedListener(this);
|
PreferenceUtil.getInstance(getContext()).registerOnSharedPreferenceChangedListener(this);
|
||||||
activity.addMusicServiceEventListener(this);
|
activity.addMusicServiceEventListener(this);
|
||||||
|
|
@ -124,9 +116,8 @@ public class PlayerAlbumCoverFragment extends Fragment implements MusicServiceEv
|
||||||
@Override
|
@Override
|
||||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case PreferenceUtil.FORCE_SQUARE_ALBUM_ART:
|
case PreferenceUtil.FORCE_SQUARE_ALBUM_COVER:
|
||||||
forceSquareAlbumArt = PreferenceUtil.getInstance(activity).forceAlbumArtSquared();
|
forceSquareAlbumCover(PreferenceUtil.getInstance(activity).forceSquareAlbumCover());
|
||||||
albumArt.forceSquare(forceSquareAlbumArt);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +131,7 @@ public class PlayerAlbumCoverFragment extends Fragment implements MusicServiceEv
|
||||||
final ColorHolder colorHolder = new ColorHolder();
|
final ColorHolder colorHolder = new ColorHolder();
|
||||||
ImageLoader.getInstance().displayImage(
|
ImageLoader.getInstance().displayImage(
|
||||||
MusicUtil.getSongImageLoaderString(MusicPlayerRemote.getCurrentSong()),
|
MusicUtil.getSongImageLoaderString(MusicPlayerRemote.getCurrentSong()),
|
||||||
albumArt,
|
albumCover,
|
||||||
new DisplayImageOptions.Builder()
|
new DisplayImageOptions.Builder()
|
||||||
.cacheInMemory(true)
|
.cacheInMemory(true)
|
||||||
.showImageOnFail(R.drawable.default_album_art)
|
.showImageOnFail(R.drawable.default_album_art)
|
||||||
|
|
@ -151,13 +142,7 @@ public class PlayerAlbumCoverFragment extends Fragment implements MusicServiceEv
|
||||||
return bitmap;
|
return bitmap;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.displayer(new FadeInBitmapDisplayer(ViewUtil.DEFAULT_COLOR_ANIMATION_DURATION) {
|
.displayer(new FadeInBitmapDisplayer(ViewUtil.DEFAULT_COLOR_ANIMATION_DURATION))
|
||||||
@Override
|
|
||||||
public void display(Bitmap bitmap, ImageAware imageAware, LoadedFrom loadedFrom) {
|
|
||||||
super.display(bitmap, imageAware, loadedFrom);
|
|
||||||
setColor(colorHolder.color);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.build(),
|
.build(),
|
||||||
new SimpleImageLoadingListener() {
|
new SimpleImageLoadingListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -170,7 +155,9 @@ public class PlayerAlbumCoverFragment extends Fragment implements MusicServiceEv
|
||||||
public void onLoadingComplete(String imageUri, View view, @Nullable Bitmap loadedImage) {
|
public void onLoadingComplete(String imageUri, View view, @Nullable Bitmap loadedImage) {
|
||||||
if (loadedImage == null) {
|
if (loadedImage == null) {
|
||||||
onLoadingFailed(imageUri, view, null);
|
onLoadingFailed(imageUri, view, null);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
setColor(colorHolder.color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -211,6 +198,10 @@ public class PlayerAlbumCoverFragment extends Fragment implements MusicServiceEv
|
||||||
.start();
|
.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void forceSquareAlbumCover(boolean forceSquareAlbumCover) {
|
||||||
|
albumCover.setScaleType(forceSquareAlbumCover ? ImageView.ScaleType.FIT_CENTER : ImageView.ScaleType.CENTER_CROP);
|
||||||
|
}
|
||||||
|
|
||||||
private void setColor(int color) {
|
private void setColor(int color) {
|
||||||
if (onColorChangedListener != null) onColorChangedListener.onColorChanged(color);
|
if (onColorChangedListener != null) onColorChangedListener.onColorChanged(color);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,6 @@ import butterknife.ButterKnife;
|
||||||
public class PlayerFragment extends Fragment implements SharedPreferences.OnSharedPreferenceChangeListener, MusicServiceEventListener, Toolbar.OnMenuItemClickListener, PaletteColorHolder, MusicProgressViewUpdateHelper.Callback, PlayerAlbumCoverFragment.OnColorChangedListener {
|
public class PlayerFragment extends Fragment implements SharedPreferences.OnSharedPreferenceChangeListener, MusicServiceEventListener, Toolbar.OnMenuItemClickListener, PaletteColorHolder, MusicProgressViewUpdateHelper.Callback, PlayerAlbumCoverFragment.OnColorChangedListener {
|
||||||
public static final String TAG = PlayerFragment.class.getSimpleName();
|
public static final String TAG = PlayerFragment.class.getSimpleName();
|
||||||
|
|
||||||
@Bind(R.id.player_status_bar)
|
|
||||||
View statusbar;
|
|
||||||
@Bind(R.id.player_toolbar)
|
@Bind(R.id.player_toolbar)
|
||||||
Toolbar toolbar;
|
Toolbar toolbar;
|
||||||
|
|
||||||
|
|
@ -59,6 +57,7 @@ public class PlayerFragment extends Fragment implements SharedPreferences.OnShar
|
||||||
private Callbacks callbacks;
|
private Callbacks callbacks;
|
||||||
|
|
||||||
private PlaybackControlsFragment playbackControlsFragment;
|
private PlaybackControlsFragment playbackControlsFragment;
|
||||||
|
private PlayingInfoFragment playingInfoFragment;
|
||||||
private PlayerAlbumCoverFragment playerAlbumCoverFragment;
|
private PlayerAlbumCoverFragment playerAlbumCoverFragment;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -97,6 +96,7 @@ public class PlayerFragment extends Fragment implements SharedPreferences.OnShar
|
||||||
ButterKnife.bind(this, view);
|
ButterKnife.bind(this, view);
|
||||||
|
|
||||||
playbackControlsFragment = (PlaybackControlsFragment) getChildFragmentManager().findFragmentById(R.id.playback_controls_fragment);
|
playbackControlsFragment = (PlaybackControlsFragment) getChildFragmentManager().findFragmentById(R.id.playback_controls_fragment);
|
||||||
|
playingInfoFragment = (PlayingInfoFragment) getChildFragmentManager().findFragmentById(R.id.playing_info_fragment);
|
||||||
playerAlbumCoverFragment = (PlayerAlbumCoverFragment) getChildFragmentManager().findFragmentById(R.id.player_album_cover_fragment);
|
playerAlbumCoverFragment = (PlayerAlbumCoverFragment) getChildFragmentManager().findFragmentById(R.id.player_album_cover_fragment);
|
||||||
playerAlbumCoverFragment.setOnColorChangedListener(this);
|
playerAlbumCoverFragment.setOnColorChangedListener(this);
|
||||||
|
|
||||||
|
|
@ -340,46 +340,7 @@ public class PlayerFragment extends Fragment implements SharedPreferences.OnShar
|
||||||
}
|
}
|
||||||
|
|
||||||
private void animateColorChange(final int newColor) {
|
private void animateColorChange(final int newColor) {
|
||||||
// if (colorTransitionAnimator != null && colorTransitionAnimator.isStarted()) {
|
getView().setBackgroundColor(newColor);
|
||||||
// colorTransitionAnimator.cancel();
|
|
||||||
// }
|
|
||||||
// colorTransitionAnimator = new AnimatorSet();
|
|
||||||
// AnimatorSet.Builder animatorSetBuilder = colorTransitionAnimator.play(ViewUtil.createBackgroundColorTransition(footer, lastColor, newColor));
|
|
||||||
//
|
|
||||||
// if (opaqueToolBar) {
|
|
||||||
// animatorSetBuilder.with(ViewUtil.createBackgroundColorTransition(toolbar, lastColor, newColor));
|
|
||||||
// ViewUtil.setToolbarContentColorForBackground(activity, toolbar, newColor);
|
|
||||||
// } else {
|
|
||||||
// toolbar.setBackgroundColor(Color.TRANSPARENT);
|
|
||||||
// ViewUtil.setToolbarContentDark(activity, toolbar, false);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (opaqueStatusBar) {
|
|
||||||
// int newStatusbarColor = newColor;
|
|
||||||
// int oldStatusbarColor = lastColor;
|
|
||||||
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
// newStatusbarColor = ColorUtil.shiftColorDown(newStatusbarColor);
|
|
||||||
// oldStatusbarColor = ColorUtil.shiftColorDown(oldStatusbarColor);
|
|
||||||
// }
|
|
||||||
// animatorSetBuilder.with(ViewUtil.createBackgroundColorTransition(statusbar, oldStatusbarColor, newStatusbarColor));
|
|
||||||
// } else {
|
|
||||||
// statusbar.setBackgroundColor(Color.TRANSPARENT);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// colorTransitionAnimator.addListener(new SimpleAnimatorListener() {
|
|
||||||
// @Override
|
|
||||||
// public void onAnimationStart(Animator animation) {
|
|
||||||
// if (newColor == ColorUtil.resolveColor(activity, R.attr.default_bar_color) && ThemeSingleton.get().darkTheme) {
|
|
||||||
// lastPlaybackControlsColor = Color.WHITE;
|
|
||||||
// } else {
|
|
||||||
// lastPlaybackControlsColor = newColor;
|
|
||||||
// }
|
|
||||||
// updateProgressSliderTint();
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// colorTransitionAnimator.start();
|
|
||||||
|
|
||||||
lastColor = newColor;
|
lastColor = newColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
package com.kabouzeid.gramophone.ui.fragments;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import com.kabouzeid.gramophone.R;
|
||||||
|
import com.kabouzeid.gramophone.interfaces.MusicServiceEventListener;
|
||||||
|
import com.kabouzeid.gramophone.ui.activities.base.AbsMusicServiceActivity;
|
||||||
|
|
||||||
|
import butterknife.ButterKnife;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karim Abou Zeid (kabouzeid)
|
||||||
|
*/
|
||||||
|
public class PlayingInfoFragment extends Fragment implements MusicServiceEventListener {
|
||||||
|
|
||||||
|
|
||||||
|
private AbsMusicServiceActivity activity;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
try {
|
||||||
|
activity = (AbsMusicServiceActivity) context;
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
throw new RuntimeException(context.getClass().getSimpleName() + " must be an instance of " + AbsMusicServiceActivity.class.getSimpleName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetach() {
|
||||||
|
super.onDetach();
|
||||||
|
activity = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
return inflater.inflate(R.layout.fragment_playing_info, container, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
ButterKnife.bind(this, view);
|
||||||
|
activity.addMusicServiceEventListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
activity.removeMusicServiceEventListener(this);
|
||||||
|
ButterKnife.unbind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPlayingMetaChanged() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPlayStateChanged() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRepeatModeChanged() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onShuffleModeChanged() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMediaStoreChanged() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -118,7 +118,7 @@ public class MusicUtil {
|
||||||
public static String getReadableDurationString(long songDurationMillis) {
|
public static String getReadableDurationString(long songDurationMillis) {
|
||||||
long minutes = (songDurationMillis / 1000) / 60;
|
long minutes = (songDurationMillis / 1000) / 60;
|
||||||
long seconds = (songDurationMillis / 1000) % 60;
|
long seconds = (songDurationMillis / 1000) % 60;
|
||||||
return String.format("%02d:%02d", minutes, seconds);
|
return String.format("%01d:%02d", minutes, seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
//iTunes uses for example 1002 for track 2 CD1 or 3011 for track 11 CD3.
|
//iTunes uses for example 1002 for track 2 CD1 or 3011 for track 11 CD3.
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ public final class PreferenceUtil {
|
||||||
|
|
||||||
public static final String OPAQUE_TOOLBAR_NOW_PLAYING = "opaque_toolbar_now_playing";
|
public static final String OPAQUE_TOOLBAR_NOW_PLAYING = "opaque_toolbar_now_playing";
|
||||||
public static final String OPAQUE_STATUSBAR_NOW_PLAYING = "opaque_statusbar_now_playing";
|
public static final String OPAQUE_STATUSBAR_NOW_PLAYING = "opaque_statusbar_now_playing";
|
||||||
public static final String FORCE_SQUARE_ALBUM_ART = "force_square_album_art";
|
public static final String FORCE_SQUARE_ALBUM_COVER = "force_square_album_art";
|
||||||
public static final String LARGER_TITLE_BOX_NOW_PLAYING = "larger_title_box_now_playing";
|
public static final String LARGER_TITLE_BOX_NOW_PLAYING = "larger_title_box_now_playing";
|
||||||
public static final String ALTERNATIVE_PROGRESS_SLIDER_NOW_PLAYING = "alternative_progress_slider_now_playing";
|
public static final String ALTERNATIVE_PROGRESS_SLIDER_NOW_PLAYING = "alternative_progress_slider_now_playing";
|
||||||
public static final String PLAYBACK_CONTROLLER_CARD_NOW_PLAYING = "playback_controller_card_now_playing";
|
public static final String PLAYBACK_CONTROLLER_CARD_NOW_PLAYING = "playback_controller_card_now_playing";
|
||||||
|
|
@ -167,8 +167,8 @@ public final class PreferenceUtil {
|
||||||
return mPreferences.getBoolean(OPAQUE_TOOLBAR_NOW_PLAYING, false);
|
return mPreferences.getBoolean(OPAQUE_TOOLBAR_NOW_PLAYING, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean forceAlbumArtSquared() {
|
public final boolean forceSquareAlbumCover() {
|
||||||
return mPreferences.getBoolean(FORCE_SQUARE_ALBUM_ART, false);
|
return mPreferences.getBoolean(FORCE_SQUARE_ALBUM_COVER, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean playbackControllerCardNowPlaying() {
|
public final boolean playbackControllerCardNowPlaying() {
|
||||||
|
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
package com.kabouzeid.gramophone.views;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
|
||||||
*/
|
|
||||||
public class HeightFitSquareImageView extends ImageView {
|
|
||||||
|
|
||||||
public HeightFitSquareImageView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HeightFitSquareImageView(@NonNull Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HeightFitSquareImageView(@NonNull Context context, AttributeSet attrs, int defStyle) {
|
|
||||||
super(context, attrs, defStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
//noinspection SuspiciousNameCombination
|
|
||||||
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
package com.kabouzeid.gramophone.views;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
|
||||||
*/
|
|
||||||
public class HeightWidthFitSquareImageView extends ImageView {
|
|
||||||
|
|
||||||
public HeightWidthFitSquareImageView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HeightWidthFitSquareImageView(@NonNull Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public HeightWidthFitSquareImageView(@NonNull Context context, AttributeSet attrs, int defStyle) {
|
|
||||||
super(context, attrs, defStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
final int small = Math.min(widthMeasureSpec, heightMeasureSpec);
|
|
||||||
super.onMeasure(small, small);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
package com.kabouzeid.gramophone.views;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Karim Abou Zeid (kabouzeid)
|
|
||||||
*/
|
|
||||||
public class SquareIfPlaceImageView extends ImageView {
|
|
||||||
private boolean forceSquare = false;
|
|
||||||
|
|
||||||
public SquareIfPlaceImageView(Context context) {
|
|
||||||
super(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SquareIfPlaceImageView(@NonNull Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SquareIfPlaceImageView(@NonNull Context context, AttributeSet attrs, int defStyle) {
|
|
||||||
super(context, attrs, defStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
||||||
final int small = Math.min(widthMeasureSpec, heightMeasureSpec);
|
|
||||||
final int large = Math.max(widthMeasureSpec, heightMeasureSpec);
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:shape="rectangle">
|
android:shape="rectangle">
|
||||||
<size
|
<size
|
||||||
android:width="3dp"
|
android:width="4dp"
|
||||||
android:height="20dp" />
|
android:height="24dp" />
|
||||||
<solid android:color="@android:color/black" />
|
<solid android:color="@android:color/black" />
|
||||||
</shape>
|
</shape>
|
||||||
|
|
@ -1,41 +1,59 @@
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="false">
|
android:focusable="false"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:baselineAligned="false">
|
||||||
|
|
||||||
<include layout="@layout/shadow_statusbar_actionbar" />
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
<View
|
|
||||||
android:id="@+id/player_status_bar"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/status_bar_padding"
|
android:layout_height="match_parent"
|
||||||
android:background="@android:color/transparent"
|
android:layout_weight="1">
|
||||||
android:elevation="@dimen/toolbar_elevation"
|
|
||||||
tools:ignore="UnusedAttribute" />
|
|
||||||
|
|
||||||
<android.support.v7.widget.Toolbar
|
<fragment
|
||||||
android:id="@+id/player_toolbar"
|
android:id="@+id/playing_info_fragment"
|
||||||
style="@style/Toolbar"
|
class="com.kabouzeid.gramophone.ui.fragments.PlayingInfoFragment"
|
||||||
android:layout_below="@id/player_status_bar"
|
android:layout_width="match_parent"
|
||||||
android:background="@android:color/transparent"
|
android:layout_height="72dp"
|
||||||
tools:ignore="UnusedAttribute" />
|
android:layout_above="@+id/playback_controls_fragment"
|
||||||
|
tools:layout="@layout/fragment_player_album_cover" />
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/playback_controls_fragment"
|
||||||
|
class="com.kabouzeid.gramophone.ui.fragments.PlaybackControlsFragment"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
tools:layout="@layout/fragment_playback_controls" />
|
||||||
|
|
||||||
|
<include layout="@layout/shadow_statusbar_actionbar" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/player_status_bar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/status_bar_padding"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:elevation="@dimen/toolbar_elevation"
|
||||||
|
tools:ignore="UnusedAttribute" />
|
||||||
|
|
||||||
|
<android.support.v7.widget.Toolbar
|
||||||
|
android:id="@+id/player_toolbar"
|
||||||
|
style="@style/Toolbar"
|
||||||
|
android:layout_below="@id/player_status_bar"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
tools:ignore="UnusedAttribute" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:id="@+id/player_album_cover_fragment"
|
android:id="@+id/player_album_cover_fragment"
|
||||||
class="com.kabouzeid.gramophone.ui.fragments.PlayerAlbumCoverFragment"
|
class="com.kabouzeid.gramophone.ui.fragments.PlayerAlbumCoverFragment"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"
|
||||||
tools:layout="@layout/fragment_player_album_cover" />
|
tools:layout="@layout/fragment_player_album_cover" />
|
||||||
|
|
||||||
<fragment
|
</LinearLayout>
|
||||||
android:layout_toRightOf="@id/player_album_cover_fragment"
|
|
||||||
android:id="@+id/playback_controls_fragment"
|
|
||||||
class="com.kabouzeid.gramophone.ui.fragments.PlaybackControlsFragment"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
tools:layout="@layout/fragment_playback_controls" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<com.kabouzeid.gramophone.views.SquareIfPlaceImageView
|
<ImageView
|
||||||
android:id="@+id/image"
|
android:id="@+id/image"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/header_image_height"
|
android:layout_height="@dimen/header_image_height"
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<com.kabouzeid.gramophone.views.SquareIfPlaceImageView
|
<ImageView
|
||||||
android:id="@+id/image"
|
android:id="@+id/image"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/header_image_height"
|
android:layout_height="@dimen/header_image_height"
|
||||||
|
|
|
||||||
|
|
@ -2,142 +2,121 @@
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/player_footer_frame"
|
android:id="@+id/player_footer_frame"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<RelativeLayout
|
||||||
android:id="@+id/player_footer"
|
android:background="#5a000000"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="@dimen/progress_container_height">
|
||||||
android:background="?default_bar_color"
|
|
||||||
android:elevation="@dimen/toolbar_elevation"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingBottom="@dimen/title_box_padding_large"
|
|
||||||
android:paddingLeft="72dp"
|
|
||||||
android:paddingRight="72dp"
|
|
||||||
android:paddingTop="@dimen/title_box_padding_large"
|
|
||||||
tools:ignore="UnusedAttribute">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/player_title"
|
android:id="@+id/player_song_current_progress"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
android:fontFamily="sans-serif-medium"
|
android:fontFamily="sans-serif-medium"
|
||||||
|
android:gravity="center_vertical|left|end"
|
||||||
|
android:paddingLeft="8dp"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Title" />
|
android:textAppearance="@style/TextAppearance.AppCompat.Title"
|
||||||
|
android:textColor="?android:textColorSecondary"
|
||||||
|
android:textSize="12sp"
|
||||||
|
tools:ignore="RtlHardcoded,RtlSymmetry" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/player_text"
|
android:id="@+id/player_song_total_time"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:fontFamily="sans-serif"
|
android:layout_alignParentRight="true"
|
||||||
|
android:fontFamily="sans-serif-medium"
|
||||||
|
android:gravity="center_vertical|right|end"
|
||||||
|
android:paddingRight="8dp"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Caption" />
|
android:textAppearance="@style/TextAppearance.AppCompat.Title"
|
||||||
|
android:textColor="?android:textColorSecondary"
|
||||||
|
android:textSize="12sp"
|
||||||
|
tools:ignore="RtlHardcoded,RtlSymmetry" />
|
||||||
|
|
||||||
</LinearLayout>
|
<SeekBar
|
||||||
|
android:id="@+id/player_progress_slider"
|
||||||
|
style="@style/MusicProgressSlider"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_toLeftOf="@id/player_song_total_time"
|
||||||
|
android:layout_toRightOf="@id/player_song_current_progress"
|
||||||
|
tools:ignore="RtlHardcoded,UnusedAttribute" />
|
||||||
|
|
||||||
<FrameLayout
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/player_media_controller_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="@dimen/media_controller_container_height"
|
||||||
|
tools:ignore="ContentDescription,UnusedAttribute">
|
||||||
|
|
||||||
<RelativeLayout
|
<ImageButton
|
||||||
android:id="@+id/player_media_controller_container"
|
android:id="@+id/player_prev_button"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="72dp"
|
||||||
android:layout_height="@dimen/media_controller_container_height"
|
android:layout_height="72dp"
|
||||||
tools:ignore="ContentDescription,UnusedAttribute">
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginEnd="-8dp"
|
||||||
|
android:layout_marginRight="-8dp"
|
||||||
|
android:layout_toLeftOf="@+id/player_play_pause_fab"
|
||||||
|
android:layout_toStartOf="@+id/player_play_pause_fab"
|
||||||
|
android:background="?round_selector"
|
||||||
|
android:padding="22dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:src="@drawable/ic_skip_previous_white_36dp" />
|
||||||
|
|
||||||
<View
|
<ImageButton
|
||||||
android:id="@+id/player_media_controller_container_background"
|
android:id="@+id/player_next_button"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="72dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="72dp"
|
||||||
android:background="?music_controller_container_color" />
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginLeft="-8dp"
|
||||||
|
android:layout_marginStart="-8dp"
|
||||||
|
android:layout_toEndOf="@+id/player_play_pause_fab"
|
||||||
|
android:layout_toRightOf="@+id/player_play_pause_fab"
|
||||||
|
android:background="?round_selector"
|
||||||
|
android:padding="22dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:src="@drawable/ic_skip_next_white_36dp" />
|
||||||
|
|
||||||
<android.support.v7.widget.CardView
|
<ImageButton
|
||||||
android:id="@+id/player_playback_controller_card"
|
android:id="@+id/player_repeat_button"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="72dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="72dp"
|
||||||
android:layout_margin="16dp"
|
android:layout_alignParentLeft="true"
|
||||||
android:visibility="gone"
|
android:layout_alignParentStart="true"
|
||||||
app:cardBackgroundColor="?music_controller_container_color"
|
android:layout_centerVertical="true"
|
||||||
app:elevation="@dimen/card_elevation" />
|
android:layout_marginLeft="24dp"
|
||||||
|
android:layout_marginStart="24dp"
|
||||||
|
android:background="?round_selector"
|
||||||
|
android:padding="22dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:src="@drawable/ic_repeat_white_36dp" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/player_prev_button"
|
android:id="@+id/player_shuffle_button"
|
||||||
android:layout_width="72dp"
|
android:layout_width="72dp"
|
||||||
android:layout_height="72dp"
|
android:layout_height="72dp"
|
||||||
android:layout_centerVertical="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_marginEnd="-8dp"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_marginRight="-8dp"
|
android:layout_centerVertical="true"
|
||||||
android:layout_toLeftOf="@+id/dummy_fab"
|
android:layout_marginEnd="24dp"
|
||||||
android:layout_toStartOf="@+id/dummy_fab"
|
android:layout_marginRight="24dp"
|
||||||
android:background="?round_selector"
|
android:background="?round_selector"
|
||||||
android:elevation="8dp"
|
android:padding="22dp"
|
||||||
android:padding="22dp"
|
android:scaleType="fitCenter"
|
||||||
android:scaleType="fitCenter"
|
android:src="@drawable/ic_shuffle_white_36dp" />
|
||||||
android:src="@drawable/ic_skip_previous_white_36dp" />
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/player_next_button"
|
|
||||||
android:layout_width="72dp"
|
|
||||||
android:layout_height="72dp"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_marginLeft="-8dp"
|
|
||||||
android:layout_marginStart="-8dp"
|
|
||||||
android:layout_toEndOf="@+id/dummy_fab"
|
|
||||||
android:layout_toRightOf="@+id/dummy_fab"
|
|
||||||
android:background="?round_selector"
|
|
||||||
android:elevation="8dp"
|
|
||||||
android:padding="22dp"
|
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:src="@drawable/ic_skip_next_white_36dp" />
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/player_repeat_button"
|
|
||||||
android:layout_width="72dp"
|
|
||||||
android:layout_height="72dp"
|
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_marginLeft="24dp"
|
|
||||||
android:layout_marginStart="24dp"
|
|
||||||
android:background="?round_selector"
|
|
||||||
android:elevation="8dp"
|
|
||||||
android:padding="22dp"
|
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:src="@drawable/ic_repeat_white_36dp" />
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/player_shuffle_button"
|
|
||||||
android:layout_width="72dp"
|
|
||||||
android:layout_height="72dp"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:layout_marginEnd="24dp"
|
|
||||||
android:layout_marginRight="24dp"
|
|
||||||
android:background="?round_selector"
|
|
||||||
android:elevation="8dp"
|
|
||||||
android:padding="22dp"
|
|
||||||
android:scaleType="fitCenter"
|
|
||||||
android:src="@drawable/ic_shuffle_white_36dp" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/dummy_fab"
|
|
||||||
android:layout_width="56dp"
|
|
||||||
android:layout_height="56dp"
|
|
||||||
android:layout_centerInParent="true"
|
|
||||||
android:visibility="invisible" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<android.support.design.widget.FloatingActionButton
|
<android.support.design.widget.FloatingActionButton
|
||||||
android:id="@+id/player_play_pause_fab"
|
android:id="@+id/player_play_pause_fab"
|
||||||
style="@style/PlayPauseFab"
|
style="@style/PlayPauseFab"
|
||||||
android:layout_gravity="center" />
|
android:layout_centerInParent="true" />
|
||||||
|
|
||||||
</FrameLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
@ -5,36 +5,43 @@
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="false">
|
android:focusable="false">
|
||||||
|
|
||||||
<fragment
|
<RelativeLayout
|
||||||
android:id="@+id/player_album_cover_fragment"
|
|
||||||
class="com.kabouzeid.gramophone.ui.fragments.PlayerAlbumCoverFragment"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_above="@+id/playback_controls_fragment"
|
android:orientation="vertical">
|
||||||
tools:layout="@layout/fragment_player_album_cover" />
|
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:layout_alignParentBottom="true"
|
android:id="@+id/player_album_cover_fragment"
|
||||||
android:id="@+id/playback_controls_fragment"
|
class="com.kabouzeid.gramophone.ui.fragments.PlayerAlbumCoverFragment"
|
||||||
class="com.kabouzeid.gramophone.ui.fragments.PlaybackControlsFragment"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_alignParentTop="true"
|
||||||
tools:layout="@layout/fragment_playback_controls" />
|
tools:layout="@layout/fragment_player_album_cover" />
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/playback_controls_fragment"
|
||||||
|
class="com.kabouzeid.gramophone.ui.fragments.PlaybackControlsFragment"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/player_album_cover_fragment"
|
||||||
|
tools:layout="@layout/fragment_playback_controls" />
|
||||||
|
|
||||||
|
<fragment
|
||||||
|
android:id="@+id/playing_info_fragment"
|
||||||
|
class="com.kabouzeid.gramophone.ui.fragments.PlayingInfoFragment"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/playback_controls_fragment"
|
||||||
|
tools:layout="@layout/fragment_playing_info" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
<include layout="@layout/shadow_statusbar_actionbar" />
|
<include layout="@layout/shadow_statusbar_actionbar" />
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/player_status_bar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/status_bar_padding"
|
|
||||||
android:background="@android:color/transparent"
|
|
||||||
android:elevation="@dimen/toolbar_elevation"
|
|
||||||
tools:ignore="UnusedAttribute" />
|
|
||||||
|
|
||||||
<android.support.v7.widget.Toolbar
|
<android.support.v7.widget.Toolbar
|
||||||
android:id="@+id/player_toolbar"
|
android:id="@+id/player_toolbar"
|
||||||
style="@style/Toolbar"
|
style="@style/Toolbar"
|
||||||
android:layout_below="@id/player_status_bar"
|
android:layout_marginTop="@dimen/status_bar_padding"
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
tools:ignore="UnusedAttribute" />
|
tools:ignore="UnusedAttribute" />
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,11 @@
|
||||||
android:layout_above="@id/player_footer_frame"
|
android:layout_above="@id/player_footer_frame"
|
||||||
android:background="@android:color/black">
|
android:background="@android:color/black">
|
||||||
|
|
||||||
<com.kabouzeid.gramophone.views.SquareIfPlaceImageView
|
<com.kabouzeid.gramophone.views.WidthFitSquareImageView
|
||||||
android:id="@+id/player_image"
|
android:id="@+id/player_image"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_gravity="center"
|
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
android:src="@drawable/default_album_art"
|
|
||||||
tools:ignore="ContentDescription,UnusedAttribute" />
|
tools:ignore="ContentDescription,UnusedAttribute" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
|
|
||||||
37
app/src/main/res/layout/fragment_playing_info.xml
Normal file
37
app/src/main/res/layout/fragment_playing_info.xml
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
<FrameLayout
|
||||||
|
android:paddingLeft="16dp"
|
||||||
|
android:paddingRight="16dp"
|
||||||
|
android:id="@+id/player_footer"
|
||||||
|
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="wrap_content">
|
||||||
|
|
||||||
|
<android.support.v7.widget.CardView
|
||||||
|
android:layout_marginBottom="-18dp"
|
||||||
|
app:cardUseCompatPadding="true"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:cardBackgroundColor="?cardBackgroundColor"
|
||||||
|
app:cardElevation="@dimen/card_elevation">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<include layout="@layout/item_list" />
|
||||||
|
|
||||||
|
<include layout="@layout/item_list" />
|
||||||
|
|
||||||
|
<include layout="@layout/item_list" />
|
||||||
|
|
||||||
|
<include layout="@layout/item_list" />
|
||||||
|
|
||||||
|
<include layout="@layout/item_list" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</android.support.v7.widget.CardView>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
@ -1,23 +1,24 @@
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.percent.PercentFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/header"
|
android:id="@+id/header"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/navigation_drawer_header_height"
|
android:layout_height="wrap_content"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:foreground="?rect_selector">
|
android:foreground="?rect_selector">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/image"
|
android:id="@+id/image"
|
||||||
android:layout_width="match_parent"
|
app:layout_widthPercent="100%"
|
||||||
android:layout_height="match_parent"
|
app:layout_aspectRatio="178%"
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
android:src="@drawable/default_album_art"
|
android:src="@drawable/default_album_art"
|
||||||
android:transitionName="@string/transition_album_art"
|
android:transitionName="@string/transition_album_art"
|
||||||
tools:ignore="UnusedAttribute" />
|
tools:ignore="ContentDescription,UnusedAttribute" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="56dp"
|
||||||
android:layout_gravity="bottom"
|
android:layout_gravity="bottom"
|
||||||
android:background="@drawable/shadow_up" />
|
android:background="@drawable/shadow_up" />
|
||||||
|
|
||||||
|
|
@ -55,4 +56,4 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</FrameLayout>
|
</android.support.percent.PercentFrameLayout>
|
||||||
|
|
@ -23,7 +23,6 @@
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="MusicProgressSlider" parent="MusicProgressSliderParent">
|
<style name="MusicProgressSlider" parent="MusicProgressSliderParent">
|
||||||
<item name="android:elevation">2dp</item>
|
|
||||||
<item name="android:padding">0dp</item>
|
<item name="android:padding">0dp</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -205,4 +205,7 @@
|
||||||
<string name="aleksandar_tesic_summary">For helping me with the design.</string>
|
<string name="aleksandar_tesic_summary">For helping me with the design.</string>
|
||||||
<string name="website">Website</string>
|
<string name="website">Website</string>
|
||||||
<string name="loading_products">Loading products…</string>
|
<string name="loading_products">Loading products…</string>
|
||||||
|
|
||||||
|
<!-- TODO: Remove or change this placeholder text -->
|
||||||
|
<string name="hello_blank_fragment">Hello blank fragment</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ buildscript {
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:1.3.1'
|
classpath 'com.android.tools.build:gradle:1.5.0'
|
||||||
classpath 'com.github.triplet.gradle:play-publisher:1.1.3'
|
classpath 'com.github.triplet.gradle:play-publisher:1.1.3'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-2.9-all.zip
|
||||||
Loading…
Add table
Add a link
Reference in a new issue