1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2024-06-25 22:53:20 +00:00

add recycler view adapter

This commit is contained in:
Christian Schabesberger 2016-08-02 00:58:52 +02:00
parent 4164195fae
commit f34cacbc5c
9 changed files with 214 additions and 73 deletions

View File

@ -45,5 +45,4 @@ dependencies {
compile 'com.google.code.gson:gson:2.4'
compile 'com.nononsenseapps:filepicker:2.0.5'
testCompile 'junit:junit:4.12'
//compile 'net.sourceforge.cssparser:cssparser:0.9.20'
}

View File

@ -1,7 +1,6 @@
package org.schabi.newpipe;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@ -18,8 +17,6 @@ import android.widget.ProgressBar;
import android.widget.Toast;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
import org.schabi.newpipe.extractor.ChannelExtractor;
import org.schabi.newpipe.extractor.ChannelInfo;
@ -34,40 +31,10 @@ import java.util.ArrayList;
public class ChannelActivity extends AppCompatActivity {
private static final String TAG = ChannelActivity.class.toString();
private View rootView = null;
class FailedThumbnailListener implements ImageLoadingListener {
int serviceId = -1;
public FailedThumbnailListener(int serviceId) {
this.serviceId= serviceId;
}
@Override
public void onLoadingStarted(String imageUri, View view) {
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
ErrorActivity.reportError(ChannelActivity.this,
failReason.getCause(), null, rootView,
ErrorActivity.ErrorInfo.make(ErrorActivity.LOAD_IMAGE,
ServiceList.getNameOfService(serviceId), imageUri,
R.string.could_not_load_image));
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
}
@Override
public void onLoadingCancelled(String imageUri, View view) {
}
}
// intent const
public static final String CHANNEL_URL = "channel_url";
public static final String SERVICE_ID = "service_id";
@ -137,8 +104,8 @@ public class ChannelActivity extends AppCompatActivity {
private void updateUi(final ChannelInfo info) {
VideoInfoItemViewCreator viCreator =
new VideoInfoItemViewCreator(LayoutInflater.from(this), this, rootView);
StreamInfoItemViewCreator viCreator =
new StreamInfoItemViewCreator(LayoutInflater.from(this), this, rootView);
CollapsingToolbarLayout ctl = (CollapsingToolbarLayout) findViewById(R.id.channel_toolbar_layout);
ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
ImageView channelBanner = (ImageView) findViewById(R.id.channel_banner_image);
@ -156,14 +123,14 @@ public class ChannelActivity extends AppCompatActivity {
if(info.banner_url != null && !info.banner_url.isEmpty()) {
imageLoader.displayImage(info.banner_url, channelBanner,
new FailedThumbnailListener(info.service_id));
new ImageErrorLoadingListener(this, rootView ,info.service_id));
}
if(info.avatar_url != null && !info.avatar_url.isEmpty()) {
avatarView.setVisibility(View.VISIBLE);
haloView.setVisibility(View.VISIBLE);
imageLoader.displayImage(info.avatar_url, avatarView,
new FailedThumbnailListener(info.service_id));
new ImageErrorLoadingListener(this, rootView ,info.service_id));
}
if(info.feed_url != null && !info.feed_url.isEmpty()) {
@ -182,7 +149,7 @@ public class ChannelActivity extends AppCompatActivity {
initVideos(info, viCreator);
}
private void initVideos(final ChannelInfo info, VideoInfoItemViewCreator viCreator) {
private void initVideos(final ChannelInfo info, StreamInfoItemViewCreator viCreator) {
LinearLayout streamLayout = (LinearLayout) findViewById(R.id.channel_streams_view);
ArrayList<StreamPreviewInfo> streamsList = new ArrayList<>(info.related_streams);

View File

@ -15,7 +15,7 @@ import org.schabi.newpipe.extractor.ServiceList;
* Created by Christian Schabesberger on 01.08.16.
*
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
* VideoInfoItemViewCreator.java is part of NewPipe.
* StreamInfoItemViewCreator.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

View File

@ -0,0 +1,29 @@
package org.schabi.newpipe;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
/**
* Created by the-scrabi on 01.08.16.
*/
public class StreamInfoItemHolder extends RecyclerView.ViewHolder {
public ImageView itemThumbnailView;
public TextView itemVideoTitleView,
itemUploaderView,
itemDurationView,
itemUploadDateView,
itemViewCountView;
public StreamInfoItemHolder(View v) {
super(v);
itemThumbnailView = (ImageView) v.findViewById(R.id.itemThumbnailView);
itemVideoTitleView = (TextView) v.findViewById(R.id.itemVideoTitleView);
itemUploaderView = (TextView) v.findViewById(R.id.itemUploaderView);
itemDurationView = (TextView) v.findViewById(R.id.itemDurationView);
itemUploadDateView = (TextView) v.findViewById(R.id.itemUploadDateView);
itemViewCountView = (TextView) v.findViewById(R.id.itemViewCountView);
}
}

View File

@ -20,7 +20,7 @@ import org.schabi.newpipe.extractor.StreamPreviewInfo;
* Created by Christian Schabesberger on 24.10.15.
*
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
* VideoInfoItemViewCreator.java is part of NewPipe.
* StreamInfoItemViewCreator.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
@ -36,7 +36,16 @@ import org.schabi.newpipe.extractor.StreamPreviewInfo;
* along with NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/
public class VideoInfoItemViewCreator {
public class StreamInfoItemViewCreator {
private class ViewHolder {
public ImageView itemThumbnailView;
public TextView itemVideoTitleView,
itemUploaderView,
itemDurationView,
itemUploadDateView,
itemViewCountView;
}
private View rootView = null; //root view of the activty
private Activity activity = null;
@ -44,7 +53,7 @@ public class VideoInfoItemViewCreator {
private ImageLoader imageLoader = ImageLoader.getInstance();
private DisplayImageOptions displayImageOptions = new DisplayImageOptions.Builder().cacheInMemory(true).build();
public VideoInfoItemViewCreator(LayoutInflater inflater, Activity a, View rootView) {
public StreamInfoItemViewCreator(LayoutInflater inflater, Activity a, View rootView) {
this.inflater = inflater;
activity = a;
this.rootView = rootView;
@ -95,12 +104,16 @@ public class VideoInfoItemViewCreator {
holder.itemThumbnailView.setImageResource(R.drawable.dummy_thumbnail);
if(info.thumbnail_url != null && !info.thumbnail_url.isEmpty()) {
imageLoader.displayImage(info.thumbnail_url, holder.itemThumbnailView, displayImageOptions);
imageLoader.displayImage(info.thumbnail_url,
holder.itemThumbnailView,
displayImageOptions,
new ImageErrorLoadingListener(activity, rootView, info.service_id));
}
return convertView;
}
public View setupView(View convertView, final StreamPreviewInfo info) {
convertView.setClickable(true);
convertView.setFocusable(true);
@ -134,12 +147,7 @@ public class VideoInfoItemViewCreator {
return convertView;
}
private class ViewHolder {
public ImageView itemThumbnailView;
public TextView itemVideoTitleView, itemUploaderView, itemDurationView, itemUploadDateView, itemViewCountView;
}
private String shortViewCount(Long viewCount){
public static String shortViewCount(Long viewCount){
if(viewCount >= 1000000000){
return Long.toString(viewCount/1000000000)+"B views";
}else if(viewCount>=1000000){

View File

@ -0,0 +1,153 @@
package org.schabi.newpipe;
import android.app.Activity;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
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.extractor.AbstractVideoInfo;
import org.schabi.newpipe.extractor.StreamPreviewInfo;
import java.util.List;
import java.util.Vector;
/**
* Created by the-scrabi on 01.08.16.
*/
public class StreamInfoListAdapter extends RecyclerView.Adapter<StreamInfoItemHolder> {
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();
StreamInfoListAdapter(Activity a, View rootView) {
activity = a;
this.rootView = rootView;
}
@Override
public int getItemCount() {
return streamList.size();
}
@Override
public StreamInfoItemHolder onCreateViewHolder(ViewGroup parent, int i) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.video_item, parent, false);
return new StreamInfoItemHolder(itemView);
}
@Override
public void onBindViewHolder(StreamInfoItemHolder holder, int i) {
StreamPreviewInfo info = 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(StreamInfoItemViewCreator.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));
}
}
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;
}
}

View File

@ -4,7 +4,6 @@ import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
@ -50,7 +49,6 @@ import java.util.Vector;
import org.schabi.newpipe.download.DownloadDialog;
import org.schabi.newpipe.extractor.AudioStream;
import org.schabi.newpipe.extractor.ChannelExtractor;
import org.schabi.newpipe.extractor.MediaFormat;
import org.schabi.newpipe.extractor.ParsingException;
import org.schabi.newpipe.extractor.ServiceList;
@ -266,8 +264,8 @@ public class VideoItemDetailFragment extends Fragment {
private void updateInfo(final StreamInfo info) {
try {
Context c = getContext();
VideoInfoItemViewCreator videoItemViewCreator =
new VideoInfoItemViewCreator(LayoutInflater.from(getActivity()),
StreamInfoItemViewCreator videoItemViewCreator =
new StreamInfoItemViewCreator(LayoutInflater.from(getActivity()),
getActivity(), rootView);
RelativeLayout textContentLayout =
@ -688,7 +686,7 @@ public class VideoItemDetailFragment extends Fragment {
return 0;
}
private void initSimilarVideos(final StreamInfo info, VideoInfoItemViewCreator videoItemViewCreator) {
private void initSimilarVideos(final StreamInfo info, StreamInfoItemViewCreator videoItemViewCreator) {
LinearLayout similarLayout = (LinearLayout) activity.findViewById(R.id.similarVideosView);
ArrayList<StreamPreviewInfo> similarStreamsList = new ArrayList<>(info.related_streams);

View File

@ -36,12 +36,12 @@ import java.util.Vector;
class VideoListAdapter extends BaseAdapter {
private final Context context;
private final VideoInfoItemViewCreator viewCreator;
private final StreamInfoItemViewCreator viewCreator;
private Vector<StreamPreviewInfo> videoList = new Vector<>();
private final ListView listView;
public VideoListAdapter(Activity activity, VideoItemListFragment videoListFragment) {
viewCreator = new VideoInfoItemViewCreator(LayoutInflater.from(activity), activity, null);
viewCreator = new StreamInfoItemViewCreator(LayoutInflater.from(activity), activity, null);
this.listView = videoListFragment.getListView();
this.listView.setDivider(null);
this.listView.setDividerHeight(0);

View File

@ -101,29 +101,16 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
@Override
public String getBannerUrl() throws ParsingException {
String cssContent = "";
try {
Element el = doc.select("div[id=\"gh-banner\"]").first().select("style").first();
cssContent = el.html();
// todo: parse this using a css parser
/*
CSSStyleSheet sheet = cssParser.parseStyleSheet(
new org.w3c.css.sac.InputSource(
new StringReader(cssContent)), null, null);
CSSRuleList rules = sheet.getCssRules();
for (int i = 0; i < rules.getLength(); i++) {
final CSSRule rule = rules.item(i);
System.out.println(rule.getCssText());
}
*/
String cssContent = el.html();
String url = "https:" + Parser.matchGroup1("url\\((.*)\\)", cssContent);
if(url.contains("s.ytimg.com")) {
return null;
} else {
return url;
}
/* } catch(CSSParseException csse) {
throw new ParsingException("Could not parse css: " + cssContent); */
} catch(Exception e) {
throw new ParsingException("Could not get Banner", e);
}