mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2025-01-08 16:30:34 +00:00
+ Added Callback method to set suggestion list on ListView.
+ Search Suggestion Feature Implemented completely.
This commit is contained in:
parent
24cd478bbf
commit
f7031115c0
@ -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);
|
||||||
|
@ -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.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user