mirror of
https://github.com/clangen/musikcube.git
synced 2025-03-29 19:20:28 +00:00
- Added buffering indicator in seekbar for transcoding streams; disallow
seeks past what's been buffered. - Unified position of buffering indicator in MainMetadataView. Removed fades, they were super subtle and causing layout issues. - Don't show the volume% unless we're in remoting mote
This commit is contained in:
parent
3051ebf813
commit
c5d88afd1c
@ -7,7 +7,6 @@ import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
@ -360,6 +359,7 @@ public class MainActivity extends WebSocketActivityBase {
|
||||
|
||||
seekbar.setMax((int) duration);
|
||||
seekbar.setProgress((int) current);
|
||||
seekbar.setSecondaryProgress((int) playback.getBufferedTime());
|
||||
|
||||
scheduleUpdateTime(false);
|
||||
};
|
||||
|
@ -5,6 +5,7 @@ import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.util.Base64;
|
||||
|
||||
import com.danikula.videocache.CacheListener;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.ExoPlayer;
|
||||
import com.google.android.exoplayer2.ExoPlayerFactory;
|
||||
@ -40,6 +41,7 @@ import okhttp3.Request;
|
||||
public class ExoPlayerWrapper extends PlayerWrapper {
|
||||
private static OkHttpClient audioStreamHttpClient = null;
|
||||
|
||||
private final SharedPreferences prefs;
|
||||
private DataSource.Factory datasources;
|
||||
private ExtractorsFactory extractors;
|
||||
private MediaSource source;
|
||||
@ -47,7 +49,9 @@ public class ExoPlayerWrapper extends PlayerWrapper {
|
||||
private boolean prefetch;
|
||||
private Context context;
|
||||
private long lastPosition = -1;
|
||||
private int percentAvailable = 0;
|
||||
private String originalUri, resolvedUri;
|
||||
private boolean transcoding;
|
||||
|
||||
private void initHttpClient(final String uri) {
|
||||
if (StreamProxy.ENABLED) {
|
||||
@ -56,9 +60,6 @@ public class ExoPlayerWrapper extends PlayerWrapper {
|
||||
|
||||
synchronized (ExoPlayerWrapper.class) {
|
||||
if (audioStreamHttpClient == null) {
|
||||
final SharedPreferences prefs = Application.getInstance()
|
||||
.getSharedPreferences(Prefs.NAME, Context.MODE_PRIVATE);
|
||||
|
||||
final File path = new File(context.getExternalCacheDir(), "audio");
|
||||
|
||||
int diskCacheIndex = prefs.getInt(
|
||||
@ -107,6 +108,8 @@ public class ExoPlayerWrapper extends PlayerWrapper {
|
||||
this.extractors = new DefaultExtractorsFactory();
|
||||
this.player.addListener(eventListener);
|
||||
this.datasources = new DefaultDataSourceFactory(context, Util.getUserAgent(context, "musikdroid"));
|
||||
this.prefs = Application.getInstance().getSharedPreferences(Prefs.NAME, Context.MODE_PRIVATE);
|
||||
this.transcoding = this.prefs.getInt(Prefs.Key.TRANSCODER_BITRATE_INDEX, 0) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -117,6 +120,7 @@ public class ExoPlayerWrapper extends PlayerWrapper {
|
||||
initHttpClient(uri);
|
||||
this.originalUri = uri;
|
||||
this.resolvedUri = StreamProxy.getProxyUrl(context, uri);
|
||||
addCacheListener();
|
||||
this.source = new ExtractorMediaSource(Uri.parse(resolvedUri), datasources, extractors, null, null);
|
||||
this.player.setPlayWhenReady(true);
|
||||
this.player.prepare(this.source);
|
||||
@ -134,6 +138,7 @@ public class ExoPlayerWrapper extends PlayerWrapper {
|
||||
this.originalUri = uri;
|
||||
this.prefetch = true;
|
||||
this.resolvedUri = StreamProxy.getProxyUrl(context, uri);
|
||||
addCacheListener();
|
||||
this.source = new ExtractorMediaSource(Uri.parse(resolvedUri), datasources, extractors, null, null);
|
||||
this.player.setPlayWhenReady(false);
|
||||
this.player.prepare(this.source);
|
||||
@ -182,8 +187,20 @@ public class ExoPlayerWrapper extends PlayerWrapper {
|
||||
this.lastPosition = -1;
|
||||
if (this.player.getPlaybackState() != ExoPlayer.STATE_IDLE) {
|
||||
if (this.player.isCurrentWindowSeekable()) {
|
||||
this.lastPosition = millis;
|
||||
this.player.seekTo(millis);
|
||||
long offset = millis;
|
||||
|
||||
/* if we're transcoding we don't want to seek arbitrarily because it may put
|
||||
a lot of pressure on the backend. just allow seeking up to what we currently
|
||||
have buffered! */
|
||||
if (transcoding && percentAvailable != 100) {
|
||||
/* give ourselves 2% wiggle room! */
|
||||
float percent = (float) Math.max(0, percentAvailable - 2) / 100.0f;
|
||||
long totalMs = this.player.getDuration();
|
||||
long available = (long) ((float) totalMs * percent);
|
||||
offset = Math.min(millis, available);
|
||||
}
|
||||
|
||||
this.player.seekTo(offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -191,21 +208,18 @@ public class ExoPlayerWrapper extends PlayerWrapper {
|
||||
@Override
|
||||
public int getPosition() {
|
||||
Preconditions.throwIfNotOnMainThread();
|
||||
|
||||
return (int) this.player.getCurrentPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDuration() {
|
||||
Preconditions.throwIfNotOnMainThread();
|
||||
|
||||
return (int) this.player.getDuration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateVolume() {
|
||||
Preconditions.throwIfNotOnMainThread();
|
||||
|
||||
this.player.setVolume(getGlobalVolume());
|
||||
}
|
||||
|
||||
@ -214,6 +228,11 @@ public class ExoPlayerWrapper extends PlayerWrapper {
|
||||
Preconditions.throwIfNotOnMainThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBufferedPercent() {
|
||||
return transcoding ? percentAvailable : 100;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
Preconditions.throwIfNotOnMainThread();
|
||||
@ -221,6 +240,7 @@ public class ExoPlayerWrapper extends PlayerWrapper {
|
||||
if (!dead()) {
|
||||
setState(State.Killing);
|
||||
removeActivePlayer(this);
|
||||
removeCacheListener();
|
||||
if (this.player != null) {
|
||||
this.player.setPlayWhenReady(false);
|
||||
this.player.removeListener(eventListener);
|
||||
@ -241,6 +261,31 @@ public class ExoPlayerWrapper extends PlayerWrapper {
|
||||
return (state == State.Killing || state == State.Disposed);
|
||||
}
|
||||
|
||||
private void addCacheListener() {
|
||||
if (StreamProxy.ENABLED) {
|
||||
if (StreamProxy.isCached(this.originalUri)) {
|
||||
percentAvailable = 100;
|
||||
}
|
||||
else {
|
||||
StreamProxy.registerCacheListener(this.cacheListener, this.originalUri);
|
||||
}
|
||||
}
|
||||
else {
|
||||
percentAvailable = 100;
|
||||
}
|
||||
}
|
||||
|
||||
private void removeCacheListener() {
|
||||
if (StreamProxy.ENABLED) {
|
||||
StreamProxy.unregisterCacheListener(this.cacheListener);
|
||||
}
|
||||
}
|
||||
|
||||
private CacheListener cacheListener = (file, uri, percent) -> {
|
||||
//Log.e("CLCLCL", String.format("%d", percent));
|
||||
percentAvailable = percent;
|
||||
};
|
||||
|
||||
private ExoPlayer.EventListener eventListener = new ExoPlayer.EventListener() {
|
||||
@Override
|
||||
public void onTimelineChanged(Timeline timeline, Object manifest) {
|
||||
|
@ -25,6 +25,7 @@ public class MediaPlayerWrapper extends PlayerWrapper {
|
||||
private boolean prefetching;
|
||||
private Context context = Application.getInstance();
|
||||
private SharedPreferences prefs;
|
||||
private int bufferedPercent;
|
||||
|
||||
public MediaPlayerWrapper() {
|
||||
this.prefs = context.getSharedPreferences(Prefs.NAME, Context.MODE_PRIVATE);
|
||||
@ -51,6 +52,7 @@ public class MediaPlayerWrapper extends PlayerWrapper {
|
||||
player.setOnPreparedListener(onPrepared);
|
||||
player.setOnErrorListener(onError);
|
||||
player.setOnCompletionListener(onCompleted);
|
||||
player.setOnBufferingUpdateListener(onBuffering);
|
||||
player.setWakeMode(Application.getInstance(), PowerManager.PARTIAL_WAKE_LOCK);
|
||||
player.prepareAsync();
|
||||
}
|
||||
@ -149,6 +151,11 @@ public class MediaPlayerWrapper extends PlayerWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBufferedPercent() {
|
||||
return bufferedPercent;
|
||||
}
|
||||
|
||||
private boolean isPreparedOrPlaying() {
|
||||
final State state = getState();
|
||||
return state == State.Playing || state == State.Prepared;
|
||||
@ -228,4 +235,8 @@ public class MediaPlayerWrapper extends PlayerWrapper {
|
||||
setState(State.Finished);
|
||||
dispose();
|
||||
};
|
||||
|
||||
private MediaPlayer.OnBufferingUpdateListener onBuffering = (mp, percent) -> {
|
||||
bufferedPercent = percent;
|
||||
};
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ public interface PlaybackService {
|
||||
double getVolume();
|
||||
double getDuration();
|
||||
double getCurrentTime();
|
||||
double getBufferedTime();
|
||||
|
||||
PlaybackState getPlaybackState();
|
||||
|
||||
|
@ -122,6 +122,7 @@ public abstract class PlayerWrapper {
|
||||
public abstract void updateVolume();
|
||||
public abstract void setNextMediaPlayer(final PlayerWrapper wrapper);
|
||||
public abstract void dispose();
|
||||
public abstract int getBufferedPercent();
|
||||
|
||||
public void setOnStateChangedListener(OnStateChangedListener listener) {
|
||||
Preconditions.throwIfNotOnMainThread();
|
||||
|
@ -306,6 +306,11 @@ public class RemotePlaybackService implements PlaybackService {
|
||||
return currentTime.get(track);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBufferedTime() {
|
||||
return getDuration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTrackString(String key, String defaultValue) {
|
||||
if (track.has(key)) {
|
||||
|
@ -104,6 +104,10 @@ public class StreamProxy {
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized boolean isCached(final String url) {
|
||||
return INSTANCE != null && INSTANCE.proxy.isCached(url);
|
||||
}
|
||||
|
||||
public static synchronized String getProxyUrl(final Context context, final String url) {
|
||||
init(context);
|
||||
return ENABLED ? INSTANCE.proxy.getProxyUrl(url) : url;
|
||||
|
@ -416,6 +416,15 @@ public class StreamingPlaybackService implements PlaybackService {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getBufferedTime() {
|
||||
if (context.currentPlayer != null) {
|
||||
float percent = (float) context.currentPlayer.getBufferedPercent() / 100.0f;
|
||||
return percent * (float) context.currentPlayer.getDuration() / 1000.0f; /* ms -> sec */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackListSlidingWindow.QueryFactory getPlaylistQueryFactory() {
|
||||
return this.queryFactory;
|
||||
|
@ -10,8 +10,6 @@ import java.io.IOException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -13,7 +13,6 @@ import android.support.v7.widget.SearchView;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewPropertyAnimator;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
|
||||
@ -122,12 +121,6 @@ public final class Views {
|
||||
editText.setSelection(editText.getText().length());
|
||||
}
|
||||
|
||||
public static ViewPropertyAnimator animateAlpha(final View view, final float value) {
|
||||
final ViewPropertyAnimator animator = view.animate().alpha(value).setDuration(300);
|
||||
animator.start();
|
||||
return animator;
|
||||
}
|
||||
|
||||
public static void enableUpNavigation(final AppCompatActivity activity) {
|
||||
final ActionBar ab = activity.getSupportActionBar();
|
||||
if (ab != null) {
|
||||
|
@ -16,7 +16,6 @@ import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewPropertyAnimator;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
@ -35,10 +34,10 @@ import io.casey.musikcube.remote.playback.Metadata;
|
||||
import io.casey.musikcube.remote.playback.PlaybackService;
|
||||
import io.casey.musikcube.remote.playback.PlaybackServiceFactory;
|
||||
import io.casey.musikcube.remote.playback.PlaybackState;
|
||||
import io.casey.musikcube.remote.playback.StreamingPlaybackService;
|
||||
import io.casey.musikcube.remote.ui.activity.AlbumBrowseActivity;
|
||||
import io.casey.musikcube.remote.ui.activity.TrackListActivity;
|
||||
import io.casey.musikcube.remote.ui.model.AlbumArtModel;
|
||||
import io.casey.musikcube.remote.ui.util.Views;
|
||||
import io.casey.musikcube.remote.util.Strings;
|
||||
import io.casey.musikcube.remote.websocket.Messages;
|
||||
import io.casey.musikcube.remote.websocket.Prefs;
|
||||
@ -55,10 +54,9 @@ public class MainMetadataView extends FrameLayout {
|
||||
private TextView title, artist, album, volume;
|
||||
private TextView titleWithArt, artistAndAlbumWithArt, volumeWithArt;
|
||||
private View mainTrackMetadataWithAlbumArt, mainTrackMetadataNoAlbumArt;
|
||||
private View buffering, bufferingWithArt;
|
||||
private View buffering;
|
||||
private ImageView albumArtImageView;
|
||||
|
||||
private ViewPropertyAnimator metadataAnim1, metadataAnim2;
|
||||
private enum DisplayMode { Artwork, NoArtwork, Stopped }
|
||||
private AlbumArtModel albumArtModel = AlbumArtModel.empty();
|
||||
private DisplayMode lastDisplayMode = DisplayMode.Stopped;
|
||||
@ -107,23 +105,34 @@ public class MainMetadataView extends FrameLayout {
|
||||
final PlaybackService playback = getPlaybackService();
|
||||
|
||||
final boolean buffering = playback.getPlaybackState() == PlaybackState.Buffering;
|
||||
final boolean streaming = playback instanceof StreamingPlaybackService;
|
||||
|
||||
final String artist = playback.getTrackString(Metadata.Track.ARTIST, "");
|
||||
final String album = playback.getTrackString(Metadata.Track.ALBUM, "");
|
||||
final String title = playback.getTrackString(Metadata.Track.TITLE, "");
|
||||
final String volume = getString(R.string.status_volume, Math.round(playback.getVolume() * 100));
|
||||
|
||||
/* we don't display the volume amount when we're streaming -- the system has
|
||||
overlays for drawing volume. */
|
||||
if (streaming) {
|
||||
this.volume.setVisibility(View.GONE);
|
||||
this.volumeWithArt.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
final String volume = getString(R.string.status_volume, Math.round(playback.getVolume() * 100));
|
||||
this.volume.setVisibility(View.VISIBLE);
|
||||
this.volumeWithArt.setVisibility(View.VISIBLE);
|
||||
this.volume.setText(volume);
|
||||
this.volumeWithArt.setText(volume);
|
||||
}
|
||||
|
||||
this.title.setText(Strings.empty(title) ? getString(buffering ? R.string.buffering : R.string.unknown_title) : title);
|
||||
this.artist.setText(Strings.empty(artist) ? getString(buffering ? R.string.buffering : R.string.unknown_artist) : artist);
|
||||
this.album.setText(Strings.empty(album) ? getString(buffering ? R.string.buffering : R.string.unknown_album) : album);
|
||||
this.volume.setText(volume);
|
||||
|
||||
this.rebindAlbumArtistWithArtTextView(playback);
|
||||
this.titleWithArt.setText(Strings.empty(title) ? getString(buffering ? R.string.buffering : R.string.unknown_title) : title);
|
||||
this.volumeWithArt.setText(volume);
|
||||
|
||||
this.buffering.setVisibility(buffering ? View.VISIBLE : View.GONE);
|
||||
this.bufferingWithArt.setVisibility(buffering ? View.VISIBLE : View.GONE);
|
||||
|
||||
boolean albumArtEnabledInSettings = this.prefs.getBoolean(
|
||||
Prefs.Key.ALBUM_ART_ENABLED, Prefs.Default.ALBUM_ART_ENABLED);
|
||||
@ -131,7 +140,8 @@ public class MainMetadataView extends FrameLayout {
|
||||
if (!albumArtEnabledInSettings || Strings.empty(artist) || Strings.empty(album)) {
|
||||
this.albumArtModel = AlbumArtModel.empty();
|
||||
setMetadataDisplayMode(DisplayMode.NoArtwork);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (!this.albumArtModel.is(artist, album)) {
|
||||
this.albumArtModel.destroy();
|
||||
|
||||
@ -158,24 +168,19 @@ public class MainMetadataView extends FrameLayout {
|
||||
private void setMetadataDisplayMode(DisplayMode mode) {
|
||||
lastDisplayMode = mode;
|
||||
|
||||
if (metadataAnim1 != null) {
|
||||
metadataAnim1.cancel();
|
||||
metadataAnim2.cancel();
|
||||
}
|
||||
|
||||
if (mode == DisplayMode.Stopped) {
|
||||
albumArtImageView.setImageDrawable(null);
|
||||
metadataAnim1 = Views.animateAlpha(mainTrackMetadataWithAlbumArt, 0.0f);
|
||||
metadataAnim2 = Views.animateAlpha(mainTrackMetadataNoAlbumArt, 0.0f);
|
||||
mainTrackMetadataWithAlbumArt.setVisibility(View.GONE);
|
||||
mainTrackMetadataNoAlbumArt.setVisibility(View.GONE);
|
||||
}
|
||||
else if (mode == DisplayMode.Artwork) {
|
||||
metadataAnim1 = Views.animateAlpha(mainTrackMetadataWithAlbumArt, 1.0f);
|
||||
metadataAnim2 = Views.animateAlpha(mainTrackMetadataNoAlbumArt, 0.0f);
|
||||
mainTrackMetadataWithAlbumArt.setVisibility(View.VISIBLE);
|
||||
mainTrackMetadataNoAlbumArt.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
albumArtImageView.setImageDrawable(null);
|
||||
metadataAnim1 = Views.animateAlpha(mainTrackMetadataWithAlbumArt, 0.0f);
|
||||
metadataAnim2 = Views.animateAlpha(mainTrackMetadataNoAlbumArt, 1.0f);
|
||||
mainTrackMetadataWithAlbumArt.setVisibility(View.GONE);
|
||||
mainTrackMetadataNoAlbumArt.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,16 +331,11 @@ public class MainMetadataView extends FrameLayout {
|
||||
this.titleWithArt = (TextView) findViewById(R.id.with_art_track_title);
|
||||
this.artistAndAlbumWithArt = (TextView) findViewById(R.id.with_art_artist_and_album);
|
||||
this.volumeWithArt = (TextView) findViewById(R.id.with_art_volume);
|
||||
this.bufferingWithArt = findViewById(R.id.with_art_buffering);
|
||||
|
||||
this.mainTrackMetadataWithAlbumArt = findViewById(R.id.main_track_metadata_with_art);
|
||||
this.mainTrackMetadataNoAlbumArt = findViewById(R.id.main_track_metadata_without_art);
|
||||
this.albumArtImageView = (ImageView) findViewById(R.id.album_art);
|
||||
|
||||
/* these will get faded in as appropriate */
|
||||
this.mainTrackMetadataNoAlbumArt.setAlpha(0.0f);
|
||||
this.mainTrackMetadataWithAlbumArt.setAlpha(0.0f);
|
||||
|
||||
this.album.setOnClickListener((view) -> navigateToCurrentAlbum());
|
||||
this.artist.setOnClickListener((view) -> navigateToCurrentArtist());
|
||||
}
|
||||
|
@ -12,55 +12,61 @@
|
||||
android:scaleType="centerCrop"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/main_track_metadata_with_art"
|
||||
android:background="@color/main_playback_metadata"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingRight="24dp"
|
||||
android:paddingTop="2dp"
|
||||
android:paddingBottom="2dp">
|
||||
android:orientation="vertical">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/with_art_buffering"
|
||||
android:id="@+id/buffering"
|
||||
style="?android:attr/progressBarStyleSmall"
|
||||
android:layout_marginTop="2dp"
|
||||
android:padding="8dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"/>
|
||||
|
||||
<TextView
|
||||
style="@style/LightDropShadow"
|
||||
android:id="@+id/with_art_track_title"
|
||||
android:layout_width="wrap_content"
|
||||
<LinearLayout
|
||||
android:id="@+id/main_track_metadata_with_art"
|
||||
android:background="@color/main_playback_metadata"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center"
|
||||
android:textColor="@color/theme_green"
|
||||
android:text="-"/>
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingRight="24dp"
|
||||
android:paddingTop="2dp"
|
||||
android:paddingBottom="2dp">
|
||||
|
||||
<TextView
|
||||
style="@style/LightDropShadow"
|
||||
android:id="@+id/with_art_artist_and_album"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center"
|
||||
android:textColor="@color/theme_yellow"
|
||||
android:text="-"/>
|
||||
<TextView
|
||||
style="@style/LightDropShadow"
|
||||
android:id="@+id/with_art_track_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center"
|
||||
android:textColor="@color/theme_green"
|
||||
android:text="-"/>
|
||||
|
||||
<TextView
|
||||
style="@style/LightDropShadow"
|
||||
android:id="@+id/with_art_volume"
|
||||
android:textSize="@dimen/text_size_small"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:text=""/>
|
||||
<TextView
|
||||
style="@style/LightDropShadow"
|
||||
android:id="@+id/with_art_artist_and_album"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center"
|
||||
android:textColor="@color/theme_yellow"
|
||||
android:text="-"/>
|
||||
|
||||
<TextView
|
||||
style="@style/LightDropShadow"
|
||||
android:id="@+id/with_art_volume"
|
||||
android:textSize="@dimen/text_size_small"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:text=""/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
@ -74,14 +80,6 @@
|
||||
android:paddingTop="6dp"
|
||||
android:paddingBottom="6dp">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/buffering"
|
||||
style="?android:attr/progressBarStyleSmall"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_title"
|
||||
android:layout_width="wrap_content"
|
||||
|
Loading…
x
Reference in New Issue
Block a user