Added collapsing feed info

This commit is contained in:
ByteHamster 2020-03-12 22:11:07 +01:00
parent 7f4d43deb1
commit 32dd30705a
8 changed files with 406 additions and 185 deletions

View File

@ -141,6 +141,7 @@ dependencies {
implementation "androidx.preference:preference:1.1.0" implementation "androidx.preference:preference:1.1.0"
implementation "androidx.gridlayout:gridlayout:1.0.0" implementation "androidx.gridlayout:gridlayout:1.0.0"
implementation "androidx.recyclerview:recyclerview:1.0.0" implementation "androidx.recyclerview:recyclerview:1.0.0"
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
implementation "androidx.media:media:1.1.0" implementation "androidx.media:media:1.1.0"
implementation "com.google.android.material:material:1.0.0" implementation "com.google.android.material:material:1.0.0"
annotationProcessor "androidx.annotation:annotation:1.1.0" annotationProcessor "androidx.annotation:annotation:1.1.0"

View File

@ -368,8 +368,6 @@ public class OnlineFeedViewActivity extends AppCompatActivity {
ImageView cover = findViewById(R.id.imgvCover); ImageView cover = findViewById(R.id.imgvCover);
ImageView headerBackground = findViewById(R.id.imgvBackground); ImageView headerBackground = findViewById(R.id.imgvBackground);
findViewById(R.id.butShowInfo).setVisibility(View.INVISIBLE);
findViewById(R.id.butShowSettings).setVisibility(View.INVISIBLE);
headerBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000)); headerBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000));
TextView title = findViewById(R.id.txtvTitle); TextView title = findViewById(R.id.txtvTitle);
TextView author = findViewById(R.id.txtvAuthor); TextView author = findViewById(R.id.txtvAuthor);

View File

@ -29,6 +29,8 @@ import androidx.core.view.MenuItemCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.RequestOptions;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import com.joanzapata.iconify.Iconify; import com.joanzapata.iconify.Iconify;
import com.joanzapata.iconify.widget.IconTextView; import com.joanzapata.iconify.widget.IconTextView;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
@ -58,12 +60,14 @@ import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.FeedItemPermutors; import de.danoeh.antennapod.core.util.FeedItemPermutors;
import de.danoeh.antennapod.core.util.FeedItemUtil; import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.core.util.Optional; import de.danoeh.antennapod.core.util.Optional;
import de.danoeh.antennapod.core.util.ThemeUtils;
import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil; import de.danoeh.antennapod.core.util.gui.MoreContentListFooterUtil;
import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment; import de.danoeh.antennapod.dialog.EpisodesApplyActionFragment;
import de.danoeh.antennapod.dialog.RenameFeedDialog; import de.danoeh.antennapod.dialog.RenameFeedDialog;
import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler; import de.danoeh.antennapod.menuhandler.FeedItemMenuHandler;
import de.danoeh.antennapod.menuhandler.FeedMenuHandler; import de.danoeh.antennapod.menuhandler.FeedMenuHandler;
import de.danoeh.antennapod.menuhandler.MenuItemUtils; import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.view.ToolbarIconTintManager;
import io.reactivex.Observable; import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable; import io.reactivex.disposables.Disposable;
@ -86,19 +90,23 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
private AdapterView.AdapterContextMenuInfo lastMenuInfo = null; private AdapterView.AdapterContextMenuInfo lastMenuInfo = null;
private MoreContentListFooterUtil listFooter; private MoreContentListFooterUtil listFooter;
private long feedID; private ProgressBar progressBar;
private Feed feed; private ListView listView;
private boolean headerCreated = false;
private boolean isUpdatingFeed;
private TextView txtvTitle; private TextView txtvTitle;
private IconTextView txtvFailure; private IconTextView txtvFailure;
private ImageView imgvBackground; private ImageView imgvBackground;
private ImageView imgvCover; private ImageView imgvCover;
private TextView txtvInformation; private TextView txtvInformation;
private ListView listView; private TextView txtvAuthor;
private ProgressBar progressBar; private ImageButton butShowInfo;
private ImageButton butShowSettings;
private Menu optionsMenu;
private ToolbarIconTintManager iconTintManager;
private long feedID;
private Feed feed;
private boolean headerCreated = false;
private boolean isUpdatingFeed;
private Disposable disposable; private Disposable disposable;
/** /**
@ -140,7 +148,34 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
listView.setOnItemClickListener(this); listView.setOnItemClickListener(this);
registerForContextMenu(listView); registerForContextMenu(listView);
progressBar = root.findViewById(R.id.progLoading); progressBar = root.findViewById(R.id.progLoading);
txtvTitle = root.findViewById(R.id.txtvTitle);
txtvAuthor = root.findViewById(R.id.txtvAuthor);
imgvBackground = root.findViewById(R.id.imgvBackground);
imgvCover = root.findViewById(R.id.imgvCover);
butShowInfo = root.findViewById(R.id.butShowInfo);
butShowSettings = root.findViewById(R.id.butShowSettings);
txtvInformation = root.findViewById(R.id.txtvInformation);
txtvFailure = root.findViewById(R.id.txtvFailure);
AppBarLayout appBar = root.findViewById(R.id.appBar);
CollapsingToolbarLayout collapsingToolbar = root.findViewById(R.id.collapsing_toolbar);
iconTintManager = new ToolbarIconTintManager(getContext(), toolbar, collapsingToolbar) {
@Override
protected void doTint(Context themedContext) {
if (optionsMenu == null) {
return;
}
optionsMenu.findItem(R.id.sort_items)
.setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.ic_sort));
optionsMenu.findItem(R.id.filter_items)
.setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.ic_filter));
optionsMenu.findItem(R.id.refresh_item)
.setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.navigation_refresh));
optionsMenu.findItem(R.id.action_search)
.setIcon(ThemeUtils.getDrawableFromAttr(themedContext, R.attr.action_search));
}
};
appBar.addOnOffsetChangedListener(iconTintManager);
EventBus.getDefault().register(this); EventBus.getDefault().register(this);
loadItems(); loadItems();
return root; return root;
@ -171,8 +206,9 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
return; return;
} }
super.onCreateOptionsMenu(menu, inflater); super.onCreateOptionsMenu(menu, inflater);
optionsMenu = menu;
FeedMenuHandler.onCreateOptionsMenu(inflater, menu); FeedMenuHandler.onCreateOptionsMenu(inflater, menu);
iconTintManager.updateTint();
MenuItem searchItem = menu.findItem(R.id.action_search); MenuItem searchItem = menu.findItem(R.id.action_search);
final SearchView sv = (SearchView) MenuItemCompat.getActionView(searchItem); final SearchView sv = (SearchView) MenuItemCompat.getActionView(searchItem);
@ -285,9 +321,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
super.onCreateContextMenu(menu, v, menuInfo); super.onCreateContextMenu(menu, v, menuInfo);
AdapterView.AdapterContextMenuInfo adapterInfo = (AdapterView.AdapterContextMenuInfo) menuInfo; AdapterView.AdapterContextMenuInfo adapterInfo = (AdapterView.AdapterContextMenuInfo) menuInfo;
// because of addHeaderView(), positions are increased by 1! FeedItem item = (FeedItem) itemAccess.getItem(adapterInfo.position);
FeedItem item = (FeedItem) itemAccess.getItem(adapterInfo.position - 1);
MenuInflater inflater = getActivity().getMenuInflater(); MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.feeditemlist_context, menu); inflater.inflate(R.menu.feeditemlist_context, menu);
@ -305,8 +339,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
if (menuInfo == null) { if (menuInfo == null) {
menuInfo = lastMenuInfo; menuInfo = lastMenuInfo;
} }
// because of addHeaderView(), positions are increased by 1! FeedItem selectedItem = feed.getItemAtIndex(menuInfo.position);
FeedItem selectedItem = feed.getItemAtIndex(menuInfo.position - 1);
if (selectedItem == null) { if (selectedItem == null) {
Log.i(TAG, "Selected item at position " + menuInfo.position + " was null, ignoring selection"); Log.i(TAG, "Selected item at position " + menuInfo.position + " was null, ignoring selection");
@ -321,7 +354,6 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
if (adapter == null) { if (adapter == null) {
return; return;
} }
position -= listView.getHeaderViewsCount();
MainActivity activity = (MainActivity) getActivity(); MainActivity activity = (MainActivity) getActivity();
long[] ids = FeedItemUtil.getIds(feed.getItems()); long[] ids = FeedItemUtil.getIds(feed.getItems());
activity.loadChildFragment(ItemPagerFragment.newInstance(ids, position)); activity.loadChildFragment(ItemPagerFragment.newInstance(ids, position));
@ -370,7 +402,6 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
} }
private void updateUi() { private void updateUi() {
refreshHeaderView();
loadItems(); loadItems();
updateProgressBarVisibility(); updateProgressBarVisibility();
} }
@ -388,6 +419,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
public void onFeedListChanged(FeedListUpdateEvent event) { public void onFeedListChanged(FeedListUpdateEvent event) {
if (event.contains(feed)) { if (event.contains(feed)) {
refreshHeaderView();
updateUi(); updateUi();
} }
} }
@ -399,7 +431,6 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
if (listFooter != null) { if (listFooter != null) {
listFooter.setLoadingState(DownloadRequester.getInstance().isDownloadingFeeds()); listFooter.setLoadingState(DownloadRequester.getInstance().isDownloadingFeeds());
} }
} }
private void displayList() { private void displayList() {
@ -409,12 +440,10 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
} }
if (adapter == null) { if (adapter == null) {
listView.setAdapter(null); listView.setAdapter(null);
setupHeaderView();
setupFooterView(); setupFooterView();
adapter = new FeedItemlistAdapter((MainActivity) getActivity(), itemAccess, false, true); adapter = new FeedItemlistAdapter((MainActivity) getActivity(), itemAccess, false, true);
listView.setAdapter(adapter); listView.setAdapter(adapter);
} }
refreshHeaderView();
listView.setVisibility(View.VISIBLE); listView.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE); progressBar.setVisibility(View.GONE);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
@ -438,6 +467,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
txtvFailure.setVisibility(View.GONE); txtvFailure.setVisibility(View.GONE);
} }
txtvTitle.setText(feed.getTitle()); txtvTitle.setText(feed.getTitle());
txtvAuthor.setText(feed.getAuthor());
if (feed.getItemFilter() != null) { if (feed.getItemFilter() != null) {
FeedItemFilter filter = feed.getItemFilter(); FeedItemFilter filter = feed.getItemFilter();
if (filter.getValues().length > 0) { if (filter.getValues().length > 0) {
@ -461,28 +491,12 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
Log.e(TAG, "Unable to setup listview: recyclerView = null or feed = null"); Log.e(TAG, "Unable to setup listview: recyclerView = null or feed = null");
return; return;
} }
LayoutInflater inflater = (LayoutInflater) if (headerCreated) {
getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); return;
View header = inflater.inflate(R.layout.feeditemlist_header, listView, false); }
listView.addHeaderView(header);
txtvTitle = header.findViewById(R.id.txtvTitle);
TextView txtvAuthor = header.findViewById(R.id.txtvAuthor);
imgvBackground = header.findViewById(R.id.imgvBackground);
imgvCover = header.findViewById(R.id.imgvCover);
ImageButton butShowInfo = header.findViewById(R.id.butShowInfo);
ImageButton butShowSettings = header.findViewById(R.id.butShowSettings);
txtvInformation = header.findViewById(R.id.txtvInformation);
txtvFailure = header.findViewById(R.id.txtvFailure);
txtvTitle.setText(feed.getTitle());
txtvAuthor.setText(feed.getAuthor());
// https://github.com/bumptech/glide/issues/529 // https://github.com/bumptech/glide/issues/529
imgvBackground.setColorFilter(new LightingColorFilter(0xff828282, 0x000000)); imgvBackground.setColorFilter(new LightingColorFilter(0xff666666, 0x000000));
loadFeedImage();
butShowInfo.setOnClickListener(v -> showFeedInfo()); butShowInfo.setOnClickListener(v -> showFeedInfo());
imgvCover.setOnClickListener(v -> showFeedInfo()); imgvCover.setOnClickListener(v -> showFeedInfo());
butShowSettings.setOnClickListener(v -> { butShowSettings.setOnClickListener(v -> {
@ -492,6 +506,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
} }
}); });
headerCreated = true; headerCreated = true;
refreshHeaderView();
} }
private void showFeedInfo() { private void showFeedInfo() {
@ -575,6 +590,7 @@ public class FeedItemlistFragment extends Fragment implements AdapterView.OnItem
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> { .subscribe(result -> {
feed = result.orElse(null); feed = result.orElse(null);
setupHeaderView();
displayList(); displayList();
}, error -> Log.e(TAG, Log.getStackTraceString(error))); }, error -> Log.e(TAG, Log.getStackTraceString(error)));
} }

View File

@ -0,0 +1,74 @@
package de.danoeh.antennapod.view;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;
import androidx.core.view.NestedScrollingChild;
import androidx.core.view.NestedScrollingChildHelper;
/**
* ListView that can be wrapped in NestedScrollView
* Based on https://stackoverflow.com/a/34920961.
*/
public class NestedScrollingListView extends ListView implements NestedScrollingChild {
private final NestedScrollingChildHelper nestedScrollingChildHelper;
public NestedScrollingListView(Context context) {
super(context);
nestedScrollingChildHelper = new NestedScrollingChildHelper(this);
setNestedScrollingEnabled(true);
}
public NestedScrollingListView(Context context, AttributeSet attrs) {
super(context, attrs);
nestedScrollingChildHelper = new NestedScrollingChildHelper(this);
setNestedScrollingEnabled(true);
}
@Override
public void setNestedScrollingEnabled(boolean enabled) {
nestedScrollingChildHelper.setNestedScrollingEnabled(enabled);
}
@Override
public boolean isNestedScrollingEnabled() {
return nestedScrollingChildHelper.isNestedScrollingEnabled();
}
@Override
public boolean startNestedScroll(int axes) {
return nestedScrollingChildHelper.startNestedScroll(axes);
}
@Override
public void stopNestedScroll() {
nestedScrollingChildHelper.stopNestedScroll();
}
@Override
public boolean hasNestedScrollingParent() {
return nestedScrollingChildHelper.hasNestedScrollingParent();
}
@Override
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed,
int dyUnconsumed, int[] offsetInWindow) {
return nestedScrollingChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed,
dxUnconsumed, dyUnconsumed, offsetInWindow);
}
@Override
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
return nestedScrollingChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
}
@Override
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
return nestedScrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
}
@Override
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
return nestedScrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY);
}
}

View File

@ -0,0 +1,50 @@
package de.danoeh.antennapod.view;
import android.content.Context;
import android.graphics.PorterDuff;
import android.view.ContextThemeWrapper;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.ViewCompat;
import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.CollapsingToolbarLayout;
import de.danoeh.antennapod.R;
public abstract class ToolbarIconTintManager implements AppBarLayout.OnOffsetChangedListener {
private final Context context;
private final CollapsingToolbarLayout collapsingToolbar;
private final Toolbar toolbar;
private boolean isTinted = false;
public ToolbarIconTintManager(Context context, Toolbar toolbar, CollapsingToolbarLayout collapsingToolbar) {
this.context = context;
this.collapsingToolbar = collapsingToolbar;
this.toolbar = toolbar;
}
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int offset) {
boolean tint = (collapsingToolbar.getHeight() + offset) > (2 * ViewCompat.getMinimumHeight(collapsingToolbar));
if (isTinted != tint) {
isTinted = tint;
updateTint();
}
}
public void updateTint() {
if (isTinted) {
doTint(new ContextThemeWrapper(context, R.style.Theme_AntennaPod_Dark));
//toolbar.getNavigationIcon().setColorFilter(0xffffffff, PorterDuff.Mode.SRC_ATOP);
toolbar.getOverflowIcon().setColorFilter(0xffffffff, PorterDuff.Mode.SRC_ATOP);
} else {
doTint(context);
//toolbar.getNavigationIcon().clearColorFilter();
toolbar.getOverflowIcon().clearColorFilter();
}
}
/**
* View expansion was changed. Icons need to be tinted
* @param themedContext ContextThemeWrapper with dark theme while expanded
*/
protected abstract void doTint(Context themedContext);
}

View File

@ -1,27 +1,62 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.coordinatorlayout.widget.CoordinatorLayout
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_width="match_parent"
android:layout_height="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">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="@+id/imgvBackground"
style="@style/BigBlurryBackground"
android:layout_width="match_parent"
android:layout_height="256dp"
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" />
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize" android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme" android:theme="?attr/actionBarTheme"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:id="@+id/toolbar"/> android:id="@+id/toolbar"
app:layout_collapseMode="pin"/>
<ListView android:layout_width="match_parent" </com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<de.danoeh.antennapod.view.NestedScrollingListView
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_below="@id/toolbar"
android:id="@android:id/list" /> android:id="@android:id/list" />
<ProgressBar <ProgressBar
android:id="@+id/progLoading" android:id="@+id/progLoading"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true" android:layout_gravity="center"
android:indeterminateOnly="true" android:indeterminateOnly="true"
android:visibility="gone"/> android:visibility="gone"/>
</RelativeLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,51 +1,76 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/feed_image_bg" android:orientation="vertical">
tools:context="de.danoeh.antennapod.activity.MainActivity"
tools:background="@android:color/darker_gray">
<ImageView <LinearLayout
android:id="@+id/imgvBackground"
style="@style/BigBlurryBackground"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/feeditemlist_header_height" /> android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="16dp"
android:layout_marginBottom="16dp"
android:gravity="center_vertical">
<ImageView <ImageView
android:id="@+id/imgvCover" android:id="@+id/imgvCover"
android:layout_width="@dimen/thumbnail_length_onlinefeedview" android:layout_width="100dp"
android:layout_height="@dimen/thumbnail_length_onlinefeedview" android:layout_height="100dp"
android:layout_alignParentLeft="true" android:layout_marginRight="16dp"
android:layout_alignParentStart="true" android:layout_marginEnd="16dp"
android:layout_alignParentTop="true"
android:layout_centerVertical="true"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:contentDescription="@string/cover_label" android:contentDescription="@string/cover_label"
tools:src="@drawable/ic_antenna" tools:src="@drawable/ic_antenna"
tools:background="@android:color/holo_green_dark"/> tools:background="@android:color/holo_green_dark"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/txtvTitle"
style="@style/AntennaPod.TextView.Heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:shadowColor="@color/black"
android:shadowRadius="2"
android:textColor="@color/white"
tools:text="Podcast title"
tools:background="@android:color/holo_green_dark"/>
<TextView
android:id="@+id/txtvAuthor"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:shadowColor="@color/black"
android:shadowRadius="2"
android:textColor="@color/white"
android:textSize="@dimen/text_size_small"
tools:text="Podcast author"
tools:background="@android:color/holo_green_dark"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton <ImageButton
android:id="@+id/butShowInfo" android:id="@+id/butShowInfo"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="40dp" android:layout_height="40dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="8dp"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:contentDescription="@string/show_info_label" android:contentDescription="@string/show_info_label"
android:src="@drawable/ic_info_white_24dp" android:src="@drawable/ic_info_white_24dp"
tools:background="@android:color/holo_green_dark"/> tools:background="@android:color/holo_green_dark"
android:layout_marginLeft="-8dp"
android:layout_marginStart="-8dp"
android:scaleType="fitXY"
android:padding="8dp"/>
<ImageButton <ImageButton
android:id="@+id/butShowSettings" android:id="@+id/butShowSettings"
@ -55,83 +80,35 @@
android:contentDescription="@string/show_feed_settings_label" android:contentDescription="@string/show_feed_settings_label"
android:src="@drawable/ic_settings_white_24dp" android:src="@drawable/ic_settings_white_24dp"
tools:background="@android:color/holo_green_dark" tools:background="@android:color/holo_green_dark"
android:layout_below="@+id/butShowInfo" android:scaleType="fitXY"
android:layout_marginBottom="16dp" android:padding="8dp"/>
android:layout_marginRight="16dp" </LinearLayout>
android:layout_marginEnd="16dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"/>
<TextView </LinearLayout>
android:id="@+id/txtvTitle"
style="@style/AntennaPod.TextView.Heading"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_toLeftOf="@id/butShowInfo"
android:layout_toStartOf="@id/butShowInfo"
android:layout_toRightOf="@id/imgvCover"
android:layout_toEndOf="@id/imgvCover"
android:ellipsize="end"
android:maxLines="2"
android:shadowColor="@color/black"
android:shadowRadius="3"
android:textColor="@color/white"
tools:text="Podcast title"
tools:background="@android:color/holo_green_dark" />
<TextView </LinearLayout>
android:id="@+id/txtvAuthor"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_below="@id/txtvTitle"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp"
android:layout_toLeftOf="@id/butShowSettings"
android:layout_toStartOf="@id/butShowSettings"
android:layout_toRightOf="@id/imgvCover"
android:layout_toEndOf="@id/imgvCover"
android:ellipsize="end"
android:lines="1"
android:shadowColor="@color/black"
android:shadowRadius="3"
android:textColor="@color/white"
android:textSize="@dimen/text_size_small"
tools:text="Podcast author"
tools:background="@android:color/holo_green_dark"/>
<com.joanzapata.iconify.widget.IconTextView
android:id="@+id/txtvFailure"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/imgvBackground"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:background="@color/download_failed_red"
android:gravity="center"
android:textColor="@color/white"
android:visibility="gone"
android:text="@string/refresh_failed_msg"
tools:text="(!) Last refresh failed"
/>
<TextView <TextView
android:id="@+id/txtvInformation" android:id="@+id/txtvInformation"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/imgvBackground" android:padding="2dp"
android:paddingTop="2dp" android:background="?attr/colorPrimary"
android:paddingBottom="2dp"
android:gravity="center"
android:visibility="gone" android:visibility="gone"
tools:text="(i) Information" android:gravity="center"
/> tools:visibility="visible"
tools:text="(i) Information"/>
</RelativeLayout> <com.joanzapata.iconify.widget.IconTextView
android:id="@+id/txtvFailure"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="2dp"
android:background="@color/download_failed_red"
android:gravity="center"
android:textColor="@color/white"
android:visibility="gone"
android:text="@string/refresh_failed_msg"
tools:visibility="visible"
tools:text="(!) Last refresh failed"/>
</LinearLayout>

View File

@ -3,7 +3,7 @@
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:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent" xmlns:tools="http://schemas.android.com/tools">
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
@ -30,7 +30,77 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<include layout="@layout/feeditemlist_header"/> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/feed_image_bg">
<ImageView
android:id="@+id/imgvBackground"
style="@style/BigBlurryBackground"
android:layout_width="match_parent"
android:layout_height="@dimen/feeditemlist_header_height" />
<ImageView
android:id="@+id/imgvCover"
android:layout_width="@dimen/thumbnail_length_onlinefeedview"
android:layout_height="@dimen/thumbnail_length_onlinefeedview"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_centerVertical="true"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:contentDescription="@string/cover_label"
tools:src="@drawable/ic_antenna"/>
<TextView
android:id="@+id/txtvTitle"
style="@style/AntennaPod.TextView.Heading"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_toRightOf="@id/imgvCover"
android:layout_toEndOf="@id/imgvCover"
android:ellipsize="end"
android:maxLines="2"
android:shadowColor="@color/black"
android:shadowRadius="3"
android:textColor="@color/white"
tools:text="Podcast title" />
<TextView
android:id="@+id/txtvAuthor"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_below="@id/txtvTitle"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_toRightOf="@id/imgvCover"
android:layout_toEndOf="@id/imgvCover"
android:ellipsize="end"
android:lines="1"
android:shadowColor="@color/black"
android:shadowRadius="3"
android:textColor="@color/white"
android:textSize="@dimen/text_size_small"
tools:text="Podcast author"/>
</RelativeLayout>
<Spinner <Spinner
android:id="@+id/spinnerAlternateUrls" android:id="@+id/spinnerAlternateUrls"