diff options
7 files changed, 389 insertions, 120 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java b/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java index 08ffdd197..47ac4c757 100644 --- a/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java +++ b/app/src/main/java/de/danoeh/antennapod/adapter/itunes/ItunesAdapter.java @@ -10,6 +10,7 @@ import android.widget.TextView; import com.bumptech.glide.Glide; import com.bumptech.glide.load.engine.DiskCacheStrategy; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -65,6 +66,12 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> { //Set the title viewHolder.titleView.setText(podcast.title); + if(!podcast.feedUrl.contains("itunes.apple.com")) { + viewHolder.urlView.setText(podcast.feedUrl); + viewHolder.urlView.setVisibility(View.VISIBLE); + } else { + viewHolder.urlView.setVisibility(View.GONE); + } //Update the empty imageView with the image from the feed Glide.with(context) @@ -94,6 +101,8 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> { */ public final TextView titleView; + public final TextView urlView; + /** * Constructor @@ -102,6 +111,7 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> { PodcastViewHolder(View view){ coverView = (ImageView) view.findViewById(R.id.imgvCover); titleView = (TextView) view.findViewById(R.id.txtvTitle); + urlView = (TextView) view.findViewById(R.id.txtvUrl); } } @@ -124,16 +134,47 @@ public class ItunesAdapter extends ArrayAdapter<ItunesAdapter.Podcast> { */ public final String feedUrl; + + private Podcast(String title, String imageUrl, String feedUrl) { + this.title = title; + this.imageUrl = imageUrl; + this.feedUrl = feedUrl; + } + + /** + * Constructs a Podcast instance from a iTunes search result + * + * @param json object holding the podcast information + * @throws JSONException + */ + public static Podcast fromSearch(JSONObject json) throws JSONException { + String title = json.getString("collectionName"); + String imageUrl = json.getString("artworkUrl100"); + String feedUrl = json.getString("feedUrl"); + return new Podcast(title, imageUrl, feedUrl); + } + /** - * Constructor. + * Constructs a Podcast instance from iTunes toplist entry * * @param json object holding the podcast information * @throws JSONException */ - public Podcast(JSONObject json) throws JSONException { - title = json.getString("collectionName"); - imageUrl = json.getString("artworkUrl100"); - feedUrl = json.getString("feedUrl"); + public static Podcast fromToplist(JSONObject json) throws JSONException { + String title = json.getJSONObject("title").getString("label"); + String imageUrl = null; + JSONArray images = json.getJSONArray("im:image"); + for(int i=0; imageUrl == null && i < images.length(); i++) { + JSONObject image = images.getJSONObject(i); + String height = image.getJSONObject("attributes").getString("height"); + if(Integer.valueOf(height) >= 100) { + imageUrl = image.getString("label"); + } + } + String feedUrl = "https://itunes.apple.com/lookup?id=" + + json.getJSONObject("id").getJSONObject("attributes").getString("im:id"); + return new Podcast(title, imageUrl, feedUrl); } + } } diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java index e92df4885..eb947dc2b 100644 --- a/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java +++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItunesSearchFragment.java @@ -1,17 +1,23 @@ package de.danoeh.antennapod.fragment; import android.content.Intent; -import android.content.res.Resources; import android.os.Bundle; import android.support.v4.app.Fragment; +import android.support.v4.view.MenuItemCompat; import android.support.v7.widget.SearchView; import android.util.Log; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.AdapterView; +import android.widget.Button; import android.widget.GridView; +import android.widget.ProgressBar; +import android.widget.TextView; +import com.afollestad.materialdialogs.MaterialDialog; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; import com.squareup.okhttp.Response; @@ -25,13 +31,14 @@ import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.OnlineFeedViewActivity; import de.danoeh.antennapod.adapter.itunes.ItunesAdapter; import de.danoeh.antennapod.core.ClientConfig; -import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.service.download.AntennapodHttpClient; +import de.danoeh.antennapod.menuhandler.MenuItemUtils; import rx.Observable; import rx.Subscription; import rx.android.schedulers.AndroidSchedulers; @@ -46,21 +53,22 @@ public class ItunesSearchFragment extends Fragment { private static final String API_URL = "https://itunes.apple.com/search?media=podcast&term=%s"; - /** - * Search input field - */ - private SearchView searchView; /** * Adapter responsible with the search results */ private ItunesAdapter adapter; + private GridView gridView; + private ProgressBar progressBar; + private TextView txtvError; + private Button butRetry; + private TextView txtvEmpty; /** * List of podcasts retreived from the search */ private List<Podcast> searchResults; - + private List<Podcast> topList; private Subscription subscription; /** @@ -70,13 +78,17 @@ public class ItunesSearchFragment extends Fragment { void updateData(List<Podcast> result) { this.searchResults = result; adapter.clear(); - - //ArrayAdapter.addAll() requires minsdk > 10 - for(Podcast p: result) { - adapter.add(p); + if (result != null && result.size() > 0) { + gridView.setVisibility(View.VISIBLE); + txtvEmpty.setVisibility(View.GONE); + for (Podcast p : result) { + adapter.add(p); + } + adapter.notifyDataSetInvalidated(); + } else { + gridView.setVisibility(View.GONE); + txtvEmpty.setVisibility(View.VISIBLE); } - - adapter.notifyDataSetInvalidated(); } /** @@ -89,47 +101,105 @@ public class ItunesSearchFragment extends Fragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - adapter = new ItunesAdapter(getActivity(), new ArrayList<Podcast>()); - + setHasOptionsMenu(true); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment - View view = inflater.inflate(R.layout.fragment_itunes_search, container, false); - GridView gridView = (GridView) view.findViewById(R.id.gridView); + View root = inflater.inflate(R.layout.fragment_itunes_search, container, false); + gridView = (GridView) root.findViewById(R.id.gridView); + adapter = new ItunesAdapter(getActivity(), new ArrayList<>()); gridView.setAdapter(adapter); //Show information about the podcast when the list item is clicked - gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView<?> parent, View view, int position, long id) { - Intent intent = new Intent(getActivity(), - OnlineFeedViewActivity.class); - - //Tell the OnlineFeedViewActivity where to go - String url = searchResults.get(position).feedUrl; - intent.putExtra(OnlineFeedViewActivity.ARG_FEEDURL, url); - + gridView.setOnItemClickListener((parent, view1, position, id) -> { + Podcast podcast = searchResults.get(position); + if (!podcast.feedUrl.contains("itunes.apple.com")) { + Intent intent = new Intent(getActivity(), OnlineFeedViewActivity.class); + intent.putExtra(OnlineFeedViewActivity.ARG_FEEDURL, podcast.feedUrl); intent.putExtra(OnlineFeedViewActivity.ARG_TITLE, "iTunes"); startActivity(intent); + } else { + gridView.setVisibility(View.GONE); + progressBar.setVisibility(View.VISIBLE); + rx.Observable.create((Observable.OnSubscribe<String>) subscriber -> { + OkHttpClient client = AntennapodHttpClient.getHttpClient(); + Request.Builder httpReq = new Request.Builder() + .url(podcast.feedUrl) + .header("User-Agent", ClientConfig.USER_AGENT); + try { + Response response = client.newCall(httpReq.build()).execute(); + if (response.isSuccessful()) { + String resultString = response.body().string(); + JSONObject result = new JSONObject(resultString); + JSONObject results = result.getJSONArray("results").getJSONObject(0); + String feedUrl = results.getString("feedUrl"); + subscriber.onNext(feedUrl); + } else { + String prefix = getString(R.string.error_msg_prefix); + subscriber.onError(new IOException(prefix + response)); + } + } catch (IOException | JSONException e) { + subscriber.onError(e); + } + subscriber.onCompleted(); + }) + .subscribeOn(Schedulers.newThread()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(feedUrl -> { + progressBar.setVisibility(View.GONE); + gridView.setVisibility(View.VISIBLE); + Intent intent = new Intent(getActivity(), OnlineFeedViewActivity.class); + intent.putExtra(OnlineFeedViewActivity.ARG_FEEDURL, feedUrl); + intent.putExtra(OnlineFeedViewActivity.ARG_TITLE, "iTunes"); + startActivity(intent); + }, error -> { + Log.e(TAG, Log.getStackTraceString(error)); + progressBar.setVisibility(View.GONE); + gridView.setVisibility(View.VISIBLE); + String prefix = getString(R.string.error_msg_prefix); + new MaterialDialog.Builder(getActivity()) + .content(prefix + " " + error.getMessage()) + .neutralText(android.R.string.ok) + .show(); + }); } }); + progressBar = (ProgressBar) root.findViewById(R.id.progressBar); + txtvError = (TextView) root.findViewById(R.id.txtvError); + butRetry = (Button) root.findViewById(R.id.butRetry); + txtvEmpty = (TextView) root.findViewById(android.R.id.empty); + + loadToplist(); + + return root; + } - //Configure search input view to be expanded by default with a visible submit button - searchView = (SearchView) view.findViewById(R.id.itunes_search_view); - searchView.setIconifiedByDefault(false); - searchView.setIconified(false); - searchView.setSubmitButtonEnabled(true); - searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public void onDestroy() { + super.onDestroy(); + if (subscription != null) { + subscription.unsubscribe(); + } + adapter = null; + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.itunes_search, menu); + MenuItem searchItem = menu.findItem(R.id.action_search); + final SearchView sv = (SearchView) MenuItemCompat.getActionView(searchItem); + MenuItemUtils.adjustTextColor(getActivity(), sv); + sv.setQueryHint(getString(R.string.search_itunes_label)); + sv.setOnQueryTextListener(new android.support.v7.widget.SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String s) { - //This prevents onQueryTextSubmit() from being called twice when keyboard is used - //to submit the query. - searchView.clearFocus(); + sv.clearFocus(); search(s); - return false; + return true; } @Override @@ -137,21 +207,97 @@ public class ItunesSearchFragment extends Fragment { return false; } }); + MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() { + @Override + public boolean onMenuItemActionExpand(MenuItem item) { + return true; + } - SearchView.SearchAutoComplete textField = (SearchView.SearchAutoComplete) searchView.findViewById(de.danoeh.antennapod.R.id.search_src_text); - if(UserPreferences.getTheme() == de.danoeh.antennapod.R.style.Theme_AntennaPod_Dark) { - textField.setTextColor(Resources.getSystem().getColor(android.R.color.white)); - } else { - textField.setTextColor(Resources.getSystem().getColor(android.R.color.black)); + @Override + public boolean onMenuItemActionCollapse(MenuItem item) { + if(searchResults != null) { + searchResults = null; + updateData(topList); + } + return true; + } + }); + } + + private void loadToplist() { + if (subscription != null) { + subscription.unsubscribe(); } + gridView.setVisibility(View.GONE); + txtvError.setVisibility(View.GONE); + butRetry.setVisibility(View.GONE); + txtvEmpty.setVisibility(View.GONE); + progressBar.setVisibility(View.VISIBLE); + subscription = rx.Observable.create((Observable.OnSubscribe<List<Podcast>>) subscriber -> { + String lang = Locale.getDefault().getLanguage(); + String url = "https://itunes.apple.com/" + lang + "/rss/toppodcasts/limit=25/explicit=true/json"; + OkHttpClient client = AntennapodHttpClient.getHttpClient(); + Request.Builder httpReq = new Request.Builder() + .url(url) + .header("User-Agent", ClientConfig.USER_AGENT); + List<Podcast> results = new ArrayList<>(); + try { + Response response = client.newCall(httpReq.build()).execute(); + if(!response.isSuccessful()) { + // toplist for language does not exist, fall back to united states + url = "https://itunes.apple.com/us/rss/toppodcasts/limit=25/explicit=true/json"; + httpReq = new Request.Builder() + .url(url) + .header("User-Agent", ClientConfig.USER_AGENT); + response = client.newCall(httpReq.build()).execute(); + } + if(response.isSuccessful()) { + String resultString = response.body().string(); + JSONObject result = new JSONObject(resultString); + JSONObject feed = result.getJSONObject("feed"); + JSONArray entries = feed.getJSONArray("entry"); - return view; + for(int i=0; i < entries.length(); i++) { + JSONObject json = entries.getJSONObject(i); + Podcast podcast = Podcast.fromToplist(json); + results.add(podcast); + } + } + else { + String prefix = getString(R.string.error_msg_prefix); + subscriber.onError(new IOException(prefix + response)); + } + } catch (IOException | JSONException e) { + subscriber.onError(e); + } + subscriber.onNext(results); + subscriber.onCompleted(); + }) + .subscribeOn(Schedulers.newThread()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(podcasts -> { + progressBar.setVisibility(View.GONE); + topList = podcasts; + updateData(topList); + }, error -> { + Log.e(TAG, Log.getStackTraceString(error)); + progressBar.setVisibility(View.GONE); + txtvError.setText(error.toString()); + txtvError.setVisibility(View.VISIBLE); + butRetry.setOnClickListener(v -> loadToplist()); + butRetry.setVisibility(View.VISIBLE); + }); } private void search(String query) { if (subscription != null) { subscription.unsubscribe(); } + gridView.setVisibility(View.GONE); + txtvError.setVisibility(View.GONE); + butRetry.setVisibility(View.GONE); + txtvEmpty.setVisibility(View.GONE); + progressBar.setVisibility(View.VISIBLE); subscription = rx.Observable.create((Observable.OnSubscribe<List<Podcast>>) subscriber -> { String encodedQuery = null; try { @@ -181,15 +327,16 @@ public class ItunesSearchFragment extends Fragment { for (int i = 0; i < j.length(); i++) { JSONObject podcastJson = j.getJSONObject(i); - Podcast podcast = new Podcast(podcastJson); + Podcast podcast = Podcast.fromSearch(podcastJson); podcasts.add(podcast); } } else { - subscriber.onError(new IOException("Unexpected error: " + response)); + String prefix = getString(R.string.error_msg_prefix); + subscriber.onError(new IOException(prefix + response)); } } catch (IOException | JSONException e) { - Log.e(TAG, Log.getStackTraceString(e)); + subscriber.onError(e); } subscriber.onNext(podcasts); subscriber.onCompleted(); @@ -197,9 +344,15 @@ public class ItunesSearchFragment extends Fragment { .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(podcasts -> { + progressBar.setVisibility(View.GONE); updateData(podcasts); }, error -> { Log.e(TAG, Log.getStackTraceString(error)); + progressBar.setVisibility(View.GONE); + txtvError.setText(error.toString()); + txtvError.setVisibility(View.VISIBLE); + butRetry.setOnClickListener(v -> search(query)); + butRetry.setVisibility(View.VISIBLE); }); } diff --git a/app/src/main/res/layout/fragment_itunes_search.xml b/app/src/main/res/layout/fragment_itunes_search.xml index e57c59554..0cc13f74c 100644 --- a/app/src/main/res/layout/fragment_itunes_search.xml +++ b/app/src/main/res/layout/fragment_itunes_search.xml @@ -1,26 +1,64 @@ -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" -xmlns:tools="http://schemas.android.com/tools" -android:layout_width="match_parent" -android:layout_height="match_parent" -tools:context="de.danoeh.antennapod.activity.ITunesSearchActivity"> -<android.support.v7.widget.SearchView - android:id="@+id/itunes_search_view" - android:layout_height="wrap_content" +<RelativeLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - /> -<GridView - android:id="@+id/gridView" - android:layout_below="@id/itunes_search_view" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:clipToPadding="false" - android:columnWidth="400dp" - android:gravity="center" - android:horizontalSpacing="8dp" - android:numColumns="auto_fit" - android:paddingBottom="@dimen/list_vertical_padding" - android:paddingTop="@dimen/list_vertical_padding" - android:stretchMode="columnWidth" - android:verticalSpacing="8dp" - tools:listitem="@layout/gpodnet_podcast_listitem" /> + android:layout_height="match_parent"> + + <GridView + android:id="@+id/gridView" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:clipToPadding="false" + android:columnWidth="400dp" + android:gravity="center" + android:horizontalSpacing="8dp" + android:numColumns="auto_fit" + android:paddingBottom="@dimen/list_vertical_padding" + android:paddingTop="@dimen/list_vertical_padding" + android:stretchMode="columnWidth" + android:verticalSpacing="8dp" + tools:listitem="@layout/gpodnet_podcast_listitem" /> + + <TextView + android:id="@id/android:empty" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_centerInParent="true" + android:gravity="center" + android:visibility="gone" + android:text="@string/search_status_no_results" /> + + <ProgressBar + android:id="@+id/progressBar" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerInParent="true" + android:indeterminateOnly="true" + android:visibility="gone"/> + + <TextView + android:id="@+id/txtvError" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerInParent="true" + android:layout_margin="16dp" + android:textAlignment="center" + android:textSize="@dimen/text_size_small" + android:visibility="gone" + tools:visibility="visible" + tools:text="Error message" + tools:background="@android:color/holo_red_light" /> + + <Button + android:id="@+id/butRetry" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_below="@id/txtvError" + android:layout_centerHorizontal="true" + android:layout_margin="16dp" + android:text="@string/retry_label" + android:visibility="gone" + tools:visibility="visible" + tools:background="@android:color/holo_red_light" /> + </RelativeLayout> diff --git a/app/src/main/res/layout/gpodnet_podcast_listitem.xml b/app/src/main/res/layout/gpodnet_podcast_listitem.xml index 84c6c280e..bbe8e65d6 100644 --- a/app/src/main/res/layout/gpodnet_podcast_listitem.xml +++ b/app/src/main/res/layout/gpodnet_podcast_listitem.xml @@ -3,7 +3,11 @@ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="@dimen/listitem_threeline_height" + android:layout_height="wrap_content" + android:paddingTop="8dp" + android:paddingLeft="16dp" + android:paddingRight="16dp" + android:paddingBottom="8dp" tools:background="@android:color/darker_gray"> <ImageView @@ -11,11 +15,8 @@ android:layout_width="@dimen/thumbnail_length_itemlist" android:layout_height="@dimen/thumbnail_length_itemlist" android:layout_alignParentLeft="true" - android:layout_centerVertical="true" - android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" - android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding" + android:layout_alignParentTop="true" android:layout_marginRight="8dp" - android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" android:adjustViewBounds="true" android:contentDescription="@string/cover_label" android:cropToPadding="true" @@ -29,7 +30,6 @@ android:layout_height="wrap_content" android:layout_alignTop="@id/txtvTitle" android:layout_alignParentRight="true" - android:layout_marginRight="@dimen/listitem_threeline_horizontalpadding" android:orientation="horizontal"> <ImageView @@ -52,15 +52,14 @@ <TextView android:id="@+id/txtvTitle" - style="@style/AntennaPod.TextView.ListItemPrimaryTitle" + style="@style/AntennaPod.TextView.ListItemPrimaryTitle2" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginBottom="@dimen/list_vertical_padding" - android:layout_marginRight="@dimen/listitem_threeline_horizontalpadding" android:layout_toRightOf="@id/imgvCover" android:layout_toLeftOf="@id/subscribers_container" android:layout_alignTop="@id/imgvCover" - android:lines="1" + android:maxLines="2" + android:includeFontPadding="false" tools:text="Title" tools:background="@android:color/holo_green_dark" /> @@ -69,7 +68,6 @@ style="android:style/TextAppearance.Small" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginRight="@dimen/listitem_threeline_horizontalpadding" android:layout_toRightOf="@id/imgvCover" android:layout_below="@id/txtvTitle" android:textSize="14sp" diff --git a/app/src/main/res/layout/itunes_podcast_listitem.xml b/app/src/main/res/layout/itunes_podcast_listitem.xml index 41b1f495f..1e6e5a836 100644 --- a/app/src/main/res/layout/itunes_podcast_listitem.xml +++ b/app/src/main/res/layout/itunes_podcast_listitem.xml @@ -1,38 +1,58 @@ <?xml version="1.0" encoding="utf-8"?> -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" -xmlns:tools="http://schemas.android.com/tools" -android:layout_width="match_parent" -android:layout_height="@dimen/listitem_threeline_height" -tools:background="@android:color/darker_gray"> - -<ImageView - android:id="@+id/imgvCover" - android:layout_width="@dimen/thumbnail_length_itemlist" - android:layout_height="@dimen/thumbnail_length_itemlist" - android:layout_alignParentLeft="true" - android:layout_centerVertical="true" - android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" - android:layout_marginLeft="@dimen/listitem_threeline_horizontalpadding" - android:layout_marginRight="8dp" - android:layout_marginTop="@dimen/listitem_threeline_verticalpadding" - android:adjustViewBounds="true" - android:contentDescription="@string/cover_label" - android:cropToPadding="true" - android:scaleType="fitXY" - tools:src="@drawable/ic_stat_antenna_default" - tools:background="@android:color/holo_green_dark" /> - -<TextView - android:id="@+id/txtvTitle" - style="@style/AntennaPod.TextView.ListItemPrimaryTitle" +<RelativeLayout + 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" - android:layout_centerVertical="true" - android:layout_marginBottom="@dimen/listitem_threeline_verticalpadding" - android:layout_marginRight="@dimen/listitem_threeline_horizontalpadding" - android:layout_toRightOf="@id/imgvCover" - android:maxLines="1" - tools:text="Podcast title" - tools:background="@android:color/holo_green_dark" /> + android:paddingTop="8dp" + android:paddingLeft="16dp" + android:paddingRight="16dp" + android:paddingBottom="8dp" + tools:background="@android:color/darker_gray"> + + <ImageView + android:id="@+id/imgvCover" + android:layout_width="@dimen/thumbnail_length_itemlist" + android:layout_height="@dimen/thumbnail_length_itemlist" + android:layout_alignParentLeft="true" + android:layout_alignParentTop="true" + android:layout_marginRight="8dp" + android:adjustViewBounds="true" + android:contentDescription="@string/cover_label" + android:cropToPadding="true" + android:scaleType="fitXY" + tools:background="@android:color/holo_green_dark" + tools:src="@drawable/ic_stat_antenna_default" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_toRightOf="@id/imgvCover" + android:layout_centerVertical="true" + android:orientation="vertical"> + + <TextView + android:id="@+id/txtvTitle" + style="@style/AntennaPod.TextView.ListItemPrimaryTitle2" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:maxLines="2" + tools:background="@android:color/holo_green_dark" + tools:text="Podcast title" /> + + <TextView + android:id="@+id/txtvUrl" + style="android:style/TextAppearance.Small" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="14sp" + android:textColor="?android:attr/textColorSecondary" + android:ellipsize="middle" + android:maxLines="2" + tools:text="http://www.example.com/feed" + tools:background="@android:color/holo_green_dark"/> + + </LinearLayout> + </RelativeLayout> diff --git a/app/src/main/res/menu/itunes_search.xml b/app/src/main/res/menu/itunes_search.xml new file mode 100644 index 000000000..88fa36a4a --- /dev/null +++ b/app/src/main/res/menu/itunes_search.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> + +<menu xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:custom="http://schemas.android.com/apk/res-auto"> + + <item + android:id="@+id/action_search" + android:icon="?attr/action_search" + custom:showAsAction="collapseActionView|ifRoom" + custom:actionViewClass="android.support.v7.widget.SearchView" + android:title="@string/search_label"/> + +</menu> diff --git a/core/src/main/res/values/styles.xml b/core/src/main/res/values/styles.xml index b0b298906..d3718a460 100644 --- a/core/src/main/res/values/styles.xml +++ b/core/src/main/res/values/styles.xml @@ -249,6 +249,12 @@ <item name="android:ellipsize">end</item> </style> + <style name="AntennaPod.TextView.ListItemPrimaryTitle2" parent="@android:style/TextAppearance.Small"> + <item name="android:textSize">16sp</item> + <item name="android:textColor">?android:attr/textColorPrimary</item> + <item name="android:ellipsize">end</item> + </style> + <style name="AntennaPod.TextView.ListItemSecondaryTitle" parent="@android:style/TextAppearance.Small"> <item name="android:textSize">14sp</item> <item name="android:textColor">?android:attr/textColorSecondary</item> |