remove video item list plemp
This commit is contained in:
parent
2f2334eac4
commit
d6de11f54c
|
@ -276,7 +276,7 @@ public class ErrorActivity extends AppCompatActivity {
|
||||||
returnActivity.isAssignableFrom(Activity.class)) {
|
returnActivity.isAssignableFrom(Activity.class)) {
|
||||||
intent = new Intent(this, returnActivity);
|
intent = new Intent(this, returnActivity);
|
||||||
} else {
|
} else {
|
||||||
intent = new Intent(this, VideoItemListActivity.class);
|
intent = new Intent(this, MainActivity.class);
|
||||||
}
|
}
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
NavUtils.navigateUpTo(this, intent);
|
NavUtils.navigateUpTo(this, intent);
|
||||||
|
|
|
@ -49,7 +49,7 @@ public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
switch(id) {
|
switch(id) {
|
||||||
case android.R.id.home: {
|
case android.R.id.home: {
|
||||||
Intent intent = new Intent(this, VideoItemListActivity.class);
|
Intent intent = new Intent(this, MainActivity.class);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
NavUtils.navigateUpTo(this, intent);
|
NavUtils.navigateUpTo(this, intent);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1,82 +0,0 @@
|
||||||
package org.schabi.newpipe;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.database.MatrixCursor;
|
|
||||||
import android.support.v4.widget.CursorAdapter;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Madiyar on 23.02.2016.
|
|
||||||
*
|
|
||||||
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
|
||||||
* SuggestionListAdapter.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 SuggestionListAdapter extends CursorAdapter {
|
|
||||||
|
|
||||||
private String[] columns = new String[]{"_id", "title"};
|
|
||||||
|
|
||||||
public SuggestionListAdapter(Context context) {
|
|
||||||
super(context, null, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View newView(Context context, Cursor cursor, ViewGroup parent) {
|
|
||||||
ViewHolder viewHolder;
|
|
||||||
|
|
||||||
View view = LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_1, parent, false);
|
|
||||||
viewHolder = new ViewHolder();
|
|
||||||
viewHolder.suggestionTitle = (TextView) view.findViewById(android.R.id.text1);
|
|
||||||
view.setTag(viewHolder);
|
|
||||||
|
|
||||||
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void bindView(View view, Context context, Cursor cursor) {
|
|
||||||
ViewHolder viewHolder = (ViewHolder) view.getTag();
|
|
||||||
viewHolder.suggestionTitle.setText(cursor.getString(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void updateAdapter(List<String> suggestions) {
|
|
||||||
MatrixCursor cursor = new MatrixCursor(columns);
|
|
||||||
int i = 0;
|
|
||||||
for (String s : suggestions) {
|
|
||||||
String[] temp = new String[2];
|
|
||||||
temp[0] = Integer.toString(i);
|
|
||||||
temp[1] = s;
|
|
||||||
i++;
|
|
||||||
cursor.addRow(temp);
|
|
||||||
}
|
|
||||||
changeCursor(cursor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSuggestion(int position) {
|
|
||||||
return ((Cursor) getItem(position)).getString(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ViewHolder {
|
|
||||||
public TextView suggestionTitle;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -138,7 +138,7 @@ public class VideoItemDetailActivity extends AppCompatActivity {
|
||||||
|
|
||||||
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
|
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
|
||||||
|
|
||||||
Intent intent = new Intent(this, VideoItemListActivity.class);
|
Intent intent = new Intent(this, MainActivity.class);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
NavUtils.navigateUpTo(this, intent);
|
NavUtils.navigateUpTo(this, intent);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -199,11 +199,11 @@ public class VideoItemDetailFragment extends Fragment {
|
||||||
} catch(StreamInfo.StreamExctractException e) {
|
} catch(StreamInfo.StreamExctractException e) {
|
||||||
if(!streamInfo.errors.isEmpty()) {
|
if(!streamInfo.errors.isEmpty()) {
|
||||||
// !!! if this case ever kicks in someone gets kicked out !!!
|
// !!! if this case ever kicks in someone gets kicked out !!!
|
||||||
ErrorActivity.reportError(h, getActivity(), e, VideoItemListActivity.class, null,
|
ErrorActivity.reportError(h, getActivity(), e, VideoItemDetailFragment.class, null,
|
||||||
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
|
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
|
||||||
service.getServiceInfo().name, videoUrl, R.string.could_not_get_stream));
|
service.getServiceInfo().name, videoUrl, R.string.could_not_get_stream));
|
||||||
} else {
|
} else {
|
||||||
ErrorActivity.reportError(h, getActivity(), streamInfo.errors, VideoItemListActivity.class, null,
|
ErrorActivity.reportError(h, getActivity(), streamInfo.errors, VideoItemDetailFragment.class, null,
|
||||||
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
|
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
|
||||||
service.getServiceInfo().name, videoUrl, R.string.could_not_get_stream));
|
service.getServiceInfo().name, videoUrl, R.string.could_not_get_stream));
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,7 @@ public class VideoItemDetailFragment extends Fragment {
|
||||||
});
|
});
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (ParsingException e) {
|
} catch (ParsingException e) {
|
||||||
ErrorActivity.reportError(h, getActivity(), e, VideoItemListActivity.class, null,
|
ErrorActivity.reportError(h, getActivity(), e, VideoItemDetailFragment.class, null,
|
||||||
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
|
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
|
||||||
service.getServiceInfo().name, videoUrl, R.string.parsing_error));
|
service.getServiceInfo().name, videoUrl, R.string.parsing_error));
|
||||||
h.post(new Runnable() {
|
h.post(new Runnable() {
|
||||||
|
@ -226,7 +226,7 @@ public class VideoItemDetailFragment extends Fragment {
|
||||||
});
|
});
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
ErrorActivity.reportError(h, getActivity(), e, VideoItemListActivity.class, null,
|
ErrorActivity.reportError(h, getActivity(), e, VideoItemDetailFragment.class, null,
|
||||||
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
|
ErrorActivity.ErrorInfo.make(ErrorActivity.REQUESTED_STREAM,
|
||||||
service.getServiceInfo().name, videoUrl, R.string.general_error));
|
service.getServiceInfo().name, videoUrl, R.string.general_error));
|
||||||
h.post(new Runnable() {
|
h.post(new Runnable() {
|
||||||
|
|
|
@ -1,411 +0,0 @@
|
||||||
package org.schabi.newpipe;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.media.AudioManager;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.support.v4.app.NavUtils;
|
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.support.v7.widget.SearchView;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.inputmethod.InputMethodManager;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.download.MainActivity;
|
|
||||||
import org.schabi.newpipe.extractor.ExtractionException;
|
|
||||||
import org.schabi.newpipe.extractor.SearchEngine;
|
|
||||||
import org.schabi.newpipe.extractor.ServiceList;
|
|
||||||
import org.schabi.newpipe.extractor.StreamingService;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
|
||||||
* VideoItemListActivity.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 VideoItemListActivity extends AppCompatActivity
|
|
||||||
implements VideoItemListFragment.Callbacks {
|
|
||||||
|
|
||||||
private static final String TAG = VideoItemListFragment.class.toString();
|
|
||||||
|
|
||||||
// arguments to give to this activity
|
|
||||||
public static final String VIDEO_INFO_ITEMS = "video_info_items";
|
|
||||||
|
|
||||||
// savedInstanceBundle arguments
|
|
||||||
private static final String QUERY = "query";
|
|
||||||
private static final String STREAMING_SERVICE = "streaming_service";
|
|
||||||
|
|
||||||
// activity modes
|
|
||||||
private static final int SEARCH_MODE = 0;
|
|
||||||
private static final int PRESENT_VIDEOS_MODE = 1;
|
|
||||||
|
|
||||||
private int mode;
|
|
||||||
private int currentStreamingServiceId = -1;
|
|
||||||
private String searchQuery = "";
|
|
||||||
|
|
||||||
private VideoItemListFragment listFragment;
|
|
||||||
private VideoItemDetailFragment videoFragment;
|
|
||||||
private Menu menu;
|
|
||||||
|
|
||||||
private SuggestionListAdapter suggestionListAdapter;
|
|
||||||
private SuggestionSearchRunnable suggestionSearchRunnable;
|
|
||||||
private Thread searchThread;
|
|
||||||
|
|
||||||
private class SearchVideoQueryListener implements SearchView.OnQueryTextListener {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onQueryTextSubmit(String query) {
|
|
||||||
try {
|
|
||||||
searchQuery = query;
|
|
||||||
listFragment.search(query);
|
|
||||||
|
|
||||||
// hide virtual keyboard
|
|
||||||
InputMethodManager inputManager =
|
|
||||||
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
|
||||||
try {
|
|
||||||
//noinspection ConstantConditions
|
|
||||||
inputManager.hideSoftInputFromWindow(
|
|
||||||
getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
|
|
||||||
} catch(NullPointerException e) {
|
|
||||||
Log.e(TAG, "Could not get widget with focus");
|
|
||||||
Toast.makeText(VideoItemListActivity.this, "Could not get widget with focus",
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
// clear focus
|
|
||||||
// 1. to not open up the keyboard after switching back to this
|
|
||||||
// 2. It's a workaround to a seeming bug by the Android OS it self, causing
|
|
||||||
// onQueryTextSubmit to trigger twice when focus is not cleared.
|
|
||||||
// See: http://stackoverflow.com/questions/17874951/searchview-onquerytextsubmit-runs-twice-while-i-pressed-once
|
|
||||||
getCurrentFocus().clearFocus();
|
|
||||||
} catch(Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
View bg = findViewById(R.id.mainBG);
|
|
||||||
bg.setVisibility(View.GONE);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onQueryTextChange(String newText) {
|
|
||||||
if(!newText.isEmpty()) {
|
|
||||||
searchSuggestions(newText);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
private class SearchSuggestionListener implements SearchView.OnSuggestionListener{
|
|
||||||
|
|
||||||
private SearchView searchView;
|
|
||||||
|
|
||||||
private SearchSuggestionListener(SearchView searchView) {
|
|
||||||
this.searchView = searchView;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onSuggestionSelect(int position) {
|
|
||||||
String suggestion = suggestionListAdapter.getSuggestion(position);
|
|
||||||
searchView.setQuery(suggestion,true);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onSuggestionClick(int position) {
|
|
||||||
String suggestion = suggestionListAdapter.getSuggestion(position);
|
|
||||||
searchView.setQuery(suggestion,true);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SuggestionResultRunnable implements Runnable{
|
|
||||||
|
|
||||||
private List<String> suggestions;
|
|
||||||
|
|
||||||
private SuggestionResultRunnable(List<String> suggestions) {
|
|
||||||
this.suggestions = suggestions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
suggestionListAdapter.updateAdapter(suggestions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SuggestionSearchRunnable implements Runnable{
|
|
||||||
private final int serviceId;
|
|
||||||
private final String query;
|
|
||||||
final Handler h = new Handler();
|
|
||||||
private Context context;
|
|
||||||
private SuggestionSearchRunnable(int serviceId, String query) {
|
|
||||||
this.serviceId = serviceId;
|
|
||||||
this.query = query;
|
|
||||||
context = VideoItemListActivity.this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
SearchEngine engine =
|
|
||||||
ServiceList.getService(serviceId).getSearchEngineInstance(new Downloader());
|
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
|
||||||
String searchLanguageKey = context.getString(R.string.search_language_key);
|
|
||||||
String searchLanguage = sp.getString(searchLanguageKey,
|
|
||||||
getString(R.string.default_language_value));
|
|
||||||
List<String> suggestions = engine.suggestionList(query,searchLanguage,new Downloader());
|
|
||||||
h.post(new SuggestionResultRunnable(suggestions));
|
|
||||||
} catch (ExtractionException e) {
|
|
||||||
ErrorActivity.reportError(h, VideoItemListActivity.this, e, null, findViewById(R.id.videoitem_list),
|
|
||||||
ErrorActivity.ErrorInfo.make(ErrorActivity.SEARCHED,
|
|
||||||
ServiceList.getNameOfService(serviceId), query, R.string.parsing_error));
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
postNewErrorToast(h, R.string.network_error);
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (Exception e) {
|
|
||||||
ErrorActivity.reportError(h, VideoItemListActivity.this, e, null, findViewById(R.id.videoitem_list),
|
|
||||||
ErrorActivity.ErrorInfo.make(ErrorActivity.SEARCHED,
|
|
||||||
ServiceList.getNameOfService(serviceId), query, R.string.general_error));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
|
|
||||||
* device.
|
|
||||||
*/
|
|
||||||
private boolean mTwoPane;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_videoitem_list);
|
|
||||||
StreamingService streamingService = null;
|
|
||||||
|
|
||||||
View bg = findViewById(R.id.mainBG);
|
|
||||||
bg.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
try {
|
|
||||||
//------ todo: remove this line when multiservice support is implemented ------
|
|
||||||
currentStreamingServiceId = ServiceList.getIdOfService("Youtube");
|
|
||||||
streamingService = ServiceList.getService(currentStreamingServiceId);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
ErrorActivity.reportError(VideoItemListActivity.this, e, null, findViewById(R.id.videoitem_list),
|
|
||||||
ErrorActivity.ErrorInfo.make(ErrorActivity.SEARCHED,
|
|
||||||
ServiceList.getNameOfService(currentStreamingServiceId), "", R.string.general_error));
|
|
||||||
}
|
|
||||||
setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
|
||||||
listFragment = (VideoItemListFragment) getSupportFragmentManager()
|
|
||||||
.findFragmentById(R.id.videoitem_list);
|
|
||||||
listFragment.setStreamingService(streamingService);
|
|
||||||
|
|
||||||
if(savedInstanceState != null
|
|
||||||
&& mode != PRESENT_VIDEOS_MODE) {
|
|
||||||
searchQuery = savedInstanceState.getString(QUERY);
|
|
||||||
currentStreamingServiceId = savedInstanceState.getInt(STREAMING_SERVICE);
|
|
||||||
if(!searchQuery.isEmpty()) {
|
|
||||||
listFragment.search(searchQuery);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (findViewById(R.id.videoitem_detail_container) != null) {
|
|
||||||
// The detail container view will be present only in the
|
|
||||||
// large-screen layouts (res/values-large and
|
|
||||||
// res/values-sw600dp). If this view is present, then the
|
|
||||||
// activity should be in two-pane mode.
|
|
||||||
mTwoPane = true;
|
|
||||||
|
|
||||||
// In two-pane mode, list items should be given the
|
|
||||||
// 'activated' state when touched.
|
|
||||||
|
|
||||||
((VideoItemListFragment) getSupportFragmentManager()
|
|
||||||
.findFragmentById(R.id.videoitem_list))
|
|
||||||
.setActivateOnItemClick(true);
|
|
||||||
|
|
||||||
SearchView searchView = (SearchView)findViewById(R.id.searchViewTablet);
|
|
||||||
if(mode != PRESENT_VIDEOS_MODE) {
|
|
||||||
// Somehow the seticonifiedbydefault property set by the layout xml is not working on
|
|
||||||
// the support version on SearchView, so it needs to be set programmatically.
|
|
||||||
searchView.setIconifiedByDefault(false);
|
|
||||||
searchView.setIconified(false);
|
|
||||||
if(!searchQuery.isEmpty()) {
|
|
||||||
searchView.setQuery(searchQuery,false);
|
|
||||||
}
|
|
||||||
searchView.setOnQueryTextListener(new SearchVideoQueryListener());
|
|
||||||
suggestionListAdapter = new SuggestionListAdapter(this);
|
|
||||||
searchView.setSuggestionsAdapter(suggestionListAdapter);
|
|
||||||
searchView.setOnSuggestionListener(new SearchSuggestionListener(searchView));
|
|
||||||
} else {
|
|
||||||
searchView.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PreferenceManager.setDefaultValues(this, R.xml.settings, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
App.checkStartTor(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback method from {@link VideoItemListFragment.Callbacks}
|
|
||||||
* indicating that the item with the given ID was selected.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onItemSelected(String id) {
|
|
||||||
VideoListAdapter listAdapter = (VideoListAdapter) ((VideoItemListFragment)
|
|
||||||
getSupportFragmentManager()
|
|
||||||
.findFragmentById(R.id.videoitem_list))
|
|
||||||
.getListAdapter();
|
|
||||||
String webpageUrl = listAdapter.getVideoList().get((int) Long.parseLong(id)).webpage_url;
|
|
||||||
if (mTwoPane) {
|
|
||||||
// In two-pane mode, show the detail view in this activity by
|
|
||||||
// adding or replacing the detail fragment using a
|
|
||||||
// fragment transaction.
|
|
||||||
Bundle arguments = new Bundle();
|
|
||||||
//arguments.putString(VideoItemDetailFragment.ARG_ITEM_ID, id);
|
|
||||||
arguments.putString(VideoItemDetailFragment.VIDEO_URL, webpageUrl);
|
|
||||||
arguments.putInt(VideoItemDetailFragment.STREAMING_SERVICE, currentStreamingServiceId);
|
|
||||||
videoFragment = new VideoItemDetailFragment();
|
|
||||||
videoFragment.setArguments(arguments);
|
|
||||||
videoFragment.setOnInvokeCreateOptionsMenuListener(new VideoItemDetailFragment.OnInvokeCreateOptionsMenuListener() {
|
|
||||||
@Override
|
|
||||||
public void createOptionsMenu() {
|
|
||||||
menu.clear();
|
|
||||||
onCreateOptionsMenu(menu);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
getSupportFragmentManager().beginTransaction()
|
|
||||||
.replace(R.id.videoitem_detail_container, videoFragment)
|
|
||||||
.commit();
|
|
||||||
} else {
|
|
||||||
// In single-pane mode, simply start the detail activity
|
|
||||||
// for the selected item ID.
|
|
||||||
Intent detailIntent = new Intent(this, VideoItemDetailActivity.class);
|
|
||||||
//detailIntent.putExtra(VideoItemDetailFragment.ARG_ITEM_ID, id);
|
|
||||||
detailIntent.putExtra(VideoItemDetailFragment.VIDEO_URL, webpageUrl);
|
|
||||||
detailIntent.putExtra(VideoItemDetailFragment.STREAMING_SERVICE, currentStreamingServiceId);
|
|
||||||
startActivity(detailIntent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
super.onCreateOptionsMenu(menu);
|
|
||||||
this.menu = menu;
|
|
||||||
MenuInflater inflater = getMenuInflater();
|
|
||||||
if(mode != PRESENT_VIDEOS_MODE &&
|
|
||||||
findViewById(R.id.videoitem_detail_container) == null) {
|
|
||||||
inflater.inflate(R.menu.videoitem_list, menu);
|
|
||||||
MenuItem searchItem = menu.findItem(R.id.action_search);
|
|
||||||
SearchView searchView = (SearchView) searchItem.getActionView();
|
|
||||||
searchView.setFocusable(false);
|
|
||||||
searchView.setOnQueryTextListener(
|
|
||||||
new SearchVideoQueryListener());
|
|
||||||
suggestionListAdapter = new SuggestionListAdapter(this);
|
|
||||||
searchView.setSuggestionsAdapter(suggestionListAdapter);
|
|
||||||
searchView.setOnSuggestionListener(new SearchSuggestionListener(searchView));
|
|
||||||
if(!searchQuery.isEmpty()) {
|
|
||||||
searchView.setQuery(searchQuery,false);
|
|
||||||
searchView.setIconifiedByDefault(false);
|
|
||||||
}
|
|
||||||
} else if (videoFragment != null){
|
|
||||||
videoFragment.onCreateOptionsMenu(menu, inflater);
|
|
||||||
} else {
|
|
||||||
inflater.inflate(R.menu.videoitem_two_pannel, menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
int id = item.getItemId();
|
|
||||||
|
|
||||||
switch(id) {
|
|
||||||
case android.R.id.home: {
|
|
||||||
Intent intent = new Intent(this, VideoItemListActivity.class);
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
|
||||||
NavUtils.navigateUpTo(this, intent);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case R.id.action_settings: {
|
|
||||||
Intent intent = new Intent(this, SettingsActivity.class);
|
|
||||||
startActivity(intent);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case R.id.action_report_error: {
|
|
||||||
ErrorActivity.reportError(VideoItemListActivity.this, new Vector<Throwable>(),
|
|
||||||
null, null,
|
|
||||||
ErrorActivity.ErrorInfo.make(ErrorActivity.USER_REPORT,
|
|
||||||
ServiceList.getNameOfService(currentStreamingServiceId),
|
|
||||||
"user_report", R.string.user_report));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case R.id.action_show_downloads: {
|
|
||||||
Intent intent = new Intent(this, org.schabi.newpipe.download.MainActivity.class);
|
|
||||||
startActivity(intent);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return videoFragment.onOptionsItemSelected(item) ||
|
|
||||||
super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
/*
|
|
||||||
if (mActivatedPosition != ListView.INVALID_POSITION) {
|
|
||||||
// Serialize and persist the activated item position.
|
|
||||||
outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
outState.putString(QUERY, searchQuery);
|
|
||||||
outState.putInt(STREAMING_SERVICE, currentStreamingServiceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void searchSuggestions(String query) {
|
|
||||||
suggestionSearchRunnable =
|
|
||||||
new SuggestionSearchRunnable(currentStreamingServiceId, query);
|
|
||||||
searchThread = new Thread(suggestionSearchRunnable);
|
|
||||||
searchThread.start();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void postNewErrorToast(Handler h, final int stringResource) {
|
|
||||||
h.post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Toast.makeText(VideoItemListActivity.this, getString(stringResource),
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,371 +0,0 @@
|
||||||
package org.schabi.newpipe;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.support.v4.app.ListFragment;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.AbsListView;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.extractor.ExtractionException;
|
|
||||||
import org.schabi.newpipe.extractor.SearchResult;
|
|
||||||
import org.schabi.newpipe.extractor.StreamPreviewInfo;
|
|
||||||
import org.schabi.newpipe.extractor.SearchEngine;
|
|
||||||
import org.schabi.newpipe.extractor.StreamingService;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
|
||||||
* VideoItemListFragment.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 VideoItemListFragment extends ListFragment {
|
|
||||||
|
|
||||||
private static final String TAG = VideoItemListFragment.class.toString();
|
|
||||||
|
|
||||||
private StreamingService streamingService;
|
|
||||||
private VideoListAdapter videoListAdapter;
|
|
||||||
|
|
||||||
// activity modes
|
|
||||||
private static final int SEARCH_MODE = 0;
|
|
||||||
private static final int PRESENT_VIDEOS_MODE = 1;
|
|
||||||
|
|
||||||
private int mode;
|
|
||||||
private String query = "";
|
|
||||||
private int lastPage;
|
|
||||||
|
|
||||||
private Thread searchThread;
|
|
||||||
private SearchRunnable searchRunnable;
|
|
||||||
// used to track down if results posted by threads ar still valid
|
|
||||||
private int currentRequestId = -1;
|
|
||||||
private ListView list;
|
|
||||||
|
|
||||||
private View footer;
|
|
||||||
|
|
||||||
// used to suppress request for loading a new page while another page is already loading.
|
|
||||||
private boolean loadingNextPage = true;
|
|
||||||
|
|
||||||
private class ResultRunnable implements Runnable {
|
|
||||||
private final SearchResult result;
|
|
||||||
private final int requestId;
|
|
||||||
public ResultRunnable(SearchResult result, int requestId) {
|
|
||||||
this.result = result;
|
|
||||||
this.requestId = requestId;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
updateListOnResult(result, requestId);
|
|
||||||
if (android.os.Build.VERSION.SDK_INT >= 19) {
|
|
||||||
getListView().removeFooterView(footer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SearchRunnable implements Runnable {
|
|
||||||
public static final String YOUTUBE = "Youtube";
|
|
||||||
private final SearchEngine engine;
|
|
||||||
private final String query;
|
|
||||||
private final int page;
|
|
||||||
final Handler h = new Handler();
|
|
||||||
private volatile boolean runs = true;
|
|
||||||
private final int requestId;
|
|
||||||
public SearchRunnable(SearchEngine engine, String query, int page, int requestId) {
|
|
||||||
this.engine = engine;
|
|
||||||
this.query = query;
|
|
||||||
this.page = page;
|
|
||||||
this.requestId = requestId;
|
|
||||||
}
|
|
||||||
void terminate() {
|
|
||||||
runs = false;
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
SearchResult result = null;
|
|
||||||
try {
|
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
|
|
||||||
String searchLanguageKey = getContext().getString(R.string.search_language_key);
|
|
||||||
String searchLanguage = sp.getString(searchLanguageKey,
|
|
||||||
getString(R.string.default_language_value));
|
|
||||||
result = SearchResult
|
|
||||||
.getSearchResult(engine, query, page, searchLanguage, new Downloader());
|
|
||||||
|
|
||||||
if(runs) {
|
|
||||||
h.post(new ResultRunnable(result, requestId));
|
|
||||||
}
|
|
||||||
|
|
||||||
// look for errors during extraction
|
|
||||||
// soft errors:
|
|
||||||
if(result != null &&
|
|
||||||
!result.errors.isEmpty()) {
|
|
||||||
Log.e(TAG, "OCCURRED ERRORS DURING SEARCH EXTRACTION:");
|
|
||||||
for(Throwable e : result.errors) {
|
|
||||||
e.printStackTrace();
|
|
||||||
Log.e(TAG, "------");
|
|
||||||
}
|
|
||||||
|
|
||||||
Activity a = getActivity();
|
|
||||||
View rootView = a.findViewById(R.id.videoitem_list);
|
|
||||||
ErrorActivity.reportError(h, getActivity(), result.errors, null, rootView,
|
|
||||||
ErrorActivity.ErrorInfo.make(ErrorActivity.SEARCHED,
|
|
||||||
/* todo: this shoudl not be assigned static */ YOUTUBE, query, R.string.light_parsing_error));
|
|
||||||
|
|
||||||
}
|
|
||||||
// hard errors:
|
|
||||||
} catch(IOException e) {
|
|
||||||
postNewNothingFoundToast(h, R.string.network_error);
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch(SearchEngine.NothingFoundException e) {
|
|
||||||
postNewErrorToast(h, e.getMessage());
|
|
||||||
} catch(ExtractionException e) {
|
|
||||||
ErrorActivity.reportError(h, getActivity(), e, null, null,
|
|
||||||
ErrorActivity.ErrorInfo.make(ErrorActivity.SEARCHED,
|
|
||||||
/* todo: this shoudl not be assigned static */
|
|
||||||
YOUTUBE, query, R.string.parsing_error));
|
|
||||||
//postNewErrorToast(h, R.string.parsing_error);
|
|
||||||
e.printStackTrace();
|
|
||||||
|
|
||||||
} catch(Exception e) {
|
|
||||||
ErrorActivity.reportError(h, getActivity(), e, null, null,
|
|
||||||
ErrorActivity.ErrorInfo.make(ErrorActivity.SEARCHED,
|
|
||||||
/* todo: this shoudl not be assigned static */ YOUTUBE, query, R.string.general_error));
|
|
||||||
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void present(List<StreamPreviewInfo> videoList) {
|
|
||||||
mode = PRESENT_VIDEOS_MODE;
|
|
||||||
setListShown(true);
|
|
||||||
getListView().smoothScrollToPosition(0);
|
|
||||||
|
|
||||||
updateList(videoList);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void search(String query) {
|
|
||||||
mode = SEARCH_MODE;
|
|
||||||
this.query = query;
|
|
||||||
this.lastPage = 1;
|
|
||||||
videoListAdapter.clearVideoList();
|
|
||||||
setListShown(false);
|
|
||||||
startSearch(query, lastPage);
|
|
||||||
//todo: Somehow this command is not working on older devices,
|
|
||||||
// although it was introduced with API level 8. Test this and find a solution.
|
|
||||||
getListView().smoothScrollToPosition(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void nextPage() {
|
|
||||||
loadingNextPage = true;
|
|
||||||
lastPage++;
|
|
||||||
Log.d(TAG, getString(R.string.search_page) + Integer.toString(lastPage));
|
|
||||||
startSearch(query, lastPage);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startSearch(String query, int page) {
|
|
||||||
currentRequestId++;
|
|
||||||
terminateThreads();
|
|
||||||
searchRunnable = new SearchRunnable(streamingService.getSearchEngineInstance(new Downloader()),
|
|
||||||
query, page, currentRequestId);
|
|
||||||
searchThread = new Thread(searchRunnable);
|
|
||||||
searchThread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStreamingService(StreamingService streamingService) {
|
|
||||||
this.streamingService = streamingService;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateListOnResult(SearchResult result, int requestId) {
|
|
||||||
if(requestId == currentRequestId) {
|
|
||||||
setListShown(true);
|
|
||||||
updateList(result.resultList);
|
|
||||||
if(!result.suggestion.isEmpty()) {
|
|
||||||
|
|
||||||
Toast.makeText(getActivity(),
|
|
||||||
String.format(getActivity().getString(R.string.did_you_mean), result.suggestion),
|
|
||||||
Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateList(List<StreamPreviewInfo> list) {
|
|
||||||
try {
|
|
||||||
videoListAdapter.addVideoList(list);
|
|
||||||
terminateThreads();
|
|
||||||
} catch(java.lang.IllegalStateException e) {
|
|
||||||
Toast.makeText(getActivity(), "Trying to set value while activity doesn't exist anymore.",
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
Log.w(TAG, "Trying to set value while activity doesn't exist anymore.");
|
|
||||||
} catch(Exception e) {
|
|
||||||
Toast.makeText(getActivity(), getString(R.string.general_error),
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
loadingNextPage = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void terminateThreads() {
|
|
||||||
if(searchThread != null) {
|
|
||||||
searchRunnable.terminate();
|
|
||||||
// No need to join, since we don't really terminate the thread. We just demand
|
|
||||||
// it to post its result runnable into the gui main loop.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The serialization (saved instance state) Bundle key representing the
|
|
||||||
* activated item position. Only used on tablets.
|
|
||||||
*/
|
|
||||||
private static final String STATE_ACTIVATED_POSITION = "activated_position";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The current activated item position. Only used on tablets.
|
|
||||||
*/
|
|
||||||
private int mActivatedPosition = ListView.INVALID_POSITION;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A callback interface that all activities containing this fragment must
|
|
||||||
* implement. This mechanism allows activities to be notified of item
|
|
||||||
* selections.
|
|
||||||
*/
|
|
||||||
public interface Callbacks {
|
|
||||||
/**
|
|
||||||
* Callback for when an item has been selected.
|
|
||||||
*/
|
|
||||||
void onItemSelected(String id);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Callbacks mCallbacks;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
|
||||||
super.onViewCreated(view, savedInstanceState);
|
|
||||||
list = getListView();
|
|
||||||
videoListAdapter = new VideoListAdapter(getActivity(), this);
|
|
||||||
footer = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE))
|
|
||||||
.inflate(R.layout.paginate_footer, null, false);
|
|
||||||
|
|
||||||
|
|
||||||
setListAdapter(videoListAdapter);
|
|
||||||
|
|
||||||
// Restore the previously serialized activated item position.
|
|
||||||
if (savedInstanceState != null
|
|
||||||
|
|
||||||
&& savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
|
|
||||||
setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
getListView().setOnScrollListener(new AbsListView.OnScrollListener() {
|
|
||||||
long lastScrollDate;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onScrollStateChanged(AbsListView view, int scrollState) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onScroll(AbsListView view, int firstVisibleItem,
|
|
||||||
int visibleItemCount, int totalItemCount) {
|
|
||||||
if (mode != PRESENT_VIDEOS_MODE
|
|
||||||
&& list.getChildAt(0) != null
|
|
||||||
&& list.getLastVisiblePosition() == list.getAdapter().getCount() - 1
|
|
||||||
&& list.getChildAt(list.getChildCount() - 1).getBottom() >= list.getHeight()) {
|
|
||||||
long time = System.currentTimeMillis();
|
|
||||||
if ((time - lastScrollDate) > 200
|
|
||||||
&& !loadingNextPage) {
|
|
||||||
lastScrollDate = time;
|
|
||||||
getListView().addFooterView(footer);
|
|
||||||
nextPage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttach(Context context) {
|
|
||||||
super.onAttach(context);
|
|
||||||
|
|
||||||
// Activities containing this fragment must implement its callbacks.
|
|
||||||
if (!(context instanceof Callbacks)) {
|
|
||||||
throw new IllegalStateException("Activity must implement fragment's callbacks.");
|
|
||||||
}
|
|
||||||
|
|
||||||
mCallbacks = (Callbacks) context;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onListItemClick(ListView listView, View view, int position, long id) {
|
|
||||||
super.onListItemClick(listView, view, position, id);
|
|
||||||
setActivatedPosition(position);
|
|
||||||
mCallbacks.onItemSelected(Long.toString(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Turns on activate-on-click mode. When this mode is on, list items will be
|
|
||||||
* given the 'activated' state when touched.
|
|
||||||
*/
|
|
||||||
public void setActivateOnItemClick(@SuppressWarnings("SameParameterValue") boolean activateOnItemClick) {
|
|
||||||
// When setting CHOICE_MODE_SINGLE, ListView will automatically
|
|
||||||
// give items the 'activated' state when touched.
|
|
||||||
getListView().setChoiceMode(activateOnItemClick
|
|
||||||
? ListView.CHOICE_MODE_SINGLE
|
|
||||||
: ListView.CHOICE_MODE_NONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setActivatedPosition(int position) {
|
|
||||||
if (position == ListView.INVALID_POSITION) {
|
|
||||||
getListView().setItemChecked(mActivatedPosition, false);
|
|
||||||
} else {
|
|
||||||
getListView().setItemChecked(position, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
mActivatedPosition = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void postNewErrorToast(Handler h, final String message) {
|
|
||||||
h.post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
setListShown(true);
|
|
||||||
Toast.makeText(getActivity(), message,
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void postNewNothingFoundToast(Handler h, final int stringResource) {
|
|
||||||
h.post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
setListShown(true);
|
|
||||||
Toast.makeText(getActivity(), getString(stringResource),
|
|
||||||
Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,92 +0,0 @@
|
||||||
package org.schabi.newpipe;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.support.v4.content.ContextCompat;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.BaseAdapter;
|
|
||||||
import android.widget.ListView;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.extractor.StreamPreviewInfo;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Christian Schabesberger on 11.08.15.
|
|
||||||
*
|
|
||||||
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
|
|
||||||
* VideoListAdapter.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/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class VideoListAdapter extends BaseAdapter {
|
|
||||||
private final Context context;
|
|
||||||
private final StreamInfoItemViewCreator viewCreator;
|
|
||||||
private Vector<StreamPreviewInfo> videoList = new Vector<>();
|
|
||||||
private final ListView listView;
|
|
||||||
|
|
||||||
public VideoListAdapter(Activity activity, VideoItemListFragment videoListFragment) {
|
|
||||||
viewCreator = new StreamInfoItemViewCreator(LayoutInflater.from(activity), activity, null);
|
|
||||||
this.listView = videoListFragment.getListView();
|
|
||||||
this.listView.setDivider(null);
|
|
||||||
this.listView.setDividerHeight(0);
|
|
||||||
this.context = activity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addVideoList(List<StreamPreviewInfo> videos) {
|
|
||||||
videoList.addAll(videos);
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearVideoList() {
|
|
||||||
videoList = new Vector<>();
|
|
||||||
notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector<StreamPreviewInfo> getVideoList() {
|
|
||||||
return videoList;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCount() {
|
|
||||||
return videoList.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getItem(int position) {
|
|
||||||
return videoList.get(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getItemId(int position) {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
|
||||||
convertView = viewCreator.getViewFromVideoInfoItem(convertView, parent, videoList.get(position));
|
|
||||||
|
|
||||||
if(listView.isItemChecked(position)) {
|
|
||||||
convertView.setBackgroundColor(ContextCompat.getColor(context,R.color.light_youtube_primary_color));
|
|
||||||
} else {
|
|
||||||
convertView.setBackgroundColor(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return convertView;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -23,25 +23,16 @@ import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewTreeObserver;
|
import android.view.ViewTreeObserver;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.SeekBar;
|
import android.widget.SeekBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import android.support.v7.widget.SearchView;
|
|
||||||
|
|
||||||
import org.schabi.newpipe.ErrorActivity;
|
import org.schabi.newpipe.ErrorActivity;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.SettingsActivity;
|
import org.schabi.newpipe.SettingsActivity;
|
||||||
import org.schabi.newpipe.VideoItemDetailActivity;
|
|
||||||
import org.schabi.newpipe.VideoItemListActivity;
|
|
||||||
import org.schabi.newpipe.extractor.ServiceList;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import us.shandian.giga.get.DownloadManager;
|
import us.shandian.giga.get.DownloadManager;
|
||||||
|
@ -257,7 +248,7 @@ public class MainActivity extends AppCompatActivity implements AdapterView.OnIte
|
||||||
|
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case android.R.id.home: {
|
case android.R.id.home: {
|
||||||
Intent intent = new Intent(this, VideoItemListActivity.class);
|
Intent intent = new Intent(this, org.schabi.newpipe.MainActivity.class);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
NavUtils.navigateUpTo(this, intent);
|
NavUtils.navigateUpTo(this, intent);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -2,10 +2,9 @@ package org.schabi.newpipe.search_fragment;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v7.widget.GridLayoutManager;
|
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.support.v7.widget.SearchView;
|
import android.support.v7.widget.SearchView;
|
||||||
|
@ -16,10 +15,13 @@ import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.schabi.newpipe.ErrorActivity;
|
import org.schabi.newpipe.ErrorActivity;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
|
import org.schabi.newpipe.VideoItemDetailActivity;
|
||||||
|
import org.schabi.newpipe.VideoItemDetailFragment;
|
||||||
import org.schabi.newpipe.extractor.SearchResult;
|
import org.schabi.newpipe.extractor.SearchResult;
|
||||||
import org.schabi.newpipe.extractor.ServiceList;
|
import org.schabi.newpipe.extractor.ServiceList;
|
||||||
|
|
||||||
|
@ -78,17 +80,16 @@ public class SearchInfoItemFragment extends Fragment {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Customize parameter argument names
|
|
||||||
private static final String ARG_COLUMN_COUNT = "column-count";
|
|
||||||
// TODO: Customize parameters
|
|
||||||
private int mColumnCount = 1;
|
|
||||||
|
|
||||||
private int streamingServiceId = -1;
|
private int streamingServiceId = -1;
|
||||||
private String searchQuery = "";
|
private String searchQuery = "";
|
||||||
|
private boolean isLoading = false;
|
||||||
|
|
||||||
private SearchView searchView = null;
|
private SearchView searchView = null;
|
||||||
|
private int pageNumber = 0;
|
||||||
private SuggestionListAdapter suggestionListAdapter = null;
|
private SuggestionListAdapter suggestionListAdapter = null;
|
||||||
private StreamInfoListAdapter streamInfoListAdapter = null;
|
private StreamInfoListAdapter streamInfoListAdapter = null;
|
||||||
|
private LinearLayoutManager streamInfoListLayoutManager = null;
|
||||||
|
private RecyclerView recyclerView = null;
|
||||||
|
|
||||||
// savedInstanceBundle arguments
|
// savedInstanceBundle arguments
|
||||||
private static final String QUERY = "query";
|
private static final String QUERY = "query";
|
||||||
|
@ -105,9 +106,6 @@ public class SearchInfoItemFragment extends Fragment {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static SearchInfoItemFragment newInstance(int columnCount) {
|
public static SearchInfoItemFragment newInstance(int columnCount) {
|
||||||
SearchInfoItemFragment fragment = new SearchInfoItemFragment();
|
SearchInfoItemFragment fragment = new SearchInfoItemFragment();
|
||||||
Bundle args = new Bundle();
|
|
||||||
args.putInt(ARG_COLUMN_COUNT, columnCount);
|
|
||||||
fragment.setArguments(args);
|
|
||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,10 +113,6 @@ public class SearchInfoItemFragment extends Fragment {
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
if (getArguments() != null) {
|
|
||||||
mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(savedInstanceState != null) {
|
if(savedInstanceState != null) {
|
||||||
searchQuery = savedInstanceState.getString(QUERY);
|
searchQuery = savedInstanceState.getString(QUERY);
|
||||||
streamingServiceId = savedInstanceState.getInt(STREAMING_SERVICE);
|
streamingServiceId = savedInstanceState.getInt(STREAMING_SERVICE);
|
||||||
|
@ -140,6 +134,7 @@ public class SearchInfoItemFragment extends Fragment {
|
||||||
@Override
|
@Override
|
||||||
public void onResult(SearchResult result) {
|
public void onResult(SearchResult result) {
|
||||||
streamInfoListAdapter.addVideoList(result.resultList);
|
streamInfoListAdapter.addVideoList(result.resultList);
|
||||||
|
isLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -147,6 +142,7 @@ public class SearchInfoItemFragment extends Fragment {
|
||||||
//setListShown(true);
|
//setListShown(true);
|
||||||
Toast.makeText(getActivity(), getString(stringResource),
|
Toast.makeText(getActivity(), getString(stringResource),
|
||||||
Toast.LENGTH_SHORT).show();
|
Toast.LENGTH_SHORT).show();
|
||||||
|
isLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -154,6 +150,7 @@ public class SearchInfoItemFragment extends Fragment {
|
||||||
//setListShown(true);
|
//setListShown(true);
|
||||||
Toast.makeText(getActivity(), message,
|
Toast.makeText(getActivity(), message,
|
||||||
Toast.LENGTH_LONG).show();
|
Toast.LENGTH_LONG).show();
|
||||||
|
isLoading = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -166,16 +163,43 @@ public class SearchInfoItemFragment extends Fragment {
|
||||||
// Set the adapter
|
// Set the adapter
|
||||||
if (view instanceof RecyclerView) {
|
if (view instanceof RecyclerView) {
|
||||||
Context context = view.getContext();
|
Context context = view.getContext();
|
||||||
RecyclerView recyclerView = (RecyclerView) view;
|
recyclerView = (RecyclerView) view;
|
||||||
if (mColumnCount <= 1) {
|
streamInfoListLayoutManager = new LinearLayoutManager(context);
|
||||||
recyclerView.setLayoutManager(new LinearLayoutManager(context));
|
recyclerView.setLayoutManager(streamInfoListLayoutManager);
|
||||||
} else {
|
|
||||||
recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
|
|
||||||
}
|
|
||||||
|
|
||||||
streamInfoListAdapter = new StreamInfoListAdapter(getActivity(),
|
streamInfoListAdapter = new StreamInfoListAdapter(getActivity(),
|
||||||
getActivity().findViewById(android.R.id.content));
|
getActivity().findViewById(android.R.id.content));
|
||||||
|
streamInfoListAdapter.setOnItemSelectedListener(new StreamInfoListAdapter.OnItemSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public void selected(String url) {
|
||||||
|
Intent i = new Intent(getActivity(), VideoItemDetailActivity.class);
|
||||||
|
i.putExtra(VideoItemDetailFragment.STREAMING_SERVICE, streamingServiceId);
|
||||||
|
i.putExtra(VideoItemDetailFragment.VIDEO_URL, url);
|
||||||
|
getActivity().startActivity(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
recyclerView.setAdapter(streamInfoListAdapter);
|
recyclerView.setAdapter(streamInfoListAdapter);
|
||||||
|
|
||||||
|
|
||||||
|
recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||||
|
@Override
|
||||||
|
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
||||||
|
int pastVisiblesItems, visibleItemCount, totalItemCount;
|
||||||
|
super.onScrolled(recyclerView, dx, dy);
|
||||||
|
if(dy > 0) //check for scroll down
|
||||||
|
{
|
||||||
|
visibleItemCount = streamInfoListLayoutManager.getChildCount();
|
||||||
|
totalItemCount = streamInfoListLayoutManager.getItemCount();
|
||||||
|
pastVisiblesItems = streamInfoListLayoutManager.findFirstVisibleItemPosition();
|
||||||
|
|
||||||
|
if ( (visibleItemCount + pastVisiblesItems) >= totalItemCount && !isLoading)
|
||||||
|
{
|
||||||
|
pageNumber++;
|
||||||
|
search(searchQuery, pageNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
|
@ -219,10 +243,12 @@ public class SearchInfoItemFragment extends Fragment {
|
||||||
|
|
||||||
private void search(String query) {
|
private void search(String query) {
|
||||||
streamInfoListAdapter.clearVideoList();
|
streamInfoListAdapter.clearVideoList();
|
||||||
search(query, 0);
|
pageNumber = 0;
|
||||||
|
search(query, pageNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void search(String query, int page) {
|
private void search(String query, int page) {
|
||||||
|
isLoading = true;
|
||||||
SearchWorker sw = SearchWorker.getInstance();
|
SearchWorker sw = SearchWorker.getInstance();
|
||||||
sw.search(streamingServiceId, query, page, getActivity());
|
sw.search(streamingServiceId, query, page, getActivity());
|
||||||
}
|
}
|
||||||
|
@ -233,22 +259,4 @@ public class SearchInfoItemFragment extends Fragment {
|
||||||
Thread suggestionThread = new Thread(suggestionSearchRunnable);
|
Thread suggestionThread = new Thread(suggestionSearchRunnable);
|
||||||
suggestionThread.start();
|
suggestionThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void postNewErrorToast(Handler h, final int stringResource) {
|
|
||||||
h.post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void postNewNothingFoundToast(Handler h, final int stringResource) {
|
|
||||||
h.post(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,9 +161,8 @@ public class SearchWorker {
|
||||||
public void search(int serviceId, String query, int page, Activity a) {
|
public void search(int serviceId, String query, int page, Activity a) {
|
||||||
if(runnable != null) {
|
if(runnable != null) {
|
||||||
terminate();
|
terminate();
|
||||||
} else {
|
|
||||||
runnable = new SearchRunnable(serviceId, query, page, a, requestId);
|
|
||||||
}
|
}
|
||||||
|
runnable = new SearchRunnable(serviceId, query, page, a, requestId);
|
||||||
Thread thread = new Thread(runnable);
|
Thread thread = new Thread(runnable);
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
package org.schabi.newpipe;
|
package org.schabi.newpipe.search_fragment;
|
||||||
|
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.schabi.newpipe.R;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by the-scrabi on 01.08.16.
|
* Created by the-scrabi on 01.08.16.
|
||||||
*/
|
*/
|
||||||
|
@ -16,6 +18,7 @@ public class StreamInfoItemHolder extends RecyclerView.ViewHolder {
|
||||||
itemDurationView,
|
itemDurationView,
|
||||||
itemUploadDateView,
|
itemUploadDateView,
|
||||||
itemViewCountView;
|
itemViewCountView;
|
||||||
|
public View mainLayout;
|
||||||
|
|
||||||
public StreamInfoItemHolder(View v) {
|
public StreamInfoItemHolder(View v) {
|
||||||
super(v);
|
super(v);
|
||||||
|
@ -25,5 +28,6 @@ public class StreamInfoItemHolder extends RecyclerView.ViewHolder {
|
||||||
itemDurationView = (TextView) v.findViewById(R.id.itemDurationView);
|
itemDurationView = (TextView) v.findViewById(R.id.itemDurationView);
|
||||||
itemUploadDateView = (TextView) v.findViewById(R.id.itemUploadDateView);
|
itemUploadDateView = (TextView) v.findViewById(R.id.itemUploadDateView);
|
||||||
itemViewCountView = (TextView) v.findViewById(R.id.itemViewCountView);
|
itemViewCountView = (TextView) v.findViewById(R.id.itemViewCountView);
|
||||||
|
mainLayout = v.findViewById(R.id.item_main_layout);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
package org.schabi.newpipe.search_fragment;
|
package org.schabi.newpipe.search_fragment;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -12,7 +11,6 @@ import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
|
|
||||||
import org.schabi.newpipe.ImageErrorLoadingListener;
|
import org.schabi.newpipe.ImageErrorLoadingListener;
|
||||||
import org.schabi.newpipe.R;
|
import org.schabi.newpipe.R;
|
||||||
import org.schabi.newpipe.StreamInfoItemHolder;
|
|
||||||
import org.schabi.newpipe.StreamInfoItemViewCreator;
|
import org.schabi.newpipe.StreamInfoItemViewCreator;
|
||||||
import org.schabi.newpipe.extractor.AbstractVideoInfo;
|
import org.schabi.newpipe.extractor.AbstractVideoInfo;
|
||||||
import org.schabi.newpipe.extractor.StreamPreviewInfo;
|
import org.schabi.newpipe.extractor.StreamPreviewInfo;
|
||||||
|
@ -25,18 +23,29 @@ import java.util.Vector;
|
||||||
*/
|
*/
|
||||||
public class StreamInfoListAdapter extends RecyclerView.Adapter<StreamInfoItemHolder> {
|
public class StreamInfoListAdapter extends RecyclerView.Adapter<StreamInfoItemHolder> {
|
||||||
|
|
||||||
|
public interface OnItemSelectedListener {
|
||||||
|
void selected(String url);
|
||||||
|
}
|
||||||
|
|
||||||
private Activity activity = null;
|
private Activity activity = null;
|
||||||
private View rootView = null;
|
private View rootView = null;
|
||||||
private List<StreamPreviewInfo> streamList = new Vector<>();
|
private List<StreamPreviewInfo> streamList = new Vector<>();
|
||||||
private ImageLoader imageLoader = ImageLoader.getInstance();
|
private ImageLoader imageLoader = ImageLoader.getInstance();
|
||||||
private DisplayImageOptions displayImageOptions =
|
private DisplayImageOptions displayImageOptions =
|
||||||
new DisplayImageOptions.Builder().cacheInMemory(true).build();
|
new DisplayImageOptions.Builder().cacheInMemory(true).build();
|
||||||
|
private OnItemSelectedListener onItemSelectedListener;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
StreamInfoListAdapter(Activity a, View rootView) {
|
StreamInfoListAdapter(Activity a, View rootView) {
|
||||||
activity = a;
|
activity = a;
|
||||||
this.rootView = rootView;
|
this.rootView = rootView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOnItemSelectedListener(OnItemSelectedListener onItemSelectedListener) {
|
||||||
|
this.onItemSelectedListener = onItemSelectedListener;
|
||||||
|
}
|
||||||
|
|
||||||
public void addVideoList(List<StreamPreviewInfo> videos) {
|
public void addVideoList(List<StreamPreviewInfo> videos) {
|
||||||
streamList.addAll(videos);
|
streamList.addAll(videos);
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
|
@ -62,7 +71,7 @@ public class StreamInfoListAdapter extends RecyclerView.Adapter<StreamInfoItemHo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(StreamInfoItemHolder holder, int i) {
|
public void onBindViewHolder(StreamInfoItemHolder holder, int i) {
|
||||||
StreamPreviewInfo info = streamList.get(i);
|
final StreamPreviewInfo info = streamList.get(i);
|
||||||
// fill holder with information
|
// fill holder with information
|
||||||
holder.itemVideoTitleView.setText(info.title);
|
holder.itemVideoTitleView.setText(info.title);
|
||||||
if(info.uploader != null && !info.uploader.isEmpty()) {
|
if(info.uploader != null && !info.uploader.isEmpty()) {
|
||||||
|
@ -95,6 +104,13 @@ public class StreamInfoListAdapter extends RecyclerView.Adapter<StreamInfoItemHo
|
||||||
displayImageOptions,
|
displayImageOptions,
|
||||||
new ImageErrorLoadingListener(activity, rootView, info.service_id));
|
new ImageErrorLoadingListener(activity, rootView, info.service_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
holder.mainLayout.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
onItemSelectedListener.selected(info.webpage_url);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout
|
||||||
|
android:id="@+id/item_main_layout"
|
||||||
|
android:clickable="true"
|
||||||
|
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" >
|
||||||
|
|
Loading…
Reference in New Issue