1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2024-10-01 08:20:50 +00:00

Merge pull request #588 from coffeemakr/feature-speedup

Speed up detail page loading ⏱
This commit is contained in:
Mauricio Colli 2017-06-27 18:12:30 -03:00 committed by GitHub
commit e8b71e867c
18 changed files with 538 additions and 527 deletions

View File

@ -213,7 +213,7 @@ public class ChannelFragment extends BaseFragment implements ChannelExtractorWor
channelVideosList.setLayoutManager(new LinearLayoutManager(activity)); channelVideosList.setLayoutManager(new LinearLayoutManager(activity));
if (infoListAdapter == null) { if (infoListAdapter == null) {
infoListAdapter = new InfoListAdapter(activity, rootView); infoListAdapter = new InfoListAdapter(activity);
if (savedInstanceState != null) { if (savedInstanceState != null) {
//noinspection unchecked //noinspection unchecked
ArrayList<InfoItem> serializable = (ArrayList<InfoItem>) savedInstanceState.getSerializable(INFO_LIST_KEY); ArrayList<InfoItem> serializable = (ArrayList<InfoItem>) savedInstanceState.getSerializable(INFO_LIST_KEY);

View File

@ -1,12 +1,17 @@
package org.schabi.newpipe.fragments.detail; package org.schabi.newpipe.fragments.detail;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.annotation.FloatRange; import android.support.annotation.FloatRange;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
@ -15,6 +20,7 @@ import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.text.Html; import android.text.Html;
import android.text.Spanned;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.util.Log; import android.util.Log;
@ -26,7 +32,7 @@ import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button; import android.widget.FrameLayout;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
@ -112,9 +118,9 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
private Spinner spinnerToolbar; private Spinner spinnerToolbar;
private ParallaxScrollView parallaxScrollRootView; private ParallaxScrollView parallaxScrollRootView;
private RelativeLayout contentRootLayoutHiding; private LinearLayout contentRootLayoutHiding;
private Button thumbnailBackgroundButton; private View thumbnailBackgroundButton;
private ImageView thumbnailImageView; private ImageView thumbnailImageView;
private ImageView thumbnailPlayButton; private ImageView thumbnailPlayButton;
@ -126,12 +132,11 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
private TextView detailControlsBackground; private TextView detailControlsBackground;
private TextView detailControlsPopup; private TextView detailControlsPopup;
private RelativeLayout videoDescriptionRootLayout; private LinearLayout videoDescriptionRootLayout;
private TextView videoUploadDateView; private TextView videoUploadDateView;
private TextView videoDescriptionView; private TextView videoDescriptionView;
private View uploaderRootLayout; private View uploaderRootLayout;
private Button uploaderButton;
private TextView uploaderTextView; private TextView uploaderTextView;
private ImageView uploaderThumb; private ImageView uploaderThumb;
@ -142,9 +147,12 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
private TextView thumbsDisabledTextView; private TextView thumbsDisabledTextView;
private TextView nextStreamTitle; private TextView nextStreamTitle;
private RelativeLayout relatedStreamRootLayout; private LinearLayout relatedStreamRootLayout;
private LinearLayout relatedStreamsView; private LinearLayout relatedStreamsView;
private ImageButton relatedStreamExpandButton; private ImageButton relatedStreamExpandButton;
private Handler uiHandler;
private Handler backgroundHandler;
private HandlerThread backgroundHandlerThread;
/*////////////////////////////////////////////////////////////////////////*/ /*////////////////////////////////////////////////////////////////////////*/
@ -194,6 +202,16 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
thousand = getString(R.string.short_thousand); thousand = getString(R.string.short_thousand);
million = getString(R.string.short_million); million = getString(R.string.short_million);
billion = getString(R.string.short_billion); billion = getString(R.string.short_billion);
if(uiHandler == null) {
uiHandler = new Handler(Looper.getMainLooper(), new UICallback());
}
if(backgroundHandler == null) {
HandlerThread handlerThread = new HandlerThread("VideoDetailFragment-BG");
handlerThread.start();
backgroundHandlerThread = handlerThread;
backgroundHandler = new Handler(handlerThread.getLooper(), new BackgroundCallback(uiHandler, getContext()));
}
} }
@Override @Override
@ -241,6 +259,11 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
if(backgroundHandlerThread != null) {
backgroundHandlerThread.quit();
}
backgroundHandlerThread = null;
backgroundHandler = null;
PreferenceManager.getDefaultSharedPreferences(activity).unregisterOnSharedPreferenceChangeListener(this); PreferenceManager.getDefaultSharedPreferences(activity).unregisterOnSharedPreferenceChangeListener(this);
} }
@ -272,7 +295,7 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
videoUploadDateView = null; videoUploadDateView = null;
videoDescriptionView = null; videoDescriptionView = null;
uploaderButton = null; uploaderRootLayout = null;
uploaderTextView = null; uploaderTextView = null;
uploaderThumb = null; uploaderThumb = null;
@ -353,10 +376,14 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
case R.id.detail_controls_popup: case R.id.detail_controls_popup:
openInPopup(); openInPopup();
break; break;
case R.id.detail_uploader_button: case R.id.detail_uploader_root_layout:
NavigationHelper.openChannelFragment(getFragmentManager(), currentStreamInfo.service_id, currentStreamInfo.channel_url, currentStreamInfo.uploader); if(currentStreamInfo.channel_url == null || currentStreamInfo.channel_url.isEmpty()) {
Log.w(TAG, "Can't open channel because we got no channel URL");
} else {
NavigationHelper.openChannelFragment(getFragmentManager(), currentStreamInfo.service_id, currentStreamInfo.channel_url, currentStreamInfo.uploader);
}
break; break;
case R.id.detail_thumbnail_background_button: case R.id.detail_thumbnail_root_layout:
playVideo(currentStreamInfo); playVideo(currentStreamInfo);
break; break;
case R.id.detail_title_root_layout: case R.id.detail_title_root_layout:
@ -484,12 +511,11 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
parallaxScrollRootView = (ParallaxScrollView) rootView.findViewById(R.id.detail_main_content); parallaxScrollRootView = (ParallaxScrollView) rootView.findViewById(R.id.detail_main_content);
//thumbnailRootLayout = (RelativeLayout) rootView.findViewById(R.id.detail_thumbnail_root_layout); thumbnailBackgroundButton = rootView.findViewById(R.id.detail_thumbnail_root_layout);
thumbnailBackgroundButton = (Button) rootView.findViewById(R.id.detail_thumbnail_background_button);
thumbnailImageView = (ImageView) rootView.findViewById(R.id.detail_thumbnail_image_view); thumbnailImageView = (ImageView) rootView.findViewById(R.id.detail_thumbnail_image_view);
thumbnailPlayButton = (ImageView) rootView.findViewById(R.id.detail_thumbnail_play_button); thumbnailPlayButton = (ImageView) rootView.findViewById(R.id.detail_thumbnail_play_button);
contentRootLayoutHiding = (RelativeLayout) rootView.findViewById(R.id.detail_content_root_hiding); contentRootLayoutHiding = (LinearLayout) rootView.findViewById(R.id.detail_content_root_hiding);
videoTitleRoot = rootView.findViewById(R.id.detail_title_root_layout); videoTitleRoot = rootView.findViewById(R.id.detail_title_root_layout);
videoTitleTextView = (TextView) rootView.findViewById(R.id.detail_video_title_view); videoTitleTextView = (TextView) rootView.findViewById(R.id.detail_video_title_view);
@ -499,7 +525,7 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
detailControlsBackground = (TextView) rootView.findViewById(R.id.detail_controls_background); detailControlsBackground = (TextView) rootView.findViewById(R.id.detail_controls_background);
detailControlsPopup = (TextView) rootView.findViewById(R.id.detail_controls_popup); detailControlsPopup = (TextView) rootView.findViewById(R.id.detail_controls_popup);
videoDescriptionRootLayout = (RelativeLayout) rootView.findViewById(R.id.detail_description_root_layout); videoDescriptionRootLayout = (LinearLayout) rootView.findViewById(R.id.detail_description_root_layout);
videoUploadDateView = (TextView) rootView.findViewById(R.id.detail_upload_date_view); videoUploadDateView = (TextView) rootView.findViewById(R.id.detail_upload_date_view);
videoDescriptionView = (TextView) rootView.findViewById(R.id.detail_description_view); videoDescriptionView = (TextView) rootView.findViewById(R.id.detail_description_view);
@ -511,19 +537,19 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
thumbsDisabledTextView = (TextView) rootView.findViewById(R.id.detail_thumbs_disabled_view); thumbsDisabledTextView = (TextView) rootView.findViewById(R.id.detail_thumbs_disabled_view);
uploaderRootLayout = rootView.findViewById(R.id.detail_uploader_root_layout); uploaderRootLayout = rootView.findViewById(R.id.detail_uploader_root_layout);
uploaderButton = (Button) rootView.findViewById(R.id.detail_uploader_button);
uploaderTextView = (TextView) rootView.findViewById(R.id.detail_uploader_text_view); uploaderTextView = (TextView) rootView.findViewById(R.id.detail_uploader_text_view);
uploaderThumb = (ImageView) rootView.findViewById(R.id.detail_uploader_thumbnail_view); uploaderThumb = (ImageView) rootView.findViewById(R.id.detail_uploader_thumbnail_view);
relatedStreamRootLayout = (RelativeLayout) rootView.findViewById(R.id.detail_related_streams_root_layout); relatedStreamRootLayout = (LinearLayout) rootView.findViewById(R.id.detail_related_streams_root_layout);
nextStreamTitle = (TextView) rootView.findViewById(R.id.detail_next_stream_title); nextStreamTitle = (TextView) rootView.findViewById(R.id.detail_next_stream_title);
relatedStreamsView = (LinearLayout) rootView.findViewById(R.id.detail_related_streams_view); relatedStreamsView = (LinearLayout) rootView.findViewById(R.id.detail_related_streams_view);
relatedStreamExpandButton = ((ImageButton) rootView.findViewById(R.id.detail_related_streams_expand)); relatedStreamExpandButton = ((ImageButton) rootView.findViewById(R.id.detail_related_streams_expand));
actionBarHandler = new ActionBarHandler(activity); actionBarHandler = new ActionBarHandler(activity);
videoDescriptionView.setMovementMethod(LinkMovementMethod.getInstance()); videoDescriptionView.setMovementMethod(LinkMovementMethod.getInstance());
infoItemBuilder = new InfoItemBuilder(activity, rootView.findViewById(android.R.id.content)); infoItemBuilder = new InfoItemBuilder(activity);
setHeightThumbnail(); setHeightThumbnail();
} }
@ -539,7 +565,7 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
}); });
videoTitleRoot.setOnClickListener(this); videoTitleRoot.setOnClickListener(this);
uploaderButton.setOnClickListener(this); uploaderRootLayout.setOnClickListener(this);
thumbnailBackgroundButton.setOnClickListener(this); thumbnailBackgroundButton.setOnClickListener(this);
detailControlsBackground.setOnClickListener(this); detailControlsBackground.setOnClickListener(this);
detailControlsPopup.setOnClickListener(this); detailControlsPopup.setOnClickListener(this);
@ -593,6 +619,7 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
} }
} }
/*////////////////////////////////////////////////////////////////////////// /*//////////////////////////////////////////////////////////////////////////
// Menu // Menu
//////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////*/
@ -739,8 +766,17 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
// Get url from the new top // Get url from the new top
StackItem peek = stack.peek(); StackItem peek = stack.peek();
if (peek.getInfo() != null) selectAndHandleInfo(peek.getInfo()); if (peek.getInfo() != null) {
else selectAndLoadVideo(0, peek.getUrl(), !TextUtils.isEmpty(peek.getTitle()) ? peek.getTitle() : ""); final StreamInfo streamInfo = peek.getInfo();
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
selectAndHandleInfo(streamInfo);
}
});
} else {
selectAndLoadVideo(0, peek.getUrl(), !TextUtils.isEmpty(peek.getTitle()) ? peek.getTitle() : "");
}
return true; return true;
} }
@ -848,7 +884,7 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
} }
} }
private void handleStreamInfo(@NonNull StreamInfo info, boolean fromNetwork) { private void handleStreamInfo(@NonNull final StreamInfo info, boolean fromNetwork) {
if (DEBUG) Log.d(TAG, "handleStreamInfo() called with: info = [" + info + "]"); if (DEBUG) Log.d(TAG, "handleStreamInfo() called with: info = [" + info + "]");
currentStreamInfo = info; currentStreamInfo = info;
selectVideo(info.service_id, info.webpage_url, info.title); selectVideo(info.service_id, info.webpage_url, info.title);
@ -862,7 +898,6 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
if (!TextUtils.isEmpty(info.uploader)) uploaderTextView.setText(info.uploader); if (!TextUtils.isEmpty(info.uploader)) uploaderTextView.setText(info.uploader);
uploaderTextView.setVisibility(!TextUtils.isEmpty(info.uploader) ? View.VISIBLE : View.GONE); uploaderTextView.setVisibility(!TextUtils.isEmpty(info.uploader) ? View.VISIBLE : View.GONE);
uploaderButton.setVisibility(!TextUtils.isEmpty(info.channel_url) ? View.VISIBLE : View.GONE);
uploaderThumb.setImageDrawable(ContextCompat.getDrawable(activity, R.drawable.buddy)); uploaderThumb.setImageDrawable(ContextCompat.getDrawable(activity, R.drawable.buddy));
if (info.view_count >= 0) videoCountView.setText(Localization.localizeViewCount(info.view_count, activity)); if (info.view_count >= 0) videoCountView.setText(Localization.localizeViewCount(info.view_count, activity));
@ -887,14 +922,8 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
thumbsUpImageView.setVisibility(info.like_count >= 0 ? View.VISIBLE : View.GONE); thumbsUpImageView.setVisibility(info.like_count >= 0 ? View.VISIBLE : View.GONE);
} }
if (!TextUtils.isEmpty(info.upload_date)) videoUploadDateView.setText(Localization.localizeDate(info.upload_date, activity));
videoUploadDateView.setVisibility(!TextUtils.isEmpty(info.upload_date) ? View.VISIBLE : View.GONE);
if (!TextUtils.isEmpty(info.description)) { //noinspection deprecation
videoDescriptionView.setText(Build.VERSION.SDK_INT >= 24 ? Html.fromHtml(info.description, 0) : Html.fromHtml(info.description));
}
videoDescriptionView.setVisibility(!TextUtils.isEmpty(info.description) ? View.VISIBLE : View.GONE);
videoDescriptionView.setVisibility(View.GONE);
videoDescriptionRootLayout.setVisibility(View.GONE); videoDescriptionRootLayout.setVisibility(View.GONE);
videoTitleToggleArrow.setImageResource(R.drawable.arrow_down); videoTitleToggleArrow.setImageResource(R.drawable.arrow_down);
videoTitleToggleArrow.setVisibility(View.VISIBLE); videoTitleToggleArrow.setVisibility(View.VISIBLE);
@ -908,9 +937,26 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
toggleExpandRelatedVideos(currentStreamInfo); toggleExpandRelatedVideos(currentStreamInfo);
wasRelatedStreamsExpanded = false; wasRelatedStreamsExpanded = false;
} }
setTitleToUrl(info.webpage_url, info.title); setTitleToUrl(info.webpage_url, info.title);
setStreamInfoToUrl(info.webpage_url, info); setStreamInfoToUrl(info.webpage_url, info);
prepareDescription(info.description);
prepareUploadDate(info.upload_date);
}
private void prepareUploadDate(final String uploadDate) {
// Hide until date is prepared or forever if no date is supplied
videoUploadDateView.setVisibility(View.GONE);
if (!TextUtils.isEmpty(uploadDate)) {
backgroundHandler.sendMessage(Message.obtain(backgroundHandler, BackgroundCallback.MESSAGE_UPLOADER_DATE, uploadDate));
}
}
private void prepareDescription(final String descriptionHtml) {
// Send the unparsed description to the handler as a message
if (!TextUtils.isEmpty(descriptionHtml)) {
backgroundHandler.sendMessage(Message.obtain(backgroundHandler, BackgroundCallback.MESSAGE_DESCRIPTION, descriptionHtml));
}
} }
public void playVideo(StreamInfo info) { public void playVideo(StreamInfo info) {
@ -987,10 +1033,8 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
int height = isPortrait ? (int) (getResources().getDisplayMetrics().widthPixels / (16.0f / 9.0f)) int height = isPortrait ? (int) (getResources().getDisplayMetrics().widthPixels / (16.0f / 9.0f))
: (int) (getResources().getDisplayMetrics().heightPixels / 2f); : (int) (getResources().getDisplayMetrics().heightPixels / 2f);
thumbnailImageView.setScaleType(isPortrait ? ImageView.ScaleType.CENTER_CROP : ImageView.ScaleType.FIT_CENTER); thumbnailImageView.setScaleType(isPortrait ? ImageView.ScaleType.CENTER_CROP : ImageView.ScaleType.FIT_CENTER);
thumbnailImageView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, height)); thumbnailImageView.setLayoutParams(new FrameLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, height));
thumbnailImageView.setMinimumHeight(height); thumbnailImageView.setMinimumHeight(height);
thumbnailBackgroundButton.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, height));
thumbnailBackgroundButton.setMinimumHeight(height);
} }
public String getShortCount(Long viewCount) { public String getShortCount(Long viewCount) {
@ -1126,4 +1170,65 @@ public class VideoDetailFragment extends BaseFragment implements StreamExtractor
public void onUnrecoverableError(Exception exception) { public void onUnrecoverableError(Exception exception) {
activity.finish(); activity.finish();
} }
private static class BackgroundCallback implements Handler.Callback {
private static final int MESSAGE_DESCRIPTION = 1;
public static final int MESSAGE_UPLOADER_DATE = 2;
private final Handler uiHandler;
private final Context context;
BackgroundCallback(Handler uiHandler, Context context) {
this.uiHandler = uiHandler;
this.context = context;
}
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_DESCRIPTION:
handleDescription((String) msg.obj);
return true;
case MESSAGE_UPLOADER_DATE:
handleUploadDate((String) msg.obj);
return true;
}
return false;
}
private void handleUploadDate(String uploadDate) {
String localizedDate = Localization.localizeDate(uploadDate, context);
uiHandler.sendMessage(Message.obtain(uiHandler, MESSAGE_UPLOADER_DATE, localizedDate));
}
private void handleDescription(String description) {
Spanned parsedDescription;
if (TextUtils.isEmpty(description)) {
return;
}
if (Build.VERSION.SDK_INT >= 24) {
parsedDescription = Html.fromHtml(description, 0);
} else {
//noinspection deprecation
parsedDescription = Html.fromHtml(description);
}
uiHandler.sendMessage(Message.obtain(uiHandler, MESSAGE_DESCRIPTION, parsedDescription));
}
}
private class UICallback implements Handler.Callback {
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case BackgroundCallback.MESSAGE_DESCRIPTION:
videoDescriptionView.setText((Spanned) msg.obj);
videoDescriptionView.setVisibility(View.VISIBLE);
return true;
case BackgroundCallback.MESSAGE_UPLOADER_DATE:
videoUploadDateView.setText((String) msg.obj);
videoUploadDateView.setVisibility(View.VISIBLE);
return true;
}
return false;
}
}
} }

View File

@ -212,7 +212,7 @@ public class SearchFragment extends BaseFragment implements SuggestionWorker.OnS
resultRecyclerView.setLayoutManager(new LinearLayoutManager(activity)); resultRecyclerView.setLayoutManager(new LinearLayoutManager(activity));
if (infoListAdapter == null) { if (infoListAdapter == null) {
infoListAdapter = new InfoListAdapter(getActivity(), getActivity().findViewById(android.R.id.content)); infoListAdapter = new InfoListAdapter(getActivity());
if (savedInstanceState != null) { if (savedInstanceState != null) {
//noinspection unchecked //noinspection unchecked
ArrayList<InfoItem> serializable = (ArrayList<InfoItem>) savedInstanceState.getSerializable(INFO_LIST_KEY); ArrayList<InfoItem> serializable = (ArrayList<InfoItem>) savedInstanceState.getSerializable(INFO_LIST_KEY);

View File

@ -31,8 +31,7 @@ import de.hdodenhof.circleimageview.CircleImageView;
public class ChannelInfoItemHolder extends InfoItemHolder { public class ChannelInfoItemHolder extends InfoItemHolder {
public final CircleImageView itemThumbnailView; public final CircleImageView itemThumbnailView;
public final TextView itemChannelTitleView; public final TextView itemChannelTitleView;
public final TextView itemSubscriberCountView; public final TextView itemAdditionalDetailView;
public final TextView itemVideoCountView;
public final TextView itemChannelDescriptionView; public final TextView itemChannelDescriptionView;
public final View itemRoot; public final View itemRoot;
@ -42,8 +41,7 @@ public class ChannelInfoItemHolder extends InfoItemHolder {
itemRoot = v.findViewById(R.id.itemRoot); itemRoot = v.findViewById(R.id.itemRoot);
itemThumbnailView = (CircleImageView) v.findViewById(R.id.itemThumbnailView); itemThumbnailView = (CircleImageView) v.findViewById(R.id.itemThumbnailView);
itemChannelTitleView = (TextView) v.findViewById(R.id.itemChannelTitleView); itemChannelTitleView = (TextView) v.findViewById(R.id.itemChannelTitleView);
itemSubscriberCountView = (TextView) v.findViewById(R.id.itemSubscriberCountView); itemAdditionalDetailView = (TextView) v.findViewById(R.id.itemAdditionalDetails);
itemVideoCountView = (TextView) v.findViewById(R.id.itemVideoCountView);
itemChannelDescriptionView = (TextView) v.findViewById(R.id.itemChannelDescriptionView); itemChannelDescriptionView = (TextView) v.findViewById(R.id.itemChannelDescriptionView);
} }

View File

@ -17,6 +17,8 @@ import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.channel.ChannelInfoItem; import org.schabi.newpipe.extractor.channel.ChannelInfoItem;
import org.schabi.newpipe.extractor.stream_info.StreamInfoItem; import org.schabi.newpipe.extractor.stream_info.StreamInfoItem;
import java.util.Locale;
/** /**
* Created by Christian Schabesberger on 26.09.16. * Created by Christian Schabesberger on 26.09.16.
* <p> * <p>
@ -54,18 +56,35 @@ public class InfoItemBuilder {
void selected(int serviceId, String url, String title); void selected(int serviceId, String url, String title);
} }
private Context mContext = null;
private LayoutInflater inflater;
private View rootView = null;
private ImageLoader imageLoader = ImageLoader.getInstance(); private ImageLoader imageLoader = ImageLoader.getInstance();
private DisplayImageOptions displayImageOptions =
new DisplayImageOptions.Builder().cacheInMemory(true).build(); /** Base display options */
private static final DisplayImageOptions DISPLAY_IMAGE_OPTIONS =
new DisplayImageOptions.Builder()
.cacheInMemory(true)
.build();
/** Display options for stream thumbnails */
private static final DisplayImageOptions DISPLAY_STREAM_THUMBNAIL_OPTIONS =
new DisplayImageOptions.Builder()
.cloneFrom(DISPLAY_IMAGE_OPTIONS)
.showImageOnFail(R.drawable.dummy_thumbnail)
.showImageForEmptyUri(R.drawable.dummy_thumbnail)
.showImageOnLoading(R.drawable.dummy_thumbnail)
.build();
/** Display options for channel thumbnails */
private static final DisplayImageOptions DISPLAY_CHANNEL_THUMBNAIL_OPTIONS =
new DisplayImageOptions.Builder()
.cloneFrom(DISPLAY_IMAGE_OPTIONS)
.showImageOnLoading(R.drawable.buddy_channel_item)
.showImageForEmptyUri(R.drawable.buddy_channel_item)
.showImageOnFail(R.drawable.buddy_channel_item)
.build();
private OnInfoItemSelectedListener onStreamInfoItemSelectedListener; private OnInfoItemSelectedListener onStreamInfoItemSelectedListener;
private OnInfoItemSelectedListener onChannelInfoItemSelectedListener; private OnInfoItemSelectedListener onChannelInfoItemSelectedListener;
public InfoItemBuilder(Context context, View rootView) { public InfoItemBuilder(Context context) {
mContext = context;
this.rootView = rootView;
viewsS = context.getString(R.string.views); viewsS = context.getString(R.string.views);
videosS = context.getString(R.string.videos); videosS = context.getString(R.string.videos);
subsS = context.getString(R.string.subscriber); subsS = context.getString(R.string.subscriber);
@ -73,7 +92,6 @@ public class InfoItemBuilder {
thousand = context.getString(R.string.short_thousand); thousand = context.getString(R.string.short_thousand);
million = context.getString(R.string.short_million); million = context.getString(R.string.short_million);
billion = context.getString(R.string.short_billion); billion = context.getString(R.string.short_billion);
inflater = LayoutInflater.from(context);
} }
public void setOnStreamInfoItemSelectedListener( public void setOnStreamInfoItemSelectedListener(
@ -107,6 +125,7 @@ public class InfoItemBuilder {
public View buildView(ViewGroup parent, final InfoItem info) { public View buildView(ViewGroup parent, final InfoItem info) {
View itemView = null; View itemView = null;
InfoItemHolder holder = null; InfoItemHolder holder = null;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (info.infoType()) { switch (info.infoType()) {
case STREAM: case STREAM:
//long start = System.nanoTime(); //long start = System.nanoTime();
@ -127,6 +146,22 @@ public class InfoItemBuilder {
return itemView; return itemView;
} }
private String getStreamInfoDetailLine(final StreamInfoItem info) {
String viewsAndDate = "";
if(info.view_count >= 0) {
viewsAndDate = shortViewCount(info.view_count);
}
if(!TextUtils.isEmpty(info.upload_date)) {
if(viewsAndDate.isEmpty()) {
viewsAndDate = info.upload_date;
} else {
viewsAndDate += "" + info.upload_date;
}
}
return viewsAndDate;
}
private void buildStreamInfoItem(StreamInfoItemHolder holder, final StreamInfoItem info) { private void buildStreamInfoItem(StreamInfoItemHolder holder, final StreamInfoItem info) {
if (info.infoType() != InfoItem.InfoType.STREAM) { if (info.infoType() != InfoItem.InfoType.STREAM) {
Log.e("InfoItemBuilder", "Info type not yet supported"); Log.e("InfoItemBuilder", "Info type not yet supported");
@ -146,46 +181,59 @@ public class InfoItemBuilder {
holder.itemDurationView.setVisibility(View.GONE); holder.itemDurationView.setVisibility(View.GONE);
} }
} }
if (info.view_count >= 0) {
holder.itemViewCountView.setText(shortViewCount(info.view_count));
} else {
holder.itemViewCountView.setVisibility(View.GONE);
}
if (!TextUtils.isEmpty(info.upload_date)) holder.itemUploadDateView.setText(info.upload_date + "");
holder.itemThumbnailView.setImageResource(R.drawable.dummy_thumbnail); holder.itemAdditionalDetails.setText(getStreamInfoDetailLine(info));
if (!TextUtils.isEmpty(info.thumbnail_url)) {
imageLoader.displayImage(info.thumbnail_url, // Default thumbnail is shown on error, while loading and if the url is empty
holder.itemThumbnailView, displayImageOptions, imageLoader.displayImage(info.thumbnail_url,
new ImageErrorLoadingListener(mContext, rootView, info.service_id)); holder.itemThumbnailView,
} DISPLAY_STREAM_THUMBNAIL_OPTIONS,
new ImageErrorLoadingListener(holder.itemRoot.getContext(), holder.itemRoot.getRootView(), info.service_id));
holder.itemRoot.setOnClickListener(new View.OnClickListener() { holder.itemRoot.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
onStreamInfoItemSelectedListener.selected(info.service_id, info.webpage_url, info.getTitle()); if(onStreamInfoItemSelectedListener != null) {
onStreamInfoItemSelectedListener.selected(info.service_id, info.webpage_url, info.getTitle());
}
} }
}); });
} }
private String getChannelInfoDetailLine(final ChannelInfoItem info) {
String details = "";
if(info.subscriberCount >= 0) {
details = shortSubscriber(info.subscriberCount);
}
if(info.videoAmount >= 0) {
String formattedVideoAmount = info.videoAmount + " " + videosS;
if(!details.isEmpty()) {
details += "" + formattedVideoAmount;
} else {
details = formattedVideoAmount;
}
}
return details;
}
private void buildChannelInfoItem(ChannelInfoItemHolder holder, final ChannelInfoItem info) { private void buildChannelInfoItem(ChannelInfoItemHolder holder, final ChannelInfoItem info) {
if (!TextUtils.isEmpty(info.getTitle())) holder.itemChannelTitleView.setText(info.getTitle()); if (!TextUtils.isEmpty(info.getTitle())) holder.itemChannelTitleView.setText(info.getTitle());
holder.itemSubscriberCountView.setText(shortSubscriber(info.subscriberCount) + ""); holder.itemAdditionalDetailView.setText(getChannelInfoDetailLine(info));
holder.itemVideoCountView.setText(info.videoAmount + " " + videosS);
if (!TextUtils.isEmpty(info.description)) holder.itemChannelDescriptionView.setText(info.description); if (!TextUtils.isEmpty(info.description)) holder.itemChannelDescriptionView.setText(info.description);
holder.itemThumbnailView.setImageResource(R.drawable.buddy_channel_item); imageLoader.displayImage(info.thumbnailUrl,
if (!TextUtils.isEmpty(info.thumbnailUrl)) { holder.itemThumbnailView,
imageLoader.displayImage(info.thumbnailUrl, DISPLAY_CHANNEL_THUMBNAIL_OPTIONS,
holder.itemThumbnailView, new ImageErrorLoadingListener(holder.itemRoot.getContext(), holder.itemRoot.getRootView(), info.serviceId));
displayImageOptions,
new ImageErrorLoadingListener(mContext, rootView, info.serviceId));
}
holder.itemRoot.setOnClickListener(new View.OnClickListener() { holder.itemRoot.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
onChannelInfoItemSelectedListener.selected(info.serviceId, info.getLink(), info.channelName); if(onStreamInfoItemSelectedListener != null) {
onChannelInfoItemSelectedListener.selected(info.serviceId, info.getLink(), info.channelName);
}
} }
}); });
} }
@ -218,7 +266,10 @@ public class InfoItemBuilder {
} }
public static String getDurationString(int duration) { public static String getDurationString(int duration) {
String output = ""; if(duration < 0) {
duration = 0;
}
String output;
int days = duration / (24 * 60 * 60); /* greater than a day */ int days = duration / (24 * 60 * 60); /* greater than a day */
duration %= (24 * 60 * 60); duration %= (24 * 60 * 60);
int hours = duration / (60 * 60); /* greater than an hour */ int hours = duration / (60 * 60); /* greater than an hour */
@ -228,46 +279,12 @@ public class InfoItemBuilder {
//handle days //handle days
if (days > 0) { if (days > 0) {
output = Integer.toString(days) + ":"; output = String.format(Locale.US, "%d:%02d:%02d:%02d", days, hours, minutes, seconds);
} } else if(hours > 0) {
// handle hours output = String.format(Locale.US, "%d:%02d:%02d", hours, minutes, seconds);
if (hours > 0 || !output.isEmpty()) {
if (hours > 0) {
if (hours >= 10 || output.isEmpty()) {
output += Integer.toString(hours);
} else {
output += "0" + Integer.toString(hours);
}
} else {
output += "00";
}
output += ":";
}
//handle minutes
if (minutes > 0 || !output.isEmpty()) {
if (minutes > 0) {
if (minutes >= 10 || output.isEmpty()) {
output += Integer.toString(minutes);
} else {
output += "0" + Integer.toString(minutes);
}
} else {
output += "00";
}
output += ":";
}
//handle seconds
if (output.isEmpty()) {
output += "0:";
}
if (seconds >= 10) {
output += Integer.toString(seconds);
} else { } else {
output += "0" + Integer.toString(seconds); output = String.format(Locale.US, "%d:%02d", minutes, seconds);
} }
return output; return output;
} }
} }

View File

@ -55,8 +55,8 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
notifyDataSetChanged(); notifyDataSetChanged();
} }
public InfoListAdapter(Activity a, View rootView) { public InfoListAdapter(Activity a) {
infoItemBuilder = new InfoItemBuilder(a, rootView); infoItemBuilder = new InfoItemBuilder(a);
infoItemList = new ArrayList<>(); infoItemList = new ArrayList<>();
} }
@ -78,6 +78,9 @@ public class InfoListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
} }
public void clearStreamItemList() { public void clearStreamItemList() {
if(infoItemList.isEmpty()) {
return;
}
infoItemList.clear(); infoItemList.clear();
notifyDataSetChanged(); notifyDataSetChanged();
} }

View File

@ -33,8 +33,7 @@ public class StreamInfoItemHolder extends InfoItemHolder {
public final TextView itemVideoTitleView, public final TextView itemVideoTitleView,
itemUploaderView, itemUploaderView,
itemDurationView, itemDurationView,
itemUploadDateView, itemAdditionalDetails;
itemViewCountView;
public final View itemRoot; public final View itemRoot;
public StreamInfoItemHolder(View v) { public StreamInfoItemHolder(View v) {
@ -44,8 +43,7 @@ public class StreamInfoItemHolder extends InfoItemHolder {
itemVideoTitleView = (TextView) v.findViewById(R.id.itemVideoTitleView); itemVideoTitleView = (TextView) v.findViewById(R.id.itemVideoTitleView);
itemUploaderView = (TextView) v.findViewById(R.id.itemUploaderView); itemUploaderView = (TextView) v.findViewById(R.id.itemUploaderView);
itemDurationView = (TextView) v.findViewById(R.id.itemDurationView); itemDurationView = (TextView) v.findViewById(R.id.itemDurationView);
itemUploadDateView = (TextView) v.findViewById(R.id.itemUploadDateView); itemAdditionalDetails = (TextView) v.findViewById(R.id.itemAdditionalDetails);
itemViewCountView = (TextView) v.findViewById(R.id.itemViewCountView);
} }
@Override @Override

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout <FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -15,4 +15,4 @@
<include layout="@layout/toolbar_layout"/> <include layout="@layout/toolbar_layout"/>
</RelativeLayout> </FrameLayout>

View File

@ -4,11 +4,10 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/itemRoot" android:id="@+id/itemRoot"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="@dimen/video_item_search_height"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:clickable="true" android:clickable="true"
android:orientation="vertical" android:padding="@dimen/video_item_search_padding">
android:padding="12dp">
<de.hdodenhof.circleimageview.CircleImageView <de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/itemThumbnailView" android:id="@+id/itemThumbnailView"
@ -22,55 +21,43 @@
android:src="@drawable/buddy_channel_item" android:src="@drawable/buddy_channel_item"
tools:ignore="RtlHardcoded"/> tools:ignore="RtlHardcoded"/>
<RelativeLayout <TextView
android:id="@+id/itemChannelTitleView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/video_item_search_thumbnail_image_height" android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="@id/itemThumbnailView" android:layout_toRightOf="@id/itemThumbnailView"
android:orientation="vertical" android:layout_marginBottom="@dimen/video_item_search_image_right_margin"
tools:ignore="RtlHardcoded"> android:ellipsize="end"
android:lines="1"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="@dimen/video_item_search_title_text_size"
tools:text="Channel Title, Lorem ipsum"/>
<TextView <TextView
android:id="@+id/itemChannelTitleView" android:id="@+id/itemAdditionalDetails"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:layout_alignParentBottom="true"
android:ellipsize="end" android:layout_toRightOf="@id/itemThumbnailView"
android:maxLines="1" android:lines="1"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/channel_item_detail_title_text_size" android:textSize="@dimen/video_item_search_upload_date_text_size"
tools:text="Channel Title, Lorem ipsum"/> tools:text="10M subscribers • 1000 videos"/>
<TextView
android:id="@+id/itemChannelDescriptionView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/itemSubscriberCountView"
android:layout_below="@+id/itemChannelTitleView"
android:ellipsize="end"
android:maxLines="2"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/video_item_search_uploader_text_size"
tools:text="Channel description, Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blanditLorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blanditLorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blandit"/>
<TextView <TextView
android:id="@+id/itemSubscriberCountView" android:id="@+id/itemChannelDescriptionView"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true" android:layout_above="@id/itemAdditionalDetails"
android:maxLines="1" android:layout_marginBottom="@dimen/video_item_detail_description_to_details_margin"
android:textAppearance="?android:attr/textAppearanceSmall" android:layout_toRightOf="@id/itemThumbnailView"
android:textSize="@dimen/video_item_search_upload_date_text_size" android:ellipsize="end"
tools:text="10M subscribers • "/> android:lines="2"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/video_item_search_uploader_text_size"
tools:text="Channel description, Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blanditLorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blanditLorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blandit"/>
<TextView
android:id="@+id/itemVideoCountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toRightOf="@+id/itemSubscriberCountView"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/video_item_search_upload_date_text_size"
tools:text="1000 videos"/>
</RelativeLayout>
</RelativeLayout> </RelativeLayout>

View File

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="16dp" android:padding="16dp"
android:gravity="center_horizontal"
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
android:id="@+id/error_message_view" android:id="@+id/error_message_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="@string/general_error" android:text="@string/general_error"
android:gravity="center" android:gravity="center"
android:textSize="16sp" android:textSize="16sp"
@ -22,8 +22,6 @@
android:id="@+id/error_button_retry" android:id="@+id/error_button_retry"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/error_message_view"
android:layout_centerHorizontal="true"
android:layout_margin="8dp" android:layout_margin="8dp"
android:text="@string/retry" android:text="@string/retry"
android:textAlignment="center" android:textAlignment="center"
@ -32,4 +30,4 @@
android:textSize="16sp" android:textSize="16sp"
android:theme="@style/RedButton"/> android:theme="@style/RedButton"/>
</RelativeLayout> </LinearLayout>

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
tools:context=".fragments.channel.ChannelFragment">
<android.support.v7.widget.RecyclerView <android.support.v7.widget.RecyclerView
android:id="@+id/channel_streams_view" android:id="@+id/channel_streams_view"
@ -11,26 +11,11 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?android:windowBackground" android:background="?android:windowBackground"
android:scrollbars="vertical" android:scrollbars="vertical"
tools:listitem="@layout/stream_item"/> tools:listitem="@layout/stream_item" />
<ProgressBar
android:id="@+id/loading_progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminate="true"
android:visibility="gone"
tools:visibility="visible"/>
<!--ERROR PANEL-->
<include <include
android:id="@+id/error_panel" layout="@layout/loading_error_retry"
layout="@layout/error_retry" android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true" android:layout_gravity="center" />
android:layout_marginTop="50dp" </FrameLayout>
android:visibility="gone"
tools:visibility="visible"/>
</RelativeLayout>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout <FrameLayout 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"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -14,26 +13,11 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:scrollbars="vertical" android:scrollbars="vertical"
app:layoutManager="LinearLayoutManager" app:layoutManager="LinearLayoutManager"
tools:listitem="@layout/stream_item"/> tools:listitem="@layout/stream_item" />
<ProgressBar
android:id="@+id/loading_progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminate="true"
android:visibility="gone"
tools:visibility="visible"/>
<!--ERROR PANEL-->
<include <include
android:id="@+id/error_panel" layout="@layout/loading_error_retry"
layout="@layout/error_retry" android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerHorizontal="true" android:layout_gravity="center_vertical" />
android:layout_marginTop="50dp" </FrameLayout>
android:visibility="gone"
tools:visibility="visible"/>
</RelativeLayout>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout <FrameLayout 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"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/video_item_detail" android:id="@+id/video_item_detail"
@ -16,105 +15,92 @@
app:parallax_factor="1.9"> app:parallax_factor="1.9">
<!--WRAPPER--> <!--WRAPPER-->
<RelativeLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:orientation="vertical">
<!-- THUMBNAIL --> <!-- THUMBNAIL -->
<RelativeLayout <FrameLayout
android:id="@+id/detail_thumbnail_root_layout" android:id="@+id/detail_thumbnail_root_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@android:color/black"> android:background="@android:color/black"
android:clickable="true"
android:foreground="?attr/selectableItemBackground">
<ImageView <ImageView
android:id="@+id/detail_thumbnail_image_view" android:id="@+id/detail_thumbnail_image_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:contentDescription="@string/detail_thumbnail_view_description" android:contentDescription="@string/detail_thumbnail_view_description"
android:scaleType="centerCrop" android:scaleType="centerCrop"
tools:ignore="RtlHardcoded" tools:ignore="RtlHardcoded"
tools:layout_height="200dp" tools:layout_height="200dp"
tools:src="@drawable/dummy_thumbnail"/> tools:src="@drawable/dummy_thumbnail" />
<ImageView <ImageView
android:id="@+id/detail_thumbnail_play_button" android:id="@+id/detail_thumbnail_play_button"
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:background="@android:color/transparent" android:background="@android:color/transparent"
android:src="@drawable/new_play_arrow" android:src="@drawable/new_play_arrow"
android:visibility="invisible" android:visibility="invisible"
tools:ignore="ContentDescription" tools:ignore="ContentDescription"
tools:visibility="visible"/> tools:visibility="visible" />
<Button </FrameLayout>
android:id="@+id/detail_thumbnail_background_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"/>
</RelativeLayout>
<!-- CONTENT --> <!-- CONTENT -->
<RelativeLayout <LinearLayout
android:id="@+id/detail_content_root_layout" android:id="@+id/detail_content_root_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_below="@+id/detail_thumbnail_root_layout" android:background="?android:windowBackground"
android:background="?android:windowBackground"> android:orientation="vertical">
<!-- TITLE --> <!-- TITLE -->
<RelativeLayout <FrameLayout
android:id="@+id/detail_title_root_layout" android:id="@+id/detail_title_root_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:clickable="true" android:clickable="true"
android:paddingLeft="12dp" android:paddingLeft="12dp"
android:paddingRight="12dp" android:paddingRight="12dp">
android:paddingTop="12dp">
<TextView <TextView
android:id="@+id/detail_video_title_view" android:id="@+id/detail_video_title_view"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_alignParentLeft="true" android:layout_marginRight="20dp"
android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/detail_toggle_description_view"
android:ellipsize="end" android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1" android:maxLines="1"
android:paddingBottom="2dp" android:paddingBottom="8dp"
android:paddingTop="6dp" android:paddingTop="12dp"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="@dimen/video_item_detail_title_text_size" android:textSize="@dimen/video_item_detail_title_text_size"
tools:ignore="RtlHardcoded" tools:ignore="RtlHardcoded"
tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed a ultricies ex. Integer sit amet sodales risus. Duis non mi et urna pretium bibendum. Nunc eleifend est quis ipsum porttitor egestas. Sed facilisis, nisl quis eleifend pellentesque, orci metus egestas dolor, at accumsan eros metus quis libero."/> tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed a ultricies ex. Integer sit amet sodales risus. Duis non mi et urna pretium bibendum. Nunc eleifend est quis ipsum porttitor egestas. Sed facilisis, nisl quis eleifend pellentesque, orci metus egestas dolor, at accumsan eros metus quis libero." />
<ImageView <ImageView
android:id="@+id/detail_toggle_description_view" android:id="@+id/detail_toggle_description_view"
android:layout_width="15dp" android:layout_width="15dp"
android:layout_height="15dp" android:layout_height="15dp"
android:layout_alignParentRight="true" android:layout_gravity="center_vertical|right"
android:layout_alignParentTop="true"
android:layout_marginLeft="5dp" android:layout_marginLeft="5dp"
android:layout_marginTop="6dp"
android:src="@drawable/arrow_down" android:src="@drawable/arrow_down"
tools:ignore="ContentDescription,RtlHardcoded"/> tools:ignore="ContentDescription,RtlHardcoded" />
</RelativeLayout>
</FrameLayout>
<!--HIDING ROOT--> <!--HIDING ROOT-->
<RelativeLayout <LinearLayout
android:id="@+id/detail_content_root_hiding" android:id="@+id/detail_content_root_hiding"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_below="@+id/detail_title_root_layout" android:orientation="vertical"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible"> tools:visibility="visible">
@ -122,197 +108,156 @@
<RelativeLayout <RelativeLayout
android:id="@+id/detail_root" android:id="@+id/detail_root"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="55dp"
android:layout_marginLeft="12dp" android:layout_marginLeft="12dp"
android:layout_marginRight="12dp" android:layout_marginRight="12dp"
android:layout_marginTop="6dp"
android:baselineAligned="false" android:baselineAligned="false"
android:orientation="horizontal" android:orientation="horizontal">
android:paddingTop="6dp">
<!-- VIEW & THUMBS --> <!-- VIEW & THUMBS -->
<LinearLayout <TextView
android:id="@+id/detail_views_thumbs_root" android:id="@+id/detail_view_count_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_centerHorizontal="true" android:layout_marginBottom="6dp"
android:orientation="vertical" android:layout_marginTop="6dp"
android:paddingTop="6dp" android:lines="1"
tools:ignore="RtlHardcoded"> android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="@dimen/video_item_detail_views_text_size"
tools:ignore="RtlHardcoded"
tools:text="2,816,821,505 views" />
<TextView <ImageView
android:id="@+id/detail_view_count_view" android:id="@+id/detail_thumbs_up_img_view"
android:layout_width="match_parent" android:layout_width="@dimen/video_item_detail_like_image_width"
android:layout_height="wrap_content" android:layout_height="@dimen/video_item_detail_like_image_height"
android:layout_gravity="left" android:layout_below="@id/detail_view_count_view"
android:textAppearance="?android:attr/textAppearanceLarge" android:contentDescription="@string/detail_likes_img_view_description"
android:textSize="@dimen/video_item_detail_views_text_size" android:src="?attr/thumbs_up" />
tools:ignore="RtlHardcoded"
tools:text="2,816,821,505 views"/>
<LinearLayout <TextView
android:id="@+id/detail_thumbs_root_layout" android:id="@+id/detail_thumbs_up_count_view"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="@dimen/video_item_detail_like_image_height"
android:layout_gravity="left" android:layout_below="@id/detail_view_count_view"
android:gravity="center_vertical" android:layout_marginLeft="@dimen/video_item_detail_like_margin"
android:minHeight="30dp" android:layout_toRightOf="@id/detail_thumbs_up_img_view"
android:orientation="horizontal"> android:gravity="left|center_vertical"
android:lines="1"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/video_item_detail_likes_text_size"
tools:ignore="RtlHardcoded"
tools:text="12M" />
<ImageView <ImageView
android:id="@+id/detail_thumbs_up_img_view" android:id="@+id/detail_thumbs_down_img_view"
android:layout_width="@dimen/video_item_detail_like_image_width" android:layout_width="@dimen/video_item_detail_like_image_width"
android:layout_height="@dimen/video_item_detail_like_image_height" android:layout_height="@dimen/video_item_detail_like_image_height"
android:contentDescription="@string/detail_likes_img_view_description" android:layout_below="@id/detail_view_count_view"
android:src="?attr/thumbs_up"/> android:layout_marginLeft="15dp"
android:layout_toRightOf="@id/detail_thumbs_up_count_view"
android:contentDescription="@string/detail_dislikes_img_view_description"
android:src="?attr/thumbs_down"
tools:ignore="RtlHardcoded" />
<TextView <TextView
android:id="@+id/detail_thumbs_up_count_view" android:id="@+id/detail_thumbs_down_count_view"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="@dimen/video_item_detail_like_image_height"
android:layout_marginLeft="@dimen/video_item_detail_like_margin" android:layout_below="@id/detail_view_count_view"
android:gravity="left|center_vertical" android:layout_marginLeft="@dimen/video_item_detail_like_margin"
android:textAppearance="?android:attr/textAppearanceMedium" android:layout_toRightOf="@id/detail_thumbs_down_img_view"
android:textSize="@dimen/video_item_detail_likes_text_size" android:gravity="left|center_vertical"
tools:ignore="RtlHardcoded" android:lines="1"
tools:text="12M"/> android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/video_item_detail_likes_text_size"
tools:ignore="RtlHardcoded"
tools:text="10K" />
<ImageView <TextView
android:id="@+id/detail_thumbs_down_img_view" android:id="@+id/detail_thumbs_disabled_view"
android:layout_width="@dimen/video_item_detail_like_image_width" android:layout_width="wrap_content"
android:layout_height="@dimen/video_item_detail_like_image_height" android:layout_height="match_parent"
android:layout_marginLeft="15dp" android:layout_below="@id/detail_view_count_view"
android:contentDescription="@string/detail_dislikes_img_view_description" android:layout_marginLeft="15dp"
android:src="?attr/thumbs_down" android:gravity="left|center_vertical"
tools:ignore="RtlHardcoded"/> android:text="@string/disabled"
android:textAppearance="?android:attr/textAppearanceLarge"
<TextView android:textSize="@dimen/video_item_detail_likes_text_size"
android:id="@+id/detail_thumbs_down_count_view" android:textStyle="bold"
android:layout_width="wrap_content" android:visibility="gone"
android:layout_height="match_parent" tools:ignore="RtlHardcoded" />
android:layout_marginLeft="@dimen/video_item_detail_like_margin"
android:gravity="left|center_vertical"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/video_item_detail_likes_text_size"
tools:ignore="RtlHardcoded"
tools:text="10K"/>
<TextView
android:id="@+id/detail_thumbs_disabled_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:gravity="left|center_vertical"
android:text="@string/disabled"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="@dimen/video_item_detail_likes_text_size"
android:textStyle="bold"
android:visibility="gone"
tools:ignore="RtlHardcoded"/>
</LinearLayout>
</LinearLayout>
<!-- CONTROLS --> <!-- CONTROLS -->
<LinearLayout <TextView
android:id="@+id/detail_controls_root" android:id="@+id/detail_controls_popup"
android:layout_width="wrap_content" android:layout_width="80dp"
android:layout_height="wrap_content" android:layout_height="55dp"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_centerHorizontal="true" android:layout_alignParentTop="true"
android:orientation="horizontal" android:layout_gravity="center_vertical"
tools:ignore="RtlHardcoded"> android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
<TextView android:contentDescription="@string/open_in_popup_mode"
android:id="@+id/detail_controls_background" android:drawableTop="?attr/popup"
android:layout_width="80dp" android:gravity="center"
android:layout_height="55dp" android:paddingBottom="6dp"
android:layout_gravity="center_vertical" android:paddingTop="6dp"
android:background="?attr/selectableItemBackgroundBorderless" android:text="@string/controls_popup_title"
android:clickable="true" android:textSize="12sp" />
android:contentDescription="@string/play_audio"
android:drawableTop="?attr/audio"
android:gravity="center"
android:paddingBottom="6dp"
android:paddingTop="6dp"
android:text="@string/controls_background_title"
android:textSize="12sp"/>
<TextView
android:id="@+id/detail_controls_popup"
android:layout_width="80dp"
android:layout_height="55dp"
android:layout_gravity="center_vertical"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:contentDescription="@string/open_in_popup_mode"
android:drawableTop="?attr/popup"
android:gravity="center"
android:paddingBottom="6dp"
android:paddingTop="6dp"
android:text="@string/controls_popup_title"
android:textSize="12sp"/>
</LinearLayout>
<TextView
android:id="@+id/detail_controls_background"
android:layout_width="80dp"
android:layout_height="55dp"
android:layout_alignParentTop="true"
android:layout_gravity="center_vertical"
android:layout_toLeftOf="@id/detail_controls_popup"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:contentDescription="@string/play_audio"
android:drawableTop="?attr/audio"
android:gravity="center"
android:paddingBottom="6dp"
android:paddingTop="6dp"
android:text="@string/controls_background_title"
android:textSize="12sp" />
</RelativeLayout> </RelativeLayout>
<!--UPLOADER--> <!--UPLOADER-->
<FrameLayout <LinearLayout
android:id="@+id/detail_uploader_root_layout" android:id="@+id/detail_uploader_root_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/detail_root"> android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingBottom="8dp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:paddingTop="8dp">
<RelativeLayout
android:id="@+id/detail_uploader_layout" <de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/detail_uploader_thumbnail_view"
android:layout_width="@dimen/video_item_detail_uploader_image_size"
android:layout_height="@dimen/video_item_detail_uploader_image_size"
android:contentDescription="@string/detail_uploader_thumbnail_view_description"
android:src="@drawable/buddy"
tools:ignore="RtlHardcoded" />
<TextView
android:id="@+id/detail_uploader_text_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginLeft="15dp"
android:layout_marginLeft="12dp" android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_marginRight="12dp" android:textSize="@dimen/video_item_detail_uploader_text_size"
android:layout_marginTop="8dp"> android:textStyle="bold"
tools:ignore="RtlHardcoded"
tools:text="Uploader" />
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/detail_uploader_thumbnail_view"
android:layout_width="@dimen/video_item_detail_uploader_image_size"
android:layout_height="@dimen/video_item_detail_uploader_image_size"
android:layout_alignParentLeft="true"
android:contentDescription="@string/detail_uploader_thumbnail_view_description"
android:src="@drawable/buddy"
tools:ignore="RtlHardcoded"/>
<TextView
android:id="@+id/detail_uploader_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="15dp"
android:layout_toEndOf="@+id/detail_uploader_thumbnail_view"
android:layout_toRightOf="@+id/detail_uploader_thumbnail_view"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="@dimen/video_item_detail_uploader_text_size"
android:textStyle="bold"
tools:ignore="RtlHardcoded"
tools:text="Uploader"/>
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_gravity="bottom"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:background="?attr/separatorColor"/>
<Button
android:id="@+id/detail_uploader_button"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
tools:visibility="gone"/>
<!--<Button <!--<Button
android:id="@+id/detail_uploader_subscribe" android:id="@+id/detail_uploader_subscribe"
@ -326,15 +271,22 @@
android:drawableLeft="@drawable/ic_rss_feed_white_24dp" android:drawableLeft="@drawable/ic_rss_feed_white_24dp"
tools:ignore="RtlHardcoded" tools:ignore="RtlHardcoded"
android:visibility="gone"/>--> android:visibility="gone"/>-->
</FrameLayout> </LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:background="?attr/separatorColor" />
<!--DESCRIPTIONS--> <!--DESCRIPTIONS-->
<RelativeLayout <LinearLayout
android:id="@+id/detail_description_root_layout" android:id="@+id/detail_description_root_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/detail_uploader_root_layout"
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:orientation="vertical"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible"> tools:visibility="visible">
@ -347,106 +299,74 @@
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/video_item_detail_upload_date_text_size" android:textSize="@dimen/video_item_detail_upload_date_text_size"
android:textStyle="bold" android:textStyle="bold"
tools:text="Upload date"/> tools:text="Published on Oct 2, 2009" />
<TextView <TextView
android:id="@+id/detail_description_view" android:id="@+id/detail_description_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/detail_upload_date_view"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginLeft="12dp" android:layout_marginLeft="12dp"
android:layout_marginRight="12dp" android:layout_marginRight="12dp"
android:layout_marginTop="3dp" android:layout_marginTop="3dp"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/video_item_detail_description_text_size" android:textSize="@dimen/video_item_detail_description_text_size"
tools:text="Description Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed a ultricies ex. Integer sit amet sodales risus. Duis non mi et urna pretium bibendum."/> tools:text="Description Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed a ultricies ex. Integer sit amet sodales risus. Duis non mi et urna pretium bibendum." />
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1px" android:layout_height="1px"
android:layout_alignParentBottom="true"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginRight="8dp" android:layout_marginRight="8dp"
android:background="?attr/separatorColor"/> android:background="?attr/separatorColor" />
</RelativeLayout> </LinearLayout>
<!--NEXT AND RELATED VIDEOS--> <!--NEXT AND RELATED VIDEOS-->
<RelativeLayout <LinearLayout
android:id="@+id/detail_related_streams_root_layout" android:id="@+id/detail_related_streams_root_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:layout_below="@+id/detail_description_root_layout"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal|bottom" android:layout_gravity="center_horizontal|bottom"
android:layout_marginTop="14dp"> android:layout_marginTop="14dp"
android:orientation="vertical">
<TextView <TextView
android:id="@+id/detail_next_stream_title" android:id="@+id/detail_next_stream_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="12dp" android:layout_marginLeft="12dp"
android:text="@string/next_video_title" android:text="@string/next_video_title"
android:textAllCaps="true" android:textAllCaps="true"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/video_item_detail_next_text_size" android:textSize="@dimen/video_item_detail_next_text_size"
tools:ignore="RtlHardcoded"/> tools:ignore="RtlHardcoded" />
<LinearLayout <LinearLayout
android:id="@+id/detail_related_streams_view" android:id="@+id/detail_related_streams_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_below="@id/detail_next_stream_title"
android:layout_marginTop="2dp" android:layout_marginTop="2dp"
android:orientation="vertical" android:orientation="vertical"
tools:minHeight="50dp"/> tools:minHeight="50dp" />
<ImageButton <ImageButton
android:id="@+id/detail_related_streams_expand" android:id="@+id/detail_related_streams_expand"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/detail_related_streams_view"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:paddingBottom="10dp" android:paddingBottom="10dp"
android:paddingTop="4dp" android:paddingTop="4dp"
android:src="?attr/expand" android:src="?attr/expand"
android:textAlignment="center" android:textAlignment="center"
android:textAllCaps="true" android:textAllCaps="true"
tools:ignore="ContentDescription"/> tools:ignore="ContentDescription" />
</LinearLayout>
</LinearLayout>
<!-- LOADING BAR, ERROR & RETRY -->
</RelativeLayout> <include layout="@layout/loading_error_retry" />
</LinearLayout>
</RelativeLayout> </LinearLayout>
<!-- LOADING BAR -->
<ProgressBar
android:id="@+id/loading_progress_bar"
style="@style/Widget.AppCompat.ProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/detail_title_root_layout"
android:layout_centerHorizontal="true"
android:layout_marginTop="15dp"
android:indeterminate="true"
android:visibility="gone"
tools:visibility="visible"/>
<!--ERROR PANEL-->
<include
android:id="@+id/error_panel"
layout="@layout/error_retry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/detail_title_root_layout"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/video_item_detail_error_panel_margin"
android:visibility="gone"
tools:visibility="visible"/>
</RelativeLayout>
</RelativeLayout>
</com.nirhart.parallaxscroll.views.ParallaxScrollView> </com.nirhart.parallaxscroll.views.ParallaxScrollView>
</RelativeLayout> </FrameLayout>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
android:padding="15dp">
<ProgressBar
android:id="@+id/loading_progress_bar"
style="@style/Widget.AppCompat.ProgressBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="gone"
tools:visibility="visible" />
<!--ERROR PANEL-->
<include
android:id="@+id/error_panel"
layout="@layout/error_retry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/video_item_detail_error_panel_margin"
android:visibility="gone"
tools:visibility="visible" />
</FrameLayout>

View File

@ -4,11 +4,10 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/itemRoot" android:id="@+id/itemRoot"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="@dimen/video_item_search_height"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:clickable="true" android:clickable="true"
android:orientation="vertical" android:padding="@dimen/video_item_search_padding">
android:padding="12dp">
<ImageView <ImageView
android:id="@+id/itemThumbnailView" android:id="@+id/itemThumbnailView"
@ -42,55 +41,40 @@
tools:ignore="RtlHardcoded" tools:ignore="RtlHardcoded"
tools:text="1:09:10"/> tools:text="1:09:10"/>
<RelativeLayout
<TextView
android:id="@+id/itemVideoTitleView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/video_item_search_thumbnail_image_height" android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="@id/itemThumbnailView" android:layout_toRightOf="@id/itemThumbnailView"
android:orientation="vertical" android:ellipsize="end"
tools:ignore="RtlHardcoded"> android:lines="2"
android:maxLines="2"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="@dimen/video_item_search_title_text_size"
tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blanditLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsum"/>
<TextView <TextView
android:id="@+id/itemVideoTitleView" android:id="@+id/itemUploaderView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_above="@+id/itemUploaderView" android:layout_above="@id/itemAdditionalDetails"
android:layout_alignParentTop="true" android:layout_toRightOf="@id/itemThumbnailView"
android:ellipsize="end" android:lines="1"
android:maxLines="2" android:layout_marginBottom="@dimen/video_item_detail_description_to_details_margin"
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/video_item_search_title_text_size" android:textSize="@dimen/video_item_search_uploader_text_size"
tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique vitae sem vitae blanditLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsumLorem ipsum"/> tools:text="Uploader"/>
<TextView <TextView
android:id="@+id/itemUploaderView" android:id="@+id/itemAdditionalDetails"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_above="@+id/itemUploadDateView" android:layout_alignParentBottom="true"
android:maxLines="1" android:layout_toRightOf="@id/itemThumbnailView"
android:textAppearance="?android:attr/textAppearanceSmall" android:lines="1"
android:textSize="@dimen/video_item_search_uploader_text_size" android:textAppearance="?android:attr/textAppearanceSmall"
tools:text="Uploader"/> android:textSize="@dimen/video_item_search_upload_date_text_size"
tools:text="2 years ago • 10M views"/>
<TextView
android:id="@+id/itemUploadDateView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/video_item_search_upload_date_text_size"
tools:text="2 years ago • "/>
<TextView
android:id="@+id/itemViewCountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toRightOf="@+id/itemUploadDateView"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textSize="@dimen/video_item_search_upload_date_text_size"
tools:text="10M views"/>
</RelativeLayout>
</RelativeLayout> </RelativeLayout>

View File

@ -37,7 +37,7 @@
android:layout_gravity="right|center_vertical" android:layout_gravity="right|center_vertical"
tools:ignore="RtlHardcoded"> tools:ignore="RtlHardcoded">
<FrameLayout <View
android:layout_width="28dp" android:layout_width="28dp"
android:layout_height="28dp" android:layout_height="28dp"
android:layout_gravity="center" android:layout_gravity="center"

View File

@ -12,6 +12,8 @@
<!-- 16 / 9 ratio--> <!-- 16 / 9 ratio-->
<dimen name="video_item_search_thumbnail_image_width">142dp</dimen> <dimen name="video_item_search_thumbnail_image_width">142dp</dimen>
<dimen name="video_item_search_thumbnail_image_height">80dp</dimen> <dimen name="video_item_search_thumbnail_image_height">80dp</dimen>
<!-- Calculated: 2*video_item_search_padding + video_item_search_thumbnail_image_height -->
<dimen name="video_item_search_height">104dp</dimen>
<!-- Paddings & Margins --> <!-- Paddings & Margins -->
<dimen name="video_item_search_image_right_margin">10dp</dimen> <dimen name="video_item_search_image_right_margin">10dp</dimen>
<dimen name="video_item_search_duration_vertical_padding">1sp</dimen> <dimen name="video_item_search_duration_vertical_padding">1sp</dimen>

View File

@ -11,11 +11,15 @@
<!-- 16 / 9 ratio--> <!-- 16 / 9 ratio-->
<dimen name="video_item_search_thumbnail_image_width">124dp</dimen> <dimen name="video_item_search_thumbnail_image_width">124dp</dimen>
<dimen name="video_item_search_thumbnail_image_height">70dp</dimen> <dimen name="video_item_search_thumbnail_image_height">70dp</dimen>
<!-- Calculated: 2*video_item_search_padding + video_item_search_thumbnail_image_height -->
<dimen name="video_item_search_height">94dp</dimen>
<!-- Paddings & Margins --> <!-- Paddings & Margins -->
<dimen name="video_item_search_padding">12dp</dimen>
<dimen name="video_item_search_image_right_margin">6dp</dimen> <dimen name="video_item_search_image_right_margin">6dp</dimen>
<dimen name="video_item_search_duration_vertical_padding">1sp</dimen> <dimen name="video_item_search_duration_vertical_padding">1sp</dimen>
<dimen name="video_item_search_duration_horizontal_padding">5sp</dimen> <dimen name="video_item_search_duration_horizontal_padding">5sp</dimen>
<dimen name="video_item_search_duration_margin">2sp</dimen> <dimen name="video_item_search_duration_margin">2sp</dimen>
<dimen name="video_item_detail_description_to_details_margin">4dp</dimen>
<!-- Miscellaneous --> <!-- Miscellaneous -->
<dimen name="popup_default_width">180dp</dimen> <dimen name="popup_default_width">180dp</dimen>
<dimen name="popup_minimum_width">120dp</dimen> <dimen name="popup_minimum_width">120dp</dimen>