1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2025-01-08 00:10:32 +00:00

+ Added Callback method to set suggestion list on ListView.

+ Search Suggestion Feature Implemented completely.
This commit is contained in:
Shekhar Sahu 2015-12-17 16:30:50 +05:30
parent 24cd478bbf
commit f7031115c0
2 changed files with 143 additions and 28 deletions

View File

@ -13,10 +13,10 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import java.util.ArrayList;
import org.schabi.newpipe.services.ServiceList; import org.schabi.newpipe.services.ServiceList;
import java.util.ArrayList;
/** /**
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org> * Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
* VideoItemListActivity.java is part of NewPipe. * VideoItemListActivity.java is part of NewPipe.
@ -66,24 +66,8 @@ public class VideoItemListActivity extends AppCompatActivity
try { try {
searchQuery = query; searchQuery = query;
listFragment.search(query); listFragment.search(query);
hideKeyPad();
// 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");
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) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -92,11 +76,35 @@ public class VideoItemListActivity extends AppCompatActivity
@Override @Override
public boolean onQueryTextChange(String newText) { public boolean onQueryTextChange(String newText) {
listFragment.searchSuggestion(newText);
return true; return true;
} }
} }
private void hideKeyPad() {
// 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");
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();
}
/** /**
* Whether or not the activity is in two-pane mode, i.e. running on a tablet * Whether or not the activity is in two-pane mode, i.e. running on a tablet
* device. * device.
@ -216,6 +224,12 @@ public class VideoItemListActivity extends AppCompatActivity
} }
} }
@Override
public void onSuggestionSelected(String suggestion) {
listFragment.search(suggestion);
hideKeyPad();
}
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu); super.onCreateOptionsMenu(menu);
@ -227,8 +241,7 @@ public class VideoItemListActivity extends AppCompatActivity
MenuItem searchItem = menu.findItem(R.id.action_search); MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView(); SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setFocusable(false); searchView.setFocusable(false);
searchView.setOnQueryTextListener( searchView.setOnQueryTextListener(new SearchVideoQueryListener());
new SearchVideoQueryListener());
} else if (videoFragment != null){ } else if (videoFragment != null){
videoFragment.onCreateOptionsMenu(menu, inflater); videoFragment.onCreateOptionsMenu(menu, inflater);

View File

@ -14,13 +14,14 @@ import android.widget.AbsListView;
import android.widget.ListView; import android.widget.ListView;
import android.widget.Toast; import android.widget.Toast;
import java.net.URL;
import java.util.List;
import java.util.Vector;
import org.schabi.newpipe.services.SearchEngine; import org.schabi.newpipe.services.SearchEngine;
import org.schabi.newpipe.services.StreamingService; import org.schabi.newpipe.services.StreamingService;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
/** /**
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org> * Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
@ -210,6 +211,7 @@ public class VideoItemListFragment extends ListFragment {
private void updateListOnResult(SearchEngine.Result result, int requestId) { private void updateListOnResult(SearchEngine.Result result, int requestId) {
if(requestId == currentRequestId) { if(requestId == currentRequestId) {
setListShown(true); setListShown(true);
setListAdapter(videoListAdapter);
if (result.resultList.isEmpty()) { if (result.resultList.isEmpty()) {
Toast.makeText(getActivity(), result.errorMessage, Toast.LENGTH_LONG).show(); Toast.makeText(getActivity(), result.errorMessage, Toast.LENGTH_LONG).show();
} else { } else {
@ -246,7 +248,7 @@ public class VideoItemListFragment extends ListFragment {
e.printStackTrace(); e.printStackTrace();
} }
} }
if(searchThread != null) { if(searchThread != null && searchRunnable!=null) {
searchRunnable.terminate(); searchRunnable.terminate();
// No need to join, since we don't really terminate the thread. We just demand // 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. // it to post its result runnable into the gui main loop.
@ -274,6 +276,7 @@ public class VideoItemListFragment extends ListFragment {
* Callback for when an item has been selected. * Callback for when an item has been selected.
*/ */
void onItemSelected(String id); void onItemSelected(String id);
void onSuggestionSelected(String suggestion);
} }
private Callbacks mCallbacks = null; private Callbacks mCallbacks = null;
@ -283,7 +286,7 @@ public class VideoItemListFragment extends ListFragment {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
list = getListView(); list = getListView();
videoListAdapter = new VideoListAdapter(getActivity(), this); videoListAdapter = new VideoListAdapter(getActivity(), this);
setListAdapter(videoListAdapter); suggestionListAdapter=new SuggestionListAdapter(getActivity(),this);
// Restore the previously serialized activated item position. // Restore the previously serialized activated item position.
if (savedInstanceState != null if (savedInstanceState != null
@ -332,7 +335,11 @@ public class VideoItemListFragment extends ListFragment {
public void onListItemClick(ListView listView, View view, int position, long id) { public void onListItemClick(ListView listView, View view, int position, long id) {
super.onListItemClick(listView, view, position, id); super.onListItemClick(listView, view, position, id);
setActivatedPosition(position); setActivatedPosition(position);
mCallbacks.onItemSelected(Long.toString(id)); if (suggestionListAdapter.getData()!=null && suggestionListAdapter.getData().size()>0){
mCallbacks.onSuggestionSelected(suggestionListAdapter.getData().get(position));
}else{
mCallbacks.onItemSelected(Long.toString(id));
}
} }
/** /**
@ -357,4 +364,99 @@ public class VideoItemListFragment extends ListFragment {
mActivatedPosition = position; mActivatedPosition = position;
} }
private SuggestionListAdapter suggestionListAdapter;
private SearchSuggestionRunnable suggestionRunnable = null;
public void searchSuggestion(String query) {
currentRequestId++;
terminateSuggestionThreads();
suggestionRunnable = new SearchSuggestionRunnable(streamingService.getSearchEngineInstance(), query, currentRequestId);
searchThread = new Thread(suggestionRunnable);
searchThread.start();
}
private class SearchSuggestionRunnable implements Runnable {
private final SearchEngine engine;
private final String query;
final Handler h = new Handler();
private volatile boolean run = true;
private final int requestId;
public SearchSuggestionRunnable(SearchEngine engine, String query, int requestId) {
this.engine = engine;
this.query = query;
this.requestId = requestId;
}
void terminate() {
run = false;
}
@Override
public void run() {
try {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext());
String searchLanguageKey = getContext().getString(R.string.searchLanguage);
String searchLanguage = sp.getString(searchLanguageKey, "en");
ArrayList<String> result = engine.suggestionList(query, searchLanguage);
Log.i(TAG, "language code passed:\"" + searchLanguage + "\"");
if (run) {
h.post(new SuggestionResultRunnable(result, requestId));
}
} catch (Exception e) {
e.printStackTrace();
h.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getActivity(), "Network Error", Toast.LENGTH_SHORT).show();
}
});
}
}
}
private class SuggestionResultRunnable implements Runnable {
private final ArrayList<String> result;
private final int requestId;
public SuggestionResultRunnable(ArrayList<String> result, int requestId) {
this.result = result;
this.requestId = requestId;
}
@Override
public void run() {
updateSuggestionList(result, requestId);
}
}
private void updateSuggestionList(ArrayList<String> suggestionList, int requestId) {
if (requestId == currentRequestId) {
setListAdapter(suggestionListAdapter);
suggestionListAdapter.clearSuggestionList();
updateSuggestionViewList(suggestionList);
}
}
private void updateSuggestionViewList(ArrayList<String> list) {
try {
suggestionListAdapter.addSuggestionList(list);
terminateSuggestionThreads();
} catch (IllegalStateException e) {
Log.w(TAG, "Trying to set value while activity doesn't exist anymore.");
} catch (Exception e) {
e.printStackTrace();
}
}
private void terminateSuggestionThreads() {
if (searchThread != null && suggestionRunnable != null) {
suggestionRunnable.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.
}
}
} }