[SOLVED] Будьте любезны, подскажите, как можно сделать элемент SearchView(android.support.v7.widget) в ActionBar(android.support.v7.app) сродне MultiAutoCompleteTextView, чтоб после ввода слова(не всего выражения) отображалось дополнение конкретно для него. Я не расширял MultiAutoCompleteTextView, потому что не хотел терять стандартное решение для иконки поиска и кнопки стирания текста. Я задал этот же вопрос тут: http://stackoverflow.com/questions/2825 ... -delimiter.
К третьему посту прикрепил код решения.
Автодополнение SearchView с разделителем.
- CullyCross
- Сообщения: 3
- Зарегистрирован: 31 янв 2015, 23:15
Автодополнение SearchView с разделителем.
Последний раз редактировалось CullyCross 01 фев 2015, 07:35, всего редактировалось 1 раз.
- CullyCross
- Сообщения: 3
- Зарегистрирован: 31 янв 2015, 23:15
Re: Автодополнение SearchView с разделителем.
Обновил код на stackoverflow. Копирую сюда:
Расширение класса SearchView:
xml файл с меню:
Метод onCreateOptionsMenu
getActionView возвращает null.
Расширение класса SearchView:
Код: Выделить всё
public class MultiAutoCompleteSearchView extends android.support.v7.widget.SearchView {
private MultiAutoCompleteSearchView.SearchAutoComplete mSearchAutoComplete;
public static class SearchAutoComplete extends android.support.v7.widget.SearchView.SearchAutoComplete {
private String mSeparator = "+";
public SearchAutoComplete(Context context) {
super(context);
}
public SearchAutoComplete(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SearchAutoComplete(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void replaceText(CharSequence text) {
String newText = getText().toString();
if (newText.contains(mSeparator)) {
int lastIndex = newText.lastIndexOf(mSeparator);
newText = newText.substring(0, lastIndex + 1) + text.toString();
} else {
newText = text.toString();
}
super.replaceText(newText);
}
@Override
protected void performFiltering(CharSequence text, int keyCode) {
String newText = text.toString();
if (newText.indexOf(mSeparator) != -1) {
int lastIndex = newText.lastIndexOf(mSeparator);
if (lastIndex != newText.length() - 1) {
newText = newText.substring(lastIndex + 1).trim();
if (newText.length() >= getThreshold()) {
text = newText;
}
}
}
super.performFiltering(text, keyCode);
}
}
public void initialize() {
mSearchAutoComplete = (MultiAutoCompleteSearchView.SearchAutoComplete)
findViewById(android.support.v7.appcompat.R.id.search_src_text);
this.setAdapter(null);
this.setOnItemClickListener(null);
}
public MultiAutoCompleteSearchView(Context context) {
super(context);
initialize();
}
public MultiAutoCompleteSearchView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
public MultiAutoCompleteSearchView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize();
}
public void setOnItemClickListener(AdapterView.OnItemClickListener listener) {
mSearchAutoComplete.setOnItemClickListener(listener);
}
public void setAdapter(ArrayAdapter<?> adapter) {
mSearchAutoComplete.setAdapter(adapter);
}
}Код: Выделить всё
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".SearchActivity">
<item android:id="@+id/action_search"
android:title="@string/action_search"
android:icon="@drawable/ic_action_search"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="cullycross.com.searchview.MultiAutoCompleteSearchView" />
</menu>Код: Выделить всё
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_search, menu);
final MenuItem searchItem = menu.findItem(R.id.action_search);
final MultiAutoCompleteSearchView searchView = (MultiAutoCompleteSearchView)
MenuItemCompat.getActionView(searchItem);
searchView.setQueryHint("Type any word");
MultiAutoCompleteSearchView.SearchAutoComplete searchAutoComplete =
(MultiAutoCompleteSearchView.SearchAutoComplete)searchView
.findViewById(R.id.search_src_text);
searchAutoComplete.setAdapter(new ArrayAdapter<String>(
this,
android.R.layout.simple_dropdown_item_1line,
options
));
return true;
}- CullyCross
- Сообщения: 3
- Зарегистрирован: 31 янв 2015, 23:15
Re: Автодополнение SearchView с разделителем.
Часов 6-7 позади - я написал решение. Я долго гуглил, прежде изобретать велосипед, надеюсь, что решения действительно нет в интернете, иначе обидно
. Если кому будет интересно:
Кастомный адаптер, который фильтрует значения, сохраняет старую строку:
Расширенный SearchView :
onCreateOptionsMenu в Activity:
XML файл menu:
Кастомный адаптер, который фильтрует значения, сохраняет старую строку:
Код: Выделить всё
package cullycross.com.searchview;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
* Created by cullycross on 2/1/15.
*/
public class DelimiterAdapter extends ArrayAdapter<String> implements Filterable {
private final static String [] options = {
"Apple","Mango","Peach","Banana","Orange","Grapes","Watermelon","Tomato"
};
private final LayoutInflater mInflater;
private List<String> mSubStrings;
private String mMainString;
public String getMainString() { return mMainString; }
private FuckingAmazingFilter mFilter;
public DelimiterAdapter(Context context, int resource) {
super(context, -1);
mInflater = LayoutInflater.from(context);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final TextView tv;
if (convertView != null) {
tv = (TextView) convertView;
} else {
tv = (TextView) mInflater.inflate(android.R.layout.simple_dropdown_item_1line, parent, false);
}
tv.setText(getItem(position));
return tv;
}
@Override
public int getCount() {
return mSubStrings.size();
}
@Override
public String getItem(int position) {
return mSubStrings.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public Filter getFilter() {
if(mFilter == null) {
mFilter = new FuckingAmazingFilter();
}
return mFilter;
}
private class FuckingAmazingFilter extends Filter {
private final static String DELIMITER = "+";
@Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults filterResults = new FilterResults();
String request;
mSubStrings = new ArrayList<String>();
if(constraint != null) {
request = constraint.toString();
//cuts the string with delimiter
if (request.contains(DELIMITER) &&
request.lastIndexOf(DELIMITER) != request.length() - 1) {
final String[] splitted = request.split("\\" + DELIMITER);
request = splitted[splitted.length - 1].trim();
//save string before delimiter
int index = constraint.toString().lastIndexOf(request);
mMainString = constraint.toString().substring(0, index);
} else {
request = request.trim();
mMainString = "";
}
//checks for substring of any word in the dictionary
for(String s : options) {
if(s.contains(request)) {
mSubStrings.add(s);
}
}
}
filterResults.values = mSubStrings;
filterResults.count = mSubStrings.size();
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
clear();
for (String request : (ArrayList<String>)results.values) {
add(request);
}
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}
}
Код: Выделить всё
package cullycross.com.searchview;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
/**
* Created by cullycross on 1/31/15.
*/
public class MultiAutoCompleteSearchView extends android.support.v7.widget.SearchView {
private SearchAutoComplete mSearchAutoComplete;
public void initialize() {
mSearchAutoComplete = (SearchAutoComplete)
findViewById(android.support.v7.appcompat.R.id.search_src_text);
this.setAdapter(null);
this.setOnItemClickListener(null);
}
public MultiAutoCompleteSearchView(Context context) {
super(context);
initialize();
}
public MultiAutoCompleteSearchView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
public MultiAutoCompleteSearchView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize();
}
public void setOnItemClickListener(AdapterView.OnItemClickListener listener) {
mSearchAutoComplete.setOnItemClickListener(listener);
}
public void setAdapter(ArrayAdapter<?> adapter) {
mSearchAutoComplete.setAdapter(adapter);
}
}
Код: Выделить всё
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_search, menu);
final MenuItem searchItem = menu.findItem(R.id.action_search);
final MultiAutoCompleteSearchView searchView = (MultiAutoCompleteSearchView)
MenuItemCompat.getActionView(searchItem);
searchView.setQueryHint("Type any word");
MultiAutoCompleteSearchView.SearchAutoComplete searchAutoComplete =
(MultiAutoCompleteSearchView.SearchAutoComplete)searchView
.findViewById(R.id.search_src_text);
//since words are very short
searchAutoComplete.setThreshold(1);
searchAutoComplete.setAdapter(new DelimiterAdapter(
this,
android.R.layout.simple_dropdown_item_1line
));
searchView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String stringBefore, newString;
stringBefore = ((DelimiterAdapter)parent.getAdapter()).getMainString();
newString = parent.getAdapter().getItem(position).toString();
searchView.setQuery(stringBefore+newString, false);
}
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
if(s.length() > 0) {
mFindString = s;
mGetAndParse.getAndParse("lalka");
return true;
}
return false;
}
@Override
public boolean onQueryTextChange(String s) {
/*StringBuilder filteredStringBuilder = new StringBuilder();
for (char ch : s.toCharArray()) {
if (Character.isLetter(ch) || ch == '+') {
filteredStringBuilder.append(ch);
}
}
searchView.setQuery(filteredStringBuilder.toString(), false);*/
return false;
}
});
return true;
}Код: Выделить всё
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".SearchActivity">
<item android:id="@+id/action_search"
android:title="@string/action_search"
android:icon="@drawable/ic_action_search"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="cullycross.com.searchview.MultiAutoCompleteSearchView" />
</menu>