Added circular action buttons
This commit is contained in:
parent
8b6a53fb88
commit
29010b857e
|
@ -0,0 +1,87 @@
|
|||
package de.danoeh.antennapod.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class CircularProgressBar extends View {
|
||||
private static final float EPSILON = 0.005f;
|
||||
|
||||
private final Paint paintBackground = new Paint();
|
||||
private final Paint paintProgress = new Paint();
|
||||
private float percentage = 0;
|
||||
private float targetPercentage = 0;
|
||||
private Object tag = null;
|
||||
|
||||
public CircularProgressBar(Context context) {
|
||||
super(context);
|
||||
setup();
|
||||
}
|
||||
|
||||
public CircularProgressBar(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setup();
|
||||
}
|
||||
|
||||
public CircularProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
setup();
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
paintBackground.setAntiAlias(true);
|
||||
paintBackground.setStyle(Paint.Style.STROKE);
|
||||
|
||||
paintProgress.setAntiAlias(true);
|
||||
paintProgress.setStyle(Paint.Style.STROKE);
|
||||
paintProgress.setStrokeCap(Paint.Cap.ROUND);
|
||||
|
||||
int[] colorAttrs = new int[] { android.R.attr.textColorPrimary, android.R.attr.textColorSecondary };
|
||||
TypedArray a = getContext().obtainStyledAttributes(colorAttrs);
|
||||
paintProgress.setColor(a.getColor(0, 0xffffffff));
|
||||
paintBackground.setColor(a.getColor(1, 0xffffffff));
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the percentage to be displayed.
|
||||
* @param percentage Number from 0 to 1
|
||||
* @param tag When the tag is the same as last time calling setPercentage, the update is animated
|
||||
*/
|
||||
public void setPercentage(float percentage, Object tag) {
|
||||
targetPercentage = percentage;
|
||||
|
||||
if (tag == null || !tag.equals(this.tag)) {
|
||||
// Do not animate
|
||||
this.percentage = percentage;
|
||||
this.tag = tag;
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
float padding = getHeight() * 0.06f;
|
||||
paintBackground.setStrokeWidth(getHeight() * 0.02f);
|
||||
paintProgress.setStrokeWidth(padding);
|
||||
RectF bounds = new RectF(padding, padding, getWidth() - padding, getHeight() - padding);
|
||||
canvas.drawArc(bounds, 0, 360, false, paintBackground);
|
||||
|
||||
if (percentage > EPSILON && 1 - percentage > EPSILON) {
|
||||
canvas.drawArc(bounds, -90, percentage * 360, false, paintProgress);
|
||||
}
|
||||
|
||||
if (Math.abs(percentage - targetPercentage) > EPSILON) {
|
||||
float delta = Math.min(0.02f, Math.abs(targetPercentage - percentage));
|
||||
percentage += delta * ((targetPercentage - percentage) > 0 ? 1f : -1f);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,17 +3,14 @@ package de.danoeh.antennapod.view;
|
|||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.text.Layout;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import androidx.core.view.LayoutInflaterCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.joanzapata.iconify.Iconify;
|
||||
import de.danoeh.antennapod.R;
|
||||
|
@ -55,6 +52,7 @@ public class EpisodeItemViewHolder extends RecyclerView.ViewHolder
|
|||
public final ImageView isFavorite;
|
||||
private final ProgressBar progressBar;
|
||||
public final ImageButton butSecondary;
|
||||
private final CircularProgressBar secondaryActionProgress;
|
||||
private final MainActivity activity;
|
||||
private final TextView separatorIcons;
|
||||
|
||||
|
@ -82,6 +80,7 @@ public class EpisodeItemViewHolder extends RecyclerView.ViewHolder
|
|||
isFavorite = itemView.findViewById(R.id.isFavorite);
|
||||
size = itemView.findViewById(R.id.size);
|
||||
separatorIcons = itemView.findViewById(R.id.separatorIcons);
|
||||
secondaryActionProgress = itemView.findViewById(R.id.secondaryActionProgress);
|
||||
itemView.setTag(this);
|
||||
}
|
||||
|
||||
|
@ -106,15 +105,17 @@ public class EpisodeItemViewHolder extends RecyclerView.ViewHolder
|
|||
isInQueue.setVisibility(item.isTagged(FeedItem.TAG_QUEUE) ? View.VISIBLE : View.GONE);
|
||||
itemView.setAlpha(item.isPlayed() /*&& makePlayedItemsTransparent*/ ? 0.5f : 1.0f);
|
||||
|
||||
if (item.getMedia() != null) {
|
||||
bind(item.getMedia());
|
||||
}
|
||||
|
||||
ItemActionButton actionButton = ItemActionButton.forItem(item, true);
|
||||
actionButton.configure(butSecondary, activity);
|
||||
butSecondary.setFocusable(false);
|
||||
butSecondary.setTag(item);
|
||||
|
||||
if (item.getMedia() != null) {
|
||||
bind(item.getMedia());
|
||||
} else {
|
||||
secondaryActionProgress.setPercentage(0, item);
|
||||
}
|
||||
|
||||
new CoverLoader(activity)
|
||||
.withUri(ImageResourceUtils.getImageLocation(item))
|
||||
.withFallbackUri(item.getFeed().getImageLocation())
|
||||
|
@ -133,28 +134,27 @@ public class EpisodeItemViewHolder extends RecyclerView.ViewHolder
|
|||
container.setBackgroundColor(Color.TRANSPARENT);
|
||||
}
|
||||
|
||||
final DownloadRequest downloadRequest = DownloadRequester.getInstance().getRequestFor(media);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
position.setVisibility(View.GONE);
|
||||
if (downloadRequest != null) {
|
||||
position.setText(Converter.byteToString(downloadRequest.getSoFar()));
|
||||
if (downloadRequest.getSize() > 0) {
|
||||
duration.setText(Converter.byteToString(downloadRequest.getSize()));
|
||||
} else {
|
||||
duration.setText(Converter.byteToString(media.getSize()));
|
||||
}
|
||||
progressBar.setProgress(downloadRequest.getProgressPercent());
|
||||
if (DownloadRequester.getInstance().isDownloadingFile(media)) {
|
||||
final DownloadRequest downloadRequest = DownloadRequester.getInstance().getRequestFor(media);
|
||||
float percent = 0.01f * downloadRequest.getProgressPercent();
|
||||
secondaryActionProgress.setPercentage(Math.max(percent, 0.01f), item);
|
||||
} else if (media.isDownloaded()) {
|
||||
secondaryActionProgress.setPercentage(1, item); // Do not animate 100% -> 0%
|
||||
} else {
|
||||
secondaryActionProgress.setPercentage(0, item); // Animate X% -> 0%
|
||||
}
|
||||
|
||||
if (media.getDuration() > 0
|
||||
&& (item.getState() == FeedItem.State.PLAYING || item.getState() == FeedItem.State.IN_PROGRESS)) {
|
||||
int progress = (int) (100.0 * media.getPosition() / media.getDuration());
|
||||
progressBar.setProgress(progress);
|
||||
position.setText(Converter.getDurationStringLong(media.getPosition()));
|
||||
duration.setText(Converter.getDurationStringLong(media.getDuration()));
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
position.setVisibility(View.VISIBLE);
|
||||
} else if (item.getState() == FeedItem.State.PLAYING || item.getState() == FeedItem.State.IN_PROGRESS) {
|
||||
if (media.getDuration() > 0) {
|
||||
int progress = (int) (100.0 * media.getPosition() / media.getDuration());
|
||||
progressBar.setProgress(progress);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
position.setVisibility(View.VISIBLE);
|
||||
position.setText(Converter.getDurationStringLong(media.getPosition()));
|
||||
duration.setText(Converter.getDurationStringLong(media.getDuration()));
|
||||
}
|
||||
} else {
|
||||
progressBar.setVisibility(View.GONE);
|
||||
position.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (media.getSize() > 0) {
|
||||
|
|
|
@ -190,8 +190,6 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/vertical_list_divider"/>
|
||||
|
||||
<include layout="@layout/secondary_action"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -1,12 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/butSecondaryAction"
|
||||
android:layout_width="@dimen/listview_secondary_button_width"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:focusableInTouchMode="false"
|
||||
tools:ignore="ContentDescription"
|
||||
tools:src="@sample/secondaryaction" />
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginEnd="16dp">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/butSecondaryAction"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:layout_gravity="center"
|
||||
android:focusableInTouchMode="false"
|
||||
tools:ignore="ContentDescription"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
tools:src="@sample/secondaryaction"/>
|
||||
|
||||
<de.danoeh.antennapod.view.CircularProgressBar
|
||||
android:id="@+id/secondaryActionProgress"
|
||||
android:layout_width="40dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_height="40dp"/>
|
||||
</FrameLayout>
|
||||
|
|
Loading…
Reference in New Issue