similar videos scroll bug workaround
This commit is contained in:
parent
85e2b124ab
commit
60e18aa045
7 changed files with 351 additions and 304 deletions
|
@ -26,6 +26,7 @@ import org.schabi.newpipe.extractor.ExtractionException;
|
||||||
import org.schabi.newpipe.extractor.ParsingException;
|
import org.schabi.newpipe.extractor.ParsingException;
|
||||||
import org.schabi.newpipe.extractor.ServiceList;
|
import org.schabi.newpipe.extractor.ServiceList;
|
||||||
import org.schabi.newpipe.extractor.StreamingService;
|
import org.schabi.newpipe.extractor.StreamingService;
|
||||||
|
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||||
import org.schabi.newpipe.info_list.InfoListAdapter;
|
import org.schabi.newpipe.info_list.InfoListAdapter;
|
||||||
import org.schabi.newpipe.report.ErrorActivity;
|
import org.schabi.newpipe.report.ErrorActivity;
|
||||||
|
|
||||||
|
@ -84,7 +85,7 @@ public class ChannelActivity extends AppCompatActivity {
|
||||||
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
|
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
|
||||||
recyclerView.setLayoutManager(layoutManager);
|
recyclerView.setLayoutManager(layoutManager);
|
||||||
recyclerView.setAdapter(infoListAdapter);
|
recyclerView.setAdapter(infoListAdapter);
|
||||||
infoListAdapter.setOnItemSelectedListener(new InfoListAdapter.OnItemSelectedListener() {
|
infoListAdapter.setOnItemSelectedListener(new InfoItemBuilder.OnItemSelectedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void selected(String url) {
|
public void selected(String url) {
|
||||||
Intent detailIntent = new Intent(ChannelActivity.this, VideoItemDetailActivity.class);
|
Intent detailIntent = new Intent(ChannelActivity.this, VideoItemDetailActivity.class);
|
||||||
|
|
|
@ -14,7 +14,6 @@ import android.support.design.widget.FloatingActionButton;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
import android.text.method.LinkMovementMethod;
|
import android.text.method.LinkMovementMethod;
|
||||||
|
@ -27,6 +26,7 @@ import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
@ -43,6 +43,8 @@ import java.util.Vector;
|
||||||
|
|
||||||
import org.schabi.newpipe.ActivityCommunicator;
|
import org.schabi.newpipe.ActivityCommunicator;
|
||||||
import org.schabi.newpipe.ChannelActivity;
|
import org.schabi.newpipe.ChannelActivity;
|
||||||
|
import org.schabi.newpipe.extractor.StreamPreviewInfo;
|
||||||
|
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||||
import org.schabi.newpipe.report.ErrorActivity;
|
import org.schabi.newpipe.report.ErrorActivity;
|
||||||
import org.schabi.newpipe.ImageErrorLoadingListener;
|
import org.schabi.newpipe.ImageErrorLoadingListener;
|
||||||
import org.schabi.newpipe.Localization;
|
import org.schabi.newpipe.Localization;
|
||||||
|
@ -53,7 +55,6 @@ import org.schabi.newpipe.extractor.MediaFormat;
|
||||||
import org.schabi.newpipe.extractor.ServiceList;
|
import org.schabi.newpipe.extractor.ServiceList;
|
||||||
import org.schabi.newpipe.extractor.StreamInfo;
|
import org.schabi.newpipe.extractor.StreamInfo;
|
||||||
import org.schabi.newpipe.extractor.VideoStream;
|
import org.schabi.newpipe.extractor.VideoStream;
|
||||||
import org.schabi.newpipe.info_list.InfoListAdapter;
|
|
||||||
import org.schabi.newpipe.player.BackgroundPlayer;
|
import org.schabi.newpipe.player.BackgroundPlayer;
|
||||||
import org.schabi.newpipe.player.PlayVideoActivity;
|
import org.schabi.newpipe.player.PlayVideoActivity;
|
||||||
import org.schabi.newpipe.player.ExoPlayerActivity;
|
import org.schabi.newpipe.player.ExoPlayerActivity;
|
||||||
|
@ -110,7 +111,7 @@ public class VideoItemDetailFragment extends Fragment {
|
||||||
private DisplayImageOptions displayImageOptions =
|
private DisplayImageOptions displayImageOptions =
|
||||||
new DisplayImageOptions.Builder().cacheInMemory(true).build();
|
new DisplayImageOptions.Builder().cacheInMemory(true).build();
|
||||||
|
|
||||||
private InfoListAdapter similarStreamsAdapter = null;
|
private InfoItemBuilder infoItemBuilder = null;
|
||||||
|
|
||||||
public interface OnInvokeCreateOptionsMenuListener {
|
public interface OnInvokeCreateOptionsMenuListener {
|
||||||
void createOptionsMenu();
|
void createOptionsMenu();
|
||||||
|
@ -119,183 +120,173 @@ public class VideoItemDetailFragment extends Fragment {
|
||||||
private OnInvokeCreateOptionsMenuListener onInvokeCreateOptionsMenuListener;
|
private OnInvokeCreateOptionsMenuListener onInvokeCreateOptionsMenuListener;
|
||||||
|
|
||||||
private void updateInfo(final StreamInfo info) {
|
private void updateInfo(final StreamInfo info) {
|
||||||
try {
|
Activity a = getActivity();
|
||||||
Activity a = getActivity();
|
|
||||||
|
|
||||||
RelativeLayout textContentLayout =
|
RelativeLayout textContentLayout =
|
||||||
(RelativeLayout) activity.findViewById(R.id.detail_text_content_layout);
|
(RelativeLayout) activity.findViewById(R.id.detail_text_content_layout);
|
||||||
final TextView videoTitleView =
|
final TextView videoTitleView =
|
||||||
(TextView) activity.findViewById(R.id.detail_video_title_view);
|
(TextView) activity.findViewById(R.id.detail_video_title_view);
|
||||||
TextView uploaderView = (TextView) activity.findViewById(R.id.detail_uploader_view);
|
TextView uploaderView = (TextView) activity.findViewById(R.id.detail_uploader_view);
|
||||||
TextView viewCountView = (TextView) activity.findViewById(R.id.detail_view_count_view);
|
TextView viewCountView = (TextView) activity.findViewById(R.id.detail_view_count_view);
|
||||||
TextView thumbsUpView = (TextView) activity.findViewById(R.id.detail_thumbs_up_count_view);
|
TextView thumbsUpView = (TextView) activity.findViewById(R.id.detail_thumbs_up_count_view);
|
||||||
TextView thumbsDownView =
|
TextView thumbsDownView =
|
||||||
(TextView) activity.findViewById(R.id.detail_thumbs_down_count_view);
|
(TextView) activity.findViewById(R.id.detail_thumbs_down_count_view);
|
||||||
TextView uploadDateView = (TextView) activity.findViewById(R.id.detail_upload_date_view);
|
TextView uploadDateView = (TextView) activity.findViewById(R.id.detail_upload_date_view);
|
||||||
TextView descriptionView = (TextView) activity.findViewById(R.id.detail_description_view);
|
TextView descriptionView = (TextView) activity.findViewById(R.id.detail_description_view);
|
||||||
RecyclerView nextStreamView =
|
RecyclerView nextStreamView =
|
||||||
(RecyclerView) activity.findViewById(R.id.detail_next_stream_content);
|
(RecyclerView) activity.findViewById(R.id.detail_next_stream_content);
|
||||||
RelativeLayout nextVideoRootFrame =
|
RelativeLayout nextVideoRootFrame =
|
||||||
(RelativeLayout) activity.findViewById(R.id.detail_next_stream_root_layout);
|
(RelativeLayout) activity.findViewById(R.id.detail_next_stream_root_layout);
|
||||||
TextView similarTitle = (TextView) activity.findViewById(R.id.detail_similar_title);
|
TextView similarTitle = (TextView) activity.findViewById(R.id.detail_similar_title);
|
||||||
Button backgroundButton = (Button)
|
Button backgroundButton = (Button)
|
||||||
activity.findViewById(R.id.detail_stream_thumbnail_window_background_button);
|
activity.findViewById(R.id.detail_stream_thumbnail_window_background_button);
|
||||||
View topView = activity.findViewById(R.id.detailTopView);
|
View topView = activity.findViewById(R.id.detailTopView);
|
||||||
Button channelButton = (Button) activity.findViewById(R.id.channel_button);
|
Button channelButton = (Button) activity.findViewById(R.id.channel_button);
|
||||||
|
|
||||||
progressBar.setVisibility(View.GONE);
|
progressBar.setVisibility(View.GONE);
|
||||||
if(info.next_video != null) {
|
if(info.next_video != null) {
|
||||||
InfoListAdapter adapter = new InfoListAdapter(a, rootView);
|
infoItemBuilder.setOnItemSelectedListener(new InfoItemBuilder.OnItemSelectedListener() {
|
||||||
nextStreamView.setAdapter(adapter);
|
|
||||||
nextStreamView.setLayoutManager(new LinearLayoutManager(a));
|
|
||||||
adapter.setOnItemSelectedListener(new InfoListAdapter.OnItemSelectedListener() {
|
|
||||||
@Override
|
|
||||||
public void selected(String url) {
|
|
||||||
openStreamUrl(url);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
nextStreamView.setVisibility(View.GONE);
|
|
||||||
activity.findViewById(R.id.detail_similar_title).setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
textContentLayout.setVisibility(View.VISIBLE);
|
|
||||||
if (android.os.Build.VERSION.SDK_INT < 18) {
|
|
||||||
playVideoButton.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
|
||||||
ImageView playArrowView = (ImageView) activity.findViewById(R.id.play_arrow_view);
|
|
||||||
playArrowView.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!showNextStreamItem) {
|
|
||||||
nextVideoRootFrame.setVisibility(View.GONE);
|
|
||||||
similarTitle.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
videoTitleView.setText(info.title);
|
|
||||||
|
|
||||||
topView.setOnTouchListener(new View.OnTouchListener() {
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
public void selected(String url) {
|
||||||
if (event.getAction() == android.view.MotionEvent.ACTION_UP) {
|
openStreamUrl(url);
|
||||||
ImageView arrow = (ImageView) activity.findViewById(R.id.toggle_description_view);
|
|
||||||
View extra = activity.findViewById(R.id.detailExtraView);
|
|
||||||
if (extra.getVisibility() == View.VISIBLE) {
|
|
||||||
extra.setVisibility(View.GONE);
|
|
||||||
arrow.setImageResource(R.drawable.arrow_down);
|
|
||||||
} else {
|
|
||||||
extra.setVisibility(View.VISIBLE);
|
|
||||||
arrow.setImageResource(R.drawable.arrow_up);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
nextStreamView.setVisibility(View.GONE);
|
||||||
|
activity.findViewById(R.id.detail_similar_title).setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
// Since newpipe is designed to work even if certain information is not available,
|
textContentLayout.setVisibility(View.VISIBLE);
|
||||||
// the UI has to react on missing information.
|
if (android.os.Build.VERSION.SDK_INT < 18) {
|
||||||
videoTitleView.setText(info.title);
|
playVideoButton.setVisibility(View.VISIBLE);
|
||||||
if(!info.uploader.isEmpty()) {
|
} else {
|
||||||
uploaderView.setText(info.uploader);
|
ImageView playArrowView = (ImageView) activity.findViewById(R.id.play_arrow_view);
|
||||||
} else {
|
playArrowView.setVisibility(View.VISIBLE);
|
||||||
activity.findViewById(R.id.detail_uploader_view).setVisibility(View.GONE);
|
}
|
||||||
}
|
|
||||||
if(info.view_count >= 0) {
|
|
||||||
viewCountView.setText(Localization.localizeViewCount(info.view_count, a));
|
|
||||||
} else {
|
|
||||||
viewCountView.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
if(info.dislike_count >= 0) {
|
|
||||||
thumbsDownView.setText(Localization.localizeNumber(info.dislike_count, a));
|
|
||||||
} else {
|
|
||||||
thumbsDownView.setVisibility(View.INVISIBLE);
|
|
||||||
activity.findViewById(R.id.detail_thumbs_down_count_view).setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
if(info.like_count >= 0) {
|
|
||||||
thumbsUpView.setText(Localization.localizeNumber(info.like_count, a));
|
|
||||||
} else {
|
|
||||||
thumbsUpView.setVisibility(View.GONE);
|
|
||||||
activity.findViewById(R.id.detail_thumbs_up_img_view).setVisibility(View.GONE);
|
|
||||||
thumbsDownView.setVisibility(View.GONE);
|
|
||||||
activity.findViewById(R.id.detail_thumbs_down_img_view).setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
if(!info.upload_date.isEmpty()) {
|
|
||||||
uploadDateView.setText(Localization.localizeDate(info.upload_date, a));
|
|
||||||
} else {
|
|
||||||
uploadDateView.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
if(!info.description.isEmpty()) {
|
|
||||||
descriptionView.setText(Html.fromHtml(info.description));
|
|
||||||
} else {
|
|
||||||
descriptionView.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
descriptionView.setMovementMethod(LinkMovementMethod.getInstance());
|
if (!showNextStreamItem) {
|
||||||
|
nextVideoRootFrame.setVisibility(View.GONE);
|
||||||
|
similarTitle.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
// parse streams
|
videoTitleView.setText(info.title);
|
||||||
Vector<VideoStream> streamsToUse = new Vector<>();
|
|
||||||
for (VideoStream i : info.video_streams) {
|
|
||||||
if (useStream(i, streamsToUse)) {
|
|
||||||
streamsToUse.add(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
textContentLayout.setVisibility(View.VISIBLE);
|
topView.setOnTouchListener(new View.OnTouchListener() {
|
||||||
|
@Override
|
||||||
if(info.next_video == null) {
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
activity.findViewById(R.id.detail_next_stream_title).setVisibility(View.GONE);
|
if (event.getAction() == android.view.MotionEvent.ACTION_UP) {
|
||||||
}
|
ImageView arrow = (ImageView) activity.findViewById(R.id.toggle_description_view);
|
||||||
|
View extra = activity.findViewById(R.id.detailExtraView);
|
||||||
if(info.related_streams != null && !info.related_streams.isEmpty()) {
|
if (extra.getVisibility() == View.VISIBLE) {
|
||||||
initSimilarVideos(info);
|
extra.setVisibility(View.GONE);
|
||||||
} else {
|
arrow.setImageResource(R.drawable.arrow_down);
|
||||||
activity.findViewById(R.id.detail_similar_title).setVisibility(View.GONE);
|
} else {
|
||||||
activity.findViewById(R.id.similar_streams_view).setVisibility(View.GONE);
|
extra.setVisibility(View.VISIBLE);
|
||||||
}
|
arrow.setImageResource(R.drawable.arrow_up);
|
||||||
|
|
||||||
setupActionBarHandler(info);
|
|
||||||
|
|
||||||
if(autoPlayEnabled) {
|
|
||||||
playVideo(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (android.os.Build.VERSION.SDK_INT < 18) {
|
|
||||||
playVideoButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
playVideo(info);
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
backgroundButton.setOnClickListener(new View.OnClickListener() {
|
// Since newpipe is designed to work even if certain information is not available,
|
||||||
|
// the UI has to react on missing information.
|
||||||
|
videoTitleView.setText(info.title);
|
||||||
|
if(!info.uploader.isEmpty()) {
|
||||||
|
uploaderView.setText(info.uploader);
|
||||||
|
} else {
|
||||||
|
activity.findViewById(R.id.detail_uploader_view).setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
if(info.view_count >= 0) {
|
||||||
|
viewCountView.setText(Localization.localizeViewCount(info.view_count, a));
|
||||||
|
} else {
|
||||||
|
viewCountView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
if(info.dislike_count >= 0) {
|
||||||
|
thumbsDownView.setText(Localization.localizeNumber(info.dislike_count, a));
|
||||||
|
} else {
|
||||||
|
thumbsDownView.setVisibility(View.INVISIBLE);
|
||||||
|
activity.findViewById(R.id.detail_thumbs_down_count_view).setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
if(info.like_count >= 0) {
|
||||||
|
thumbsUpView.setText(Localization.localizeNumber(info.like_count, a));
|
||||||
|
} else {
|
||||||
|
thumbsUpView.setVisibility(View.GONE);
|
||||||
|
activity.findViewById(R.id.detail_thumbs_up_img_view).setVisibility(View.GONE);
|
||||||
|
thumbsDownView.setVisibility(View.GONE);
|
||||||
|
activity.findViewById(R.id.detail_thumbs_down_img_view).setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
if(!info.upload_date.isEmpty()) {
|
||||||
|
uploadDateView.setText(Localization.localizeDate(info.upload_date, a));
|
||||||
|
} else {
|
||||||
|
uploadDateView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
if(!info.description.isEmpty()) {
|
||||||
|
descriptionView.setText(Html.fromHtml(info.description));
|
||||||
|
} else {
|
||||||
|
descriptionView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
|
|
||||||
|
// parse streams
|
||||||
|
Vector<VideoStream> streamsToUse = new Vector<>();
|
||||||
|
for (VideoStream i : info.video_streams) {
|
||||||
|
if (useStream(i, streamsToUse)) {
|
||||||
|
streamsToUse.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
textContentLayout.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
if(info.next_video == null) {
|
||||||
|
activity.findViewById(R.id.detail_next_stream_title).setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(info.related_streams != null && !info.related_streams.isEmpty()) {
|
||||||
|
initSimilarVideos(info);
|
||||||
|
} else {
|
||||||
|
activity.findViewById(R.id.detail_similar_title).setVisibility(View.GONE);
|
||||||
|
activity.findViewById(R.id.similar_streams_view).setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
setupActionBarHandler(info);
|
||||||
|
|
||||||
|
if(autoPlayEnabled) {
|
||||||
|
playVideo(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (android.os.Build.VERSION.SDK_INT < 18) {
|
||||||
|
playVideoButton.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
playVideo(info);
|
playVideo(info);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if(info.channel_url != null && info.channel_url != "") {
|
|
||||||
channelButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
Intent i = new Intent(activity, ChannelActivity.class);
|
|
||||||
i.putExtra(ChannelActivity.CHANNEL_URL, info.channel_url);
|
|
||||||
i.putExtra(ChannelActivity.SERVICE_ID, info.service_id);
|
|
||||||
startActivity(i);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
channelButton.setVisibility(Button.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
initThumbnailViews(info);
|
|
||||||
|
|
||||||
} catch (java.lang.NullPointerException e) {
|
|
||||||
Log.w(TAG, "updateInfo(): Fragment closed before thread ended work... or else");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
backgroundButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
playVideo(info);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(info.channel_url != null && info.channel_url != "") {
|
||||||
|
channelButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
Intent i = new Intent(activity, ChannelActivity.class);
|
||||||
|
i.putExtra(ChannelActivity.CHANNEL_URL, info.channel_url);
|
||||||
|
i.putExtra(ChannelActivity.SERVICE_ID, info.service_id);
|
||||||
|
startActivity(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
channelButton.setVisibility(Button.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
initThumbnailViews(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initThumbnailViews(final StreamInfo info) {
|
private void initThumbnailViews(final StreamInfo info) {
|
||||||
|
@ -527,7 +518,10 @@ public class VideoItemDetailFragment extends Fragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initSimilarVideos(final StreamInfo info) {
|
private void initSimilarVideos(final StreamInfo info) {
|
||||||
similarStreamsAdapter.addStreamItemList(info.related_streams);
|
LinearLayout similarLayout = (LinearLayout) activity.findViewById(R.id.similar_streams_view);
|
||||||
|
for (final StreamPreviewInfo item : info.related_streams) {
|
||||||
|
similarLayout.addView(infoItemBuilder.buildView(similarLayout, item));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onErrorBlockedByGema() {
|
private void onErrorBlockedByGema() {
|
||||||
|
@ -640,6 +634,9 @@ public class VideoItemDetailFragment extends Fragment {
|
||||||
public void onActivityCreated(Bundle savedInstanceBundle) {
|
public void onActivityCreated(Bundle savedInstanceBundle) {
|
||||||
super.onActivityCreated(savedInstanceBundle);
|
super.onActivityCreated(savedInstanceBundle);
|
||||||
Activity a = getActivity();
|
Activity a = getActivity();
|
||||||
|
|
||||||
|
infoItemBuilder = new InfoItemBuilder(a, a.findViewById(android.R.id.content));
|
||||||
|
|
||||||
if (android.os.Build.VERSION.SDK_INT < 18) {
|
if (android.os.Build.VERSION.SDK_INT < 18) {
|
||||||
playVideoButton = (FloatingActionButton) a.findViewById(R.id.play_video_button);
|
playVideoButton = (FloatingActionButton) a.findViewById(R.id.play_video_button);
|
||||||
}
|
}
|
||||||
|
@ -681,17 +678,6 @@ public class VideoItemDetailFragment extends Fragment {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
similarStreamsAdapter = new InfoListAdapter(getActivity(), rootView);
|
|
||||||
RecyclerView rv = (RecyclerView) getActivity().findViewById(R.id.similar_streams_view);
|
|
||||||
rv.setLayoutManager(new LinearLayoutManager(getActivity()));
|
|
||||||
rv.setAdapter(similarStreamsAdapter);
|
|
||||||
similarStreamsAdapter.setOnItemSelectedListener(new InfoListAdapter.OnItemSelectedListener() {
|
|
||||||
@Override
|
|
||||||
public void selected(String url) {
|
|
||||||
openStreamUrl(url);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,174 @@
|
||||||
|
package org.schabi.newpipe.info_list;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||||
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.ImageErrorLoadingListener;
|
||||||
|
import org.schabi.newpipe.R;
|
||||||
|
import org.schabi.newpipe.extractor.AbstractVideoInfo;
|
||||||
|
import org.schabi.newpipe.extractor.StreamPreviewInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Christian Schabesberger on 26.09.16.
|
||||||
|
*
|
||||||
|
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
|
||||||
|
* InfoItemBuilder.java is part of NewPipe.
|
||||||
|
*
|
||||||
|
* NewPipe is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* NewPipe is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InfoItemBuilder {
|
||||||
|
|
||||||
|
public interface OnItemSelectedListener {
|
||||||
|
void selected(String url);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Activity activity = null;
|
||||||
|
private View rootView = null;
|
||||||
|
private ImageLoader imageLoader = ImageLoader.getInstance();
|
||||||
|
private DisplayImageOptions displayImageOptions =
|
||||||
|
new DisplayImageOptions.Builder().cacheInMemory(true).build();
|
||||||
|
private OnItemSelectedListener onItemSelectedListener;
|
||||||
|
|
||||||
|
public InfoItemBuilder(Activity a, View rootView) {
|
||||||
|
activity = a;
|
||||||
|
this.rootView = rootView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnItemSelectedListener(OnItemSelectedListener onItemSelectedListener) {
|
||||||
|
this.onItemSelectedListener = onItemSelectedListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void buildByHolder(InfoItemHolder holder, final StreamPreviewInfo info) {
|
||||||
|
// fill holder with information
|
||||||
|
holder.itemVideoTitleView.setText(info.title);
|
||||||
|
if(info.uploader != null && !info.uploader.isEmpty()) {
|
||||||
|
holder.itemUploaderView.setText(info.uploader);
|
||||||
|
} else {
|
||||||
|
holder.itemUploaderView.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
if(info.duration > 0) {
|
||||||
|
holder.itemDurationView.setText(getDurationString(info.duration));
|
||||||
|
} else {
|
||||||
|
if(info.stream_type == AbstractVideoInfo.StreamType.LIVE_STREAM) {
|
||||||
|
holder.itemDurationView.setText(R.string.duration_live);
|
||||||
|
} else {
|
||||||
|
holder.itemDurationView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(info.view_count >= 0) {
|
||||||
|
holder.itemViewCountView.setText(shortViewCount(info.view_count));
|
||||||
|
} else {
|
||||||
|
holder.itemViewCountView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
if(info.upload_date != null && !info.upload_date.isEmpty()) {
|
||||||
|
holder.itemUploadDateView.setText(info.upload_date + " • ");
|
||||||
|
}
|
||||||
|
|
||||||
|
holder.itemThumbnailView.setImageResource(R.drawable.dummy_thumbnail);
|
||||||
|
if(info.thumbnail_url != null && !info.thumbnail_url.isEmpty()) {
|
||||||
|
imageLoader.displayImage(info.thumbnail_url,
|
||||||
|
holder.itemThumbnailView,
|
||||||
|
displayImageOptions,
|
||||||
|
new ImageErrorLoadingListener(activity, rootView, info.service_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
holder.itemButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
onItemSelectedListener.selected(info.webpage_url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public View buildView(ViewGroup parent, final StreamPreviewInfo info) {
|
||||||
|
View streamPreviewView = LayoutInflater.from(parent.getContext())
|
||||||
|
.inflate(R.layout.video_item, parent, false);
|
||||||
|
InfoItemHolder holder = new InfoItemHolder(streamPreviewView);
|
||||||
|
buildByHolder(holder, info);
|
||||||
|
return streamPreviewView;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String shortViewCount(Long viewCount){
|
||||||
|
if(viewCount >= 1000000000){
|
||||||
|
return Long.toString(viewCount/1000000000)+"B views";
|
||||||
|
}else if(viewCount>=1000000){
|
||||||
|
return Long.toString(viewCount/1000000)+"M views";
|
||||||
|
}else if(viewCount>=1000){
|
||||||
|
return Long.toString(viewCount/1000)+"K views";
|
||||||
|
}else {
|
||||||
|
return Long.toString(viewCount)+" views";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDurationString(int duration) {
|
||||||
|
String output = "";
|
||||||
|
int days = duration / (24 * 60 * 60); /* greater than a day */
|
||||||
|
duration %= (24 * 60 * 60);
|
||||||
|
int hours = duration / (60 * 60); /* greater than an hour */
|
||||||
|
duration %= (60 * 60);
|
||||||
|
int minutes = duration / 60;
|
||||||
|
int seconds = duration % 60;
|
||||||
|
|
||||||
|
//handle days
|
||||||
|
if(days > 0) {
|
||||||
|
output = Integer.toString(days) + ":";
|
||||||
|
}
|
||||||
|
// handle hours
|
||||||
|
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 {
|
||||||
|
output += "0" + Integer.toString(seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
|
@ -39,27 +39,16 @@ import java.util.Vector;
|
||||||
|
|
||||||
public class InfoListAdapter extends RecyclerView.Adapter<InfoItemHolder> {
|
public class InfoListAdapter extends RecyclerView.Adapter<InfoItemHolder> {
|
||||||
|
|
||||||
public interface OnItemSelectedListener {
|
InfoItemBuilder infoItemBuilder = null;
|
||||||
void selected(String url);
|
List<StreamPreviewInfo> streamList = new Vector<>();
|
||||||
}
|
|
||||||
|
|
||||||
private Activity activity = null;
|
|
||||||
private View rootView = null;
|
|
||||||
private List<StreamPreviewInfo> streamList = new Vector<>();
|
|
||||||
private ImageLoader imageLoader = ImageLoader.getInstance();
|
|
||||||
private DisplayImageOptions displayImageOptions =
|
|
||||||
new DisplayImageOptions.Builder().cacheInMemory(true).build();
|
|
||||||
private OnItemSelectedListener onItemSelectedListener;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public InfoListAdapter(Activity a, View rootView) {
|
public InfoListAdapter(Activity a, View rootView) {
|
||||||
activity = a;
|
infoItemBuilder = new InfoItemBuilder(a, rootView);
|
||||||
this.rootView = rootView;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOnItemSelectedListener(OnItemSelectedListener onItemSelectedListener) {
|
public void setOnItemSelectedListener
|
||||||
this.onItemSelectedListener = onItemSelectedListener;
|
(InfoItemBuilder.OnItemSelectedListener onItemSelectedListener) {
|
||||||
|
infoItemBuilder.setOnItemSelectedListener(onItemSelectedListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addStreamItemList(List<StreamPreviewInfo> videos) {
|
public void addStreamItemList(List<StreamPreviewInfo> videos) {
|
||||||
|
@ -89,112 +78,6 @@ public class InfoListAdapter extends RecyclerView.Adapter<InfoItemHolder> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(InfoItemHolder holder, int i) {
|
public void onBindViewHolder(InfoItemHolder holder, int i) {
|
||||||
final StreamPreviewInfo info = streamList.get(i);
|
infoItemBuilder.buildByHolder(holder, streamList.get(i));
|
||||||
// fill holder with information
|
|
||||||
holder.itemVideoTitleView.setText(info.title);
|
|
||||||
if(info.uploader != null && !info.uploader.isEmpty()) {
|
|
||||||
holder.itemUploaderView.setText(info.uploader);
|
|
||||||
} else {
|
|
||||||
holder.itemUploaderView.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
|
||||||
if(info.duration > 0) {
|
|
||||||
holder.itemDurationView.setText(getDurationString(info.duration));
|
|
||||||
} else {
|
|
||||||
if(info.stream_type == AbstractVideoInfo.StreamType.LIVE_STREAM) {
|
|
||||||
holder.itemDurationView.setText(R.string.duration_live);
|
|
||||||
} else {
|
|
||||||
holder.itemDurationView.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(info.view_count >= 0) {
|
|
||||||
holder.itemViewCountView.setText(shortViewCount(info.view_count));
|
|
||||||
} else {
|
|
||||||
holder.itemViewCountView.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
if(info.upload_date != null && !info.upload_date.isEmpty()) {
|
|
||||||
holder.itemUploadDateView.setText(info.upload_date + " • ");
|
|
||||||
}
|
|
||||||
|
|
||||||
holder.itemThumbnailView.setImageResource(R.drawable.dummy_thumbnail);
|
|
||||||
if(info.thumbnail_url != null && !info.thumbnail_url.isEmpty()) {
|
|
||||||
imageLoader.displayImage(info.thumbnail_url,
|
|
||||||
holder.itemThumbnailView,
|
|
||||||
displayImageOptions,
|
|
||||||
new ImageErrorLoadingListener(activity, rootView, info.service_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
holder.itemButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
onItemSelectedListener.selected(info.webpage_url);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static String shortViewCount(Long viewCount){
|
|
||||||
if(viewCount >= 1000000000){
|
|
||||||
return Long.toString(viewCount/1000000000)+"B views";
|
|
||||||
}else if(viewCount>=1000000){
|
|
||||||
return Long.toString(viewCount/1000000)+"M views";
|
|
||||||
}else if(viewCount>=1000){
|
|
||||||
return Long.toString(viewCount/1000)+"K views";
|
|
||||||
}else {
|
|
||||||
return Long.toString(viewCount)+" views";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getDurationString(int duration) {
|
|
||||||
String output = "";
|
|
||||||
int days = duration / (24 * 60 * 60); /* greater than a day */
|
|
||||||
duration %= (24 * 60 * 60);
|
|
||||||
int hours = duration / (60 * 60); /* greater than an hour */
|
|
||||||
duration %= (60 * 60);
|
|
||||||
int minutes = duration / 60;
|
|
||||||
int seconds = duration % 60;
|
|
||||||
|
|
||||||
//handle days
|
|
||||||
if(days > 0) {
|
|
||||||
output = Integer.toString(days) + ":";
|
|
||||||
}
|
|
||||||
// handle hours
|
|
||||||
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 {
|
|
||||||
output += "0" + Integer.toString(seconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.info_list.InfoItemBuilder;
|
||||||
import org.schabi.newpipe.report.ErrorActivity;
|
import org.schabi.newpipe.report.ErrorActivity;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.detail.VideoItemDetailActivity;
|
import org.schabi.newpipe.detail.VideoItemDetailActivity;
|
||||||
|
@ -189,7 +190,7 @@ public class SearchInfoItemFragment extends Fragment {
|
||||||
|
|
||||||
infoListAdapter = new InfoListAdapter(getActivity(),
|
infoListAdapter = new InfoListAdapter(getActivity(),
|
||||||
getActivity().findViewById(android.R.id.content));
|
getActivity().findViewById(android.R.id.content));
|
||||||
infoListAdapter.setOnItemSelectedListener(new InfoListAdapter.OnItemSelectedListener() {
|
infoListAdapter.setOnItemSelectedListener(new InfoItemBuilder.OnItemSelectedListener() {
|
||||||
@Override
|
@Override
|
||||||
public void selected(String url) {
|
public void selected(String url) {
|
||||||
Intent i = new Intent(getActivity(), VideoItemDetailActivity.class);
|
Intent i = new Intent(getActivity(), VideoItemDetailActivity.class);
|
||||||
|
|
|
@ -265,12 +265,13 @@
|
||||||
android:text="@string/similar_videos_btn_text"
|
android:text="@string/similar_videos_btn_text"
|
||||||
android:layout_below="@id/detail_next_stream_content"
|
android:layout_below="@id/detail_next_stream_content"
|
||||||
android:textAllCaps="true" />
|
android:textAllCaps="true" />
|
||||||
<android.support.v7.widget.RecyclerView
|
<LinearLayout
|
||||||
android:id="@+id/similar_streams_view"
|
android:id="@+id/similar_streams_view"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
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_similar_title"/>
|
android:layout_below="@id/detail_similar_title">
|
||||||
|
</LinearLayout>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
|
@ -267,12 +267,13 @@
|
||||||
android:text="@string/similar_videos_btn_text"
|
android:text="@string/similar_videos_btn_text"
|
||||||
android:layout_below="@id/detail_next_stream_content"
|
android:layout_below="@id/detail_next_stream_content"
|
||||||
android:textAllCaps="true" />
|
android:textAllCaps="true" />
|
||||||
<android.support.v7.widget.RecyclerView
|
<LinearLayout
|
||||||
android:id="@+id/similar_streams_view"
|
android:id="@+id/similar_streams_view"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
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_similar_title"/>
|
android:layout_below="@id/detail_similar_title">
|
||||||
|
</LinearLayout>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
Loading…
Reference in a new issue