Added circular action buttons

This commit is contained in:
ByteHamster 2020-02-05 11:21:30 +01:00
parent 8b6a53fb88
commit 29010b857e
4 changed files with 139 additions and 40 deletions

View File

@ -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();
}
}
}

View File

@ -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) {

View File

@ -190,8 +190,6 @@
</LinearLayout>
<include layout="@layout/vertical_list_divider"/>
<include layout="@layout/secondary_action"/>
</LinearLayout>

View File

@ -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>