1
0
mirror of https://github.com/TeamNewPipe/NewPipe synced 2025-01-06 15:30:31 +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.inputmethod.InputMethodManager;
import java.util.ArrayList;
import org.schabi.newpipe.services.ServiceList;
import java.util.ArrayList;
/**
* Copyright (C) Christian Schabesberger 2015 <chris.schabesberger@mailbox.org>
* VideoItemListActivity.java is part of NewPipe.
@ -66,24 +66,8 @@ public class VideoItemListActivity extends AppCompatActivity
try {
searchQuery = 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) {
e.printStackTrace();
}
@ -92,11 +76,35 @@ public class VideoItemListActivity extends AppCompatActivity
@Override
public boolean onQueryTextChange(String newText) {
listFragment.searchSuggestion(newText);
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
* 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) {
super.onCreateOptionsMenu(menu);
@ -227,8 +241,7 @@ public class VideoItemListActivity extends AppCompatActivity
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setFocusable(false);
searchView.setOnQueryTextListener(
new SearchVideoQueryListener());
searchView.setOnQueryTextListener(new SearchVideoQueryListener());
} else if (videoFragment != null){
videoFragment.onCreateOptionsMenu(menu, inflater);

View File

@ -14,13 +14,14 @@ import android.widget.AbsListView;
import android.widget.ListView;
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.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>
@ -210,6 +211,7 @@ public class VideoItemListFragment extends ListFragment {
private void updateListOnResult(SearchEngine.Result result, int requestId) {
if(requestId == currentRequestId) {
setListShown(true);
setListAdapter(videoListAdapter);
if (result.resultList.isEmpty()) {
Toast.makeText(getActivity(), result.errorMessage, Toast.LENGTH_LONG).show();
} else {
@ -246,7 +248,7 @@ public class VideoItemListFragment extends ListFragment {
e.printStackTrace();
}
}
if(searchThread != null) {
if(searchThread != null && searchRunnable!=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.
@ -274,6 +276,7 @@ public class VideoItemListFragment extends ListFragment {
* Callback for when an item has been selected.
*/
void onItemSelected(String id);
void onSuggestionSelected(String suggestion);
}
private Callbacks mCallbacks = null;
@ -283,7 +286,7 @@ public class VideoItemListFragment extends ListFragment {
super.onViewCreated(view, savedInstanceState);
list = getListView();
videoListAdapter = new VideoListAdapter(getActivity(), this);
setListAdapter(videoListAdapter);
suggestionListAdapter=new SuggestionListAdapter(getActivity(),this);
// Restore the previously serialized activated item position.
if (savedInstanceState != null
@ -332,7 +335,11 @@ public class VideoItemListFragment extends ListFragment {
public void onListItemClick(ListView listView, View view, int position, long id) {
super.onListItemClick(listView, view, position, id);
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;
}
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.
}
}
}