Merge pull request #5515 from ByteHamster/feed-statistics-table

Show more detailed feed statistics
This commit is contained in:
ByteHamster 2021-11-02 21:41:44 +01:00 committed by GitHub
commit cf58b364f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 414 additions and 273 deletions

View File

@ -1,13 +1,12 @@
package de.danoeh.antennapod.adapter;
import android.content.Context;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.StatisticsItem;
import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.DateFormatter;
import de.danoeh.antennapod.fragment.FeedStatisticsDialogFragment;
import de.danoeh.antennapod.view.PieChartView;
import java.util.Date;
@ -18,10 +17,12 @@ import java.util.List;
*/
public class PlaybackStatisticsListAdapter extends StatisticsListAdapter {
private final Fragment fragment;
boolean countAll = true;
public PlaybackStatisticsListAdapter(Context context) {
super(context);
public PlaybackStatisticsListAdapter(Fragment fragment) {
super(fragment.getContext());
this.fragment = fragment;
}
public void setCountAll(boolean countAll) {
@ -60,16 +61,9 @@ public class PlaybackStatisticsListAdapter extends StatisticsListAdapter {
holder.value.setText(Converter.shortLocalizedDuration(context, time));
holder.itemView.setOnClickListener(v -> {
AlertDialog.Builder dialog = new AlertDialog.Builder(context);
dialog.setTitle(statsItem.feed.getTitle());
dialog.setMessage(context.getString(R.string.statistics_details_dialog,
countAll ? statsItem.episodesStartedIncludingMarked : statsItem.episodesStarted,
statsItem.episodes, Converter.shortLocalizedDuration(context,
countAll ? statsItem.timePlayedCountAll : statsItem.timePlayed),
Converter.shortLocalizedDuration(context, statsItem.time)));
dialog.setPositiveButton(android.R.string.ok, null);
dialog.show();
FeedStatisticsDialogFragment yourDialogFragment = FeedStatisticsDialogFragment.newInstance(
statsItem.feed.getId(), statsItem.feed.getTitle());
yourDialogFragment.show(fragment.getChildFragmentManager().beginTransaction(), "DialogFragment");
});
}
}

View File

@ -9,7 +9,15 @@ import android.graphics.LightingColorFilter;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
@ -20,55 +28,37 @@ import androidx.appcompat.widget.AppCompatDrawableManager;
import androidx.appcompat.widget.Toolbar;
import androidx.documentfile.provider.DocumentFile;
import androidx.fragment.app.Fragment;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.google.android.material.snackbar.Snackbar;
import com.joanzapata.iconify.Iconify;
import org.apache.commons.lang3.StringUtils;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.dialog.DownloadRequestErrorDialogCreator;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.model.feed.FeedFunding;
import de.danoeh.antennapod.core.glide.ApGlideSettings;
import de.danoeh.antennapod.core.glide.FastBlurTransformation;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBTasks;
import de.danoeh.antennapod.core.storage.DownloadRequestException;
import de.danoeh.antennapod.core.storage.StatisticsItem;
import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.syndication.HtmlToPlainText;
import de.danoeh.antennapod.fragment.preferences.StatisticsFragment;
import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
import de.danoeh.antennapod.model.feed.Feed;
import de.danoeh.antennapod.model.feed.FeedFunding;
import de.danoeh.antennapod.view.ToolbarIconTintManager;
import io.reactivex.Completable;
import io.reactivex.Maybe;
import io.reactivex.MaybeOnSubscribe;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
/**
* Displays information about a feed.
@ -82,24 +72,17 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic
private Feed feed;
private Disposable disposable;
private Disposable disposableStatistics;
private ImageView imgvCover;
private TextView txtvTitle;
private TextView txtvDescription;
private TextView lblStatistics;
private TextView txtvPodcastTime;
private TextView txtvPodcastSpace;
private TextView txtvPodcastEpisodeCount;
private TextView txtvFundingUrl;
private TextView lblSupport;
private Button btnvOpenStatistics;
private TextView txtvUrl;
private TextView txtvAuthorHeader;
private ImageView imgvBackground;
private View infoContainer;
private View header;
private Toolbar toolbar;
private ToolbarIconTintManager iconTintManager;
public static FeedInfoFragment newInstance(Feed feed) {
FeedInfoFragment fragment = new FeedInfoFragment();
@ -137,7 +120,7 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic
AppBarLayout appBar = root.findViewById(R.id.appBar);
CollapsingToolbarLayout collapsingToolbar = root.findViewById(R.id.collapsing_toolbar);
iconTintManager = new ToolbarIconTintManager(getContext(), toolbar, collapsingToolbar) {
ToolbarIconTintManager iconTintManager = new ToolbarIconTintManager(getContext(), toolbar, collapsingToolbar) {
@Override
protected void doTint(Context themedContext) {
toolbar.getMenu().findItem(R.id.visit_website_item)
@ -161,23 +144,20 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic
imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000));
txtvDescription = root.findViewById(R.id.txtvDescription);
lblStatistics = root.findViewById(R.id.lblStatistics);
txtvPodcastSpace = root.findViewById(R.id.txtvPodcastSpaceUsed);
txtvPodcastEpisodeCount = root.findViewById(R.id.txtvPodcastEpisodeCount);
txtvPodcastTime = root.findViewById(R.id.txtvPodcastTime);
btnvOpenStatistics = root.findViewById(R.id.btnvOpenStatistics);
txtvUrl = root.findViewById(R.id.txtvUrl);
lblSupport = root.findViewById(R.id.lblSupport);
txtvFundingUrl = root.findViewById(R.id.txtvFundingUrl);
txtvUrl.setOnClickListener(copyUrlToClipboard);
btnvOpenStatistics.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
StatisticsFragment fragment = new StatisticsFragment();
((MainActivity) getActivity()).loadChildFragment(fragment, TransitionEffect.SLIDE);
}
long feedId = getArguments().getLong(EXTRA_FEED_ID);
getParentFragmentManager().beginTransaction().replace(R.id.statisticsFragmentContainer,
FeedStatisticsFragment.newInstance(feedId, false), "feed_statistics_fragment")
.commitAllowingStateLoss();
root.findViewById(R.id.btnvOpenStatistics).setOnClickListener(view -> {
StatisticsFragment fragment = new StatisticsFragment();
((MainActivity) getActivity()).loadChildFragment(fragment, TransitionEffect.SLIDE);
});
return root;
@ -199,7 +179,6 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic
.subscribe(result -> {
feed = result;
showFeed();
loadStatistics();
}, error -> Log.d(TAG, Log.getStackTraceString(error)), () -> { });
}
@ -274,53 +253,12 @@ public class FeedInfoFragment extends Fragment implements Toolbar.OnMenuItemClic
refreshToolbarState();
}
private void loadStatistics() {
if (disposableStatistics != null) {
disposableStatistics.dispose();
}
disposableStatistics =
Observable.fromCallable(() -> {
List<StatisticsItem> statisticsData = DBReader.getStatistics();
for (StatisticsItem statisticsItem : statisticsData) {
if (statisticsItem.feed.getId() == feed.getId()) {
return statisticsItem;
}
}
return null;
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
txtvPodcastTime.setText(Converter.shortLocalizedDuration(
getContext(), result.timePlayed));
txtvPodcastSpace.setText(Formatter.formatShortFileSize(
getContext(), result.totalDownloadSize));
txtvPodcastEpisodeCount.setText(String.format(Locale.getDefault(),
"%d%s", result.episodesDownloadCount,
getString(R.string.episodes_suffix)));
}, error -> {
Log.d(TAG, Log.getStackTraceString(error));
lblStatistics.setVisibility(View.GONE);
txtvPodcastSpace.setVisibility(View.GONE);
txtvPodcastTime.setVisibility(View.GONE);
txtvPodcastEpisodeCount.setVisibility(View.GONE);
btnvOpenStatistics.setVisibility(View.GONE);
});
}
@Override
public void onDestroy() {
super.onDestroy();
if (disposable != null) {
disposable.dispose();
}
if (disposableStatistics != null) {
disposableStatistics.dispose();
}
}
private void refreshToolbarState() {

View File

@ -0,0 +1,42 @@
package de.danoeh.antennapod.fragment;
import android.app.Dialog;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import de.danoeh.antennapod.R;
public class FeedStatisticsDialogFragment extends DialogFragment {
private static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
private static final String EXTRA_FEED_TITLE = "de.danoeh.antennapod.extra.feedTitle";
public static FeedStatisticsDialogFragment newInstance(long feedId, String feedTitle) {
FeedStatisticsDialogFragment fragment = new FeedStatisticsDialogFragment();
Bundle arguments = new Bundle();
arguments.putLong(EXTRA_FEED_ID, feedId);
arguments.putString(EXTRA_FEED_TITLE, feedTitle);
fragment.setArguments(arguments);
return fragment;
}
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
AlertDialog.Builder dialog = new AlertDialog.Builder(getContext());
dialog.setPositiveButton(android.R.string.ok, null);
dialog.setTitle(getArguments().getString(EXTRA_FEED_TITLE));
dialog.setView(R.layout.feed_statistics_dialog);
return dialog.create();
}
@Override
public void onStart() {
super.onStart();
long feedId = getArguments().getLong(EXTRA_FEED_ID);
getChildFragmentManager().beginTransaction().replace(R.id.statisticsContainer,
FeedStatisticsFragment.newInstance(feedId, true), "feed_statistics_fragment")
.commitAllowingStateLoss();
}
}

View File

@ -0,0 +1,92 @@
package de.danoeh.antennapod.fragment;
import android.os.Bundle;
import android.text.format.Formatter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.StatisticsItem;
import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.databinding.FeedStatisticsBinding;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import java.util.List;
import java.util.Locale;
public class FeedStatisticsFragment extends Fragment {
private static final String EXTRA_FEED_ID = "de.danoeh.antennapod.extra.feedId";
private static final String EXTRA_DETAILED = "de.danoeh.antennapod.extra.detailed";
private long feedId;
private Disposable disposable;
private FeedStatisticsBinding viewBinding;
public static FeedStatisticsFragment newInstance(long feedId, boolean detailed) {
FeedStatisticsFragment fragment = new FeedStatisticsFragment();
Bundle arguments = new Bundle();
arguments.putLong(EXTRA_FEED_ID, feedId);
arguments.putBoolean(EXTRA_DETAILED, detailed);
fragment.setArguments(arguments);
return fragment;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
feedId = getArguments().getLong(EXTRA_FEED_ID);
viewBinding = FeedStatisticsBinding.inflate(inflater);
loadStatistics();
return viewBinding.getRoot();
}
private void loadStatistics() {
disposable =
Observable.fromCallable(() -> {
List<StatisticsItem> statisticsData = DBReader.getStatistics();
for (StatisticsItem statisticsItem : statisticsData) {
if (statisticsItem.feed.getId() == feedId) {
return statisticsItem;
}
}
return null;
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::showStats, Throwable::printStackTrace);
}
private void showStats(StatisticsItem s) {
viewBinding.startedTotalLabel.setText(String.format(Locale.getDefault(), "%d / %d",
s.episodesStarted, s.episodes));
viewBinding.timePlayedLabel.setText(Converter.shortLocalizedDuration(getContext(), s.timePlayed));
viewBinding.durationPlayedLabel.setText(Converter.shortLocalizedDuration(getContext(), s.timePlayedCountAll));
viewBinding.totalDurationLabel.setText(Converter.shortLocalizedDuration(getContext(), s.time));
viewBinding.onDeviceLabel.setText(String.format(Locale.getDefault(), "%d", s.episodesDownloadCount));
viewBinding.spaceUsedLabel.setText(Formatter.formatShortFileSize(getContext(), s.totalDownloadSize));
if (!getArguments().getBoolean(EXTRA_DETAILED)) {
for (int i = 0; i < viewBinding.getRoot().getChildCount(); i++) {
View child = viewBinding.getRoot().getChildAt(i);
if ("detailed".equals(child.getTag())) {
child.setVisibility(View.GONE);
}
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (disposable != null) {
disposable.dispose();
}
}
}

View File

@ -68,7 +68,7 @@ public class PlaybackStatisticsFragment extends Fragment {
View root = inflater.inflate(R.layout.statistics_activity, container, false);
feedStatisticsList = root.findViewById(R.id.statistics_list);
progressBar = root.findViewById(R.id.progressBar);
listAdapter = new PlaybackStatisticsListAdapter(getContext());
listAdapter = new PlaybackStatisticsListAdapter(this);
listAdapter.setCountAll(countAll);
feedStatisticsList.setLayoutManager(new LinearLayoutManager(getContext()));
feedStatisticsList.setAdapter(listAdapter);

View File

@ -0,0 +1,113 @@
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TableRow
android:tag="detailed">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/statistics_episodes_started_total" />
<TextView
android:id="@+id/startedTotalLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
tools:text="0 / 0" />
</TableRow>
<TableRow>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/statistics_time_played" />
<TextView
android:id="@+id/timePlayedLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
tools:text="0 min" />
</TableRow>
<TableRow
android:tag="detailed">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/statistics_duration_played_episodes" />
<TextView
android:id="@+id/durationPlayedLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
tools:text="0 min" />
</TableRow>
<TableRow
android:tag="detailed">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/statistics_total_duration" />
<TextView
android:id="@+id/totalDurationLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
tools:text="0 min" />
</TableRow>
<TableRow>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/statistics_episodes_on_device" />
<TextView
android:id="@+id/onDeviceLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
tools:text="0" />
</TableRow>
<TableRow>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/statistics_space_used" />
<TextView
android:id="@+id/spaceUsedLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
tools:text="0 MB" />
</TableRow>
</TableLayout>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/statisticsContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp" />

View File

@ -1,211 +1,164 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
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"
android:layout_width="match_parent"
android:layout_height="match_parent">
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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/windowBackground"
app:contentScrim="?android:attr/windowBackground"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:scrimAnimationDuration="200">
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/windowBackground"
app:contentScrim="?android:attr/windowBackground"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:scrimAnimationDuration="200">
<ImageView
android:id="@+id/imgvBackground"
style="@style/BigBlurryBackground"
android:layout_width="match_parent"
android:layout_height="232dp"
android:background="@color/image_readability_tint"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.6" />
android:id="@+id/imgvBackground"
android:layout_width="match_parent"
android:layout_height="232dp"
android:background="@color/image_readability_tint"
style="@style/BigBlurryBackground"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.6" />
<include
layout="@layout/feeditemlist_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.6" />
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
layout="@layout/feeditemlist_header"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.6" />
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:layout_collapseMode="pin"
app:navigationContentDescription="@string/toolbar_back_button_content_description"
app:navigationIcon="?homeAsUpIndicator" />
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:layout_collapseMode="pin"
app:navigationContentDescription="@string/toolbar_back_button_content_description"
app:navigationIcon="?homeAsUpIndicator" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingBottom="8dp"
android:scrollbarStyle="outsideOverlay"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingBottom="8dp"
android:scrollbarStyle="outsideOverlay"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:id="@+id/infoContainer"
android:id="@+id/infoContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingHorizontal="@dimen/additional_horizontal_spacing">
<TextView
android:id="@+id/lblUrl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_marginTop="16dp"
android:layout_marginBottom="4dp"
android:text="@string/url_label"
android:textColor="?android:attr/textColorPrimary"
tools:background="@android:color/holo_red_light" />
<TextView
android:id="@+id/txtvUrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingHorizontal="@dimen/additional_horizontal_spacing">
android:background="?attr/selectableItemBackground"
android:maxLines="4"
android:paddingTop="4dp"
android:paddingBottom="4dp"
tools:background="@android:color/holo_green_dark"
tools:text="http://www.example.com/feed" />
<TextView
android:id="@+id/lblUrl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_marginTop="16dp"
android:layout_marginBottom="4dp"
android:text="@string/url_label"
android:textColor="?android:attr/textColorPrimary"
tools:background="@android:color/holo_red_light" />
android:id="@+id/lblSupport"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="4dp"
android:text="@string/support_funding_label"
android:textColor="?android:attr/textColorPrimary"
android:textSize="18sp"
tools:background="@android:color/holo_red_light" />
<TextView
android:id="@+id/txtvUrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:maxLines="4"
android:paddingTop="4dp"
android:paddingBottom="4dp"
tools:background="@android:color/holo_green_dark"
tools:text="http://www.example.com/feed" />
android:id="@+id/txtvFundingUrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="8"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:linksClickable="true"
android:autoLink="web"
tools:background="@android:color/holo_green_dark" />
<TextView
android:id="@+id/lblSupport"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="4dp"
android:text="@string/support_funding_label"
android:textColor="?android:attr/textColorPrimary"
android:textSize="18sp"
tools:background="@android:color/holo_red_light" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_marginTop="16dp"
android:layout_marginBottom="4dp"
android:text="@string/description_label"
android:textColor="?android:attr/textColorPrimary"
tools:background="@android:color/holo_red_light" />
<TextView
android:id="@+id/txtvFundingUrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="8"
android:paddingTop="4dp"
android:paddingBottom="4dp"
android:linksClickable="true"
android:autoLink="web"
tools:background="@android:color/holo_green_dark" />
android:id="@+id/txtvDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/design_time_lorem_ipsum"
android:textIsSelectable="true"
tools:background="@android:color/holo_green_dark" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_marginTop="16dp"
android:layout_marginBottom="4dp"
android:text="@string/description_label"
android:textColor="?android:attr/textColorPrimary"
tools:background="@android:color/holo_red_light" />
android:id="@+id/lblStatistics"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:textSize="18sp"
android:layout_marginBottom="8dp"
android:text="@string/statistics_label"
android:textColor="?android:attr/textColorPrimary"
tools:background="@android:color/holo_red_light" />
<TextView
android:id="@+id/txtvDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/design_time_lorem_ipsum"
android:textIsSelectable="true"
tools:background="@android:color/holo_green_dark" />
<TextView
android:id="@+id/lblStatistics"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:textSize="18sp"
android:layout_marginBottom="8dp"
android:text="@string/statistics_label"
android:textColor="?android:attr/textColorPrimary"
tools:background="@android:color/holo_red_light" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/statistics_listened_for" />
<TextView
android:id="@+id/txtvPodcastTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/statistics_episodes_on_device" />
<TextView
android:id="@+id/txtvPodcastEpisodeCount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/statistics_space_used" />
<TextView
android:id="@+id/txtvPodcastSpaceUsed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp" />
</TableRow>
</TableLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/statisticsFragmentContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btnvOpenStatistics"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="0dp"
android:minHeight="0dp"
android:text="@string/statistics_view_all" />
android:id="@+id/btnvOpenStatistics"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="0dp"
android:minHeight="0dp"
android:text="@string/statistics_view_all"
style="@style/Widget.MaterialComponents.Button.TextButton" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -45,7 +45,6 @@
<!-- Statistics fragment -->
<string name="total_time_listened_to_podcasts">Total time of episodes played:</string>
<string name="statistics_details_dialog">%1$d out of %2$d episodes started.\n\nPlayed %3$s out of %4$s.</string>
<string name="statistics_mode">Statistics mode</string>
<string name="statistics_mode_normal">Calculate duration that was actually played. Playing twice is counted twice, while marking as played is not counted</string>
<string name="statistics_mode_count_all">Sum up all episodes marked as played</string>
@ -707,9 +706,12 @@
<string name="keep_updated">Keep Updated</string>
<string name="keep_updated_summary">Include this podcast when (auto-)refreshing all podcasts</string>
<string name="auto_download_disabled_globally">Auto download is disabled in the main AntennaPod settings</string>
<string name="statistics_listened_for">Listened for:</string>
<string name="statistics_time_played">Time played:</string>
<string name="statistics_total_duration">Total duration (estimate):</string>
<string name="statistics_duration_played_episodes">Duration of played episodes:</string>
<string name="statistics_episodes_on_device">Episodes on the device:</string>
<string name="statistics_space_used">Space used:</string>
<string name="statistics_episodes_started_total">Episodes started/total:</string>
<string name="statistics_view_all">View for all podcasts »</string>
<!-- AntennaPodSP -->