قائمة بحث Android أثناء الكتابة
-
24-09-2019 - |
سؤال
كيف يمكنني إنشاء شريط بحث حيث يتم عرض النتائج أثناء كتابة النتائج في ListView
الذي أبحث عنه؟
على سبيل المثال ، لدي عرض قائمة مع 20 سلاسل. أضغط على مفتاح البحث ويبدو الشريط. أريد عندما أكتب كلمات 3 أو أكثر ، يبدأ البحث في تشغيل النتائج في عرض القائمة (كمرشح: يعرض فقط الأوتار في القائمة التي تطابق ما أكتبه)
المحلول
لا يمكنك القيام بذلك مع شريط البحث. لكن ListView لديها إمكانية تصفية على المفتاح المضغوط, ، كما هو يتم في جهات الاتصال. يبدأ المستخدم ببساطة الكتابة ويتم تصفية القائمة بعد ذلك. التصفية لا يحب البحث حقًا. إذا كنت تحتوي على كلمة Foo في مكان ما ، فسيتم تصفية OO Foo ، ولكن إذا قمت بكتابة فسيبقى حتى إذا كان عنصر القائمة هو شريط الاتصال.
عليك ببساطة تمكينه:
ListView lv = getListView();
lv.setTextFilterEnabled(true);
لا أعرف كيف يتم ذلك إذا لم يكن لديك لوحة مفاتيح للأجهزة. أنا أستخدم الروبوت وبدأت في الكتابة تبدأ القائمة للتصفية وإظهار النتائج المطابقة فقط.
نصائح أخرى
انا اؤمن ان هذا ما تبحث عنه:
اطلب من نشاطك تطبيق SearchView.OnqueryTextListener
وأضف الطرق التالية:
public boolean onQueryTextChange(String newText) {
if (TextUtils.isEmpty(newText)) {
mListView.clearTextFilter();
} else {
mListView.setFilterText(newText.toString());
}
return true;
}
public boolean onQueryTextSubmit(String query) {
return false;
}
لقد استخدمت EditText
للقيام بهذه المهمة.
أولاً ، قمت بإنشاء نسختين من الصفيف للاحتفاظ بقائمة البيانات للبحث:
List<Map<String,String>> vehicleinfo;
List<Map<String,String>> vehicleinfodisplay;
بمجرد أن أحصل على بيانات قائمتي من مكان ما ، أقوم بنسخها:
for(Map<String,String>map : vehicleinfo)
{
vehicleinfodisplay.add(map);
}
واستخدام SimpleAdapter
لعرض إصدار العرض (نسخ) من بياناتي:
String[] from={"vehicle","dateon","dateoff","reg"};
int[] to={R.id.vehicle,R.id.vehicledateon,R.id.vehicledateoff,R.id.vehiclereg};
listadapter=new SimpleAdapter(c,vehicleinfodisplay,R.layout.vehiclelistrow,from,to);
vehiclelist.setAdapter(listadapter);
ثم أضفت أ TextWatcher
إلى EditText
الذي يستجيب إلى afterTextChanged
الحدث عن طريق مسح إصدار العرض من القائمة ثم إضافة العناصر فقط من القائمة الأخرى التي تلبي معايير البحث (في هذه الحالة ، يحتوي حقل "Reg" على سلسلة البحث). بمجرد ملء قائمة العرض مع القائمة التي تمت تصفيتها ، أتصل فقط notifyDataSetChanged
في القائمة SimpleAdapter
.
searchbox.addTextChangedListener(new TextWatcher()
{
@Override
public void afterTextChanged(Editable s)
{
vehicleinfodisplay.clear();
String search=s.toString();
for(Map<String,String>map : vehicleinfo)
{
if(map.get("reg").toLowerCase().contains(search.toLowerCase()))
vehicleinfodisplay.add(map);
listadapter.notifyDataSetChanged();
}
};
... other overridden methods can go here ...
});
نأمل أن يكون هذا مفيد لشخص ما.
استخدم التعليمات البرمجية التالية لتنفيذ قائمة البحث والفلتر في Android:
SearchAndFilterList.java
public class SearchAndFilterList extends Activity {
private ListView mSearchNFilterLv;
private EditText mSearchEdt;
private ArrayList<String> mStringList;
private ValueAdapter valueAdapter;
private TextWatcher mSearchTw;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_and_filter_list);
initUI();
initData();
valueAdapter=new ValueAdapter(mStringList,this);
mSearchNFilterLv.setAdapter(valueAdapter);
mSearchEdt.addTextChangedListener(mSearchTw);
}
private void initData() {
mStringList=new ArrayList<String>();
mStringList.add("one");
mStringList.add("two");
mStringList.add("three");
mStringList.add("four");
mStringList.add("five");
mStringList.add("six");
mStringList.add("seven");
mStringList.add("eight");
mStringList.add("nine");
mStringList.add("ten");
mStringList.add("eleven");
mStringList.add("twelve");
mStringList.add("thirteen");
mStringList.add("fourteen");
mSearchTw=new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
valueAdapter.getFilter().filter(s);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
};
}
private void initUI() {
mSearchNFilterLv=(ListView) findViewById(R.id.list_view);
mSearchEdt=(EditText) findViewById(R.id.txt_search);
}
}
محول القيمة المخصصة:Valueadapter.java
public class ValueAdapter extends BaseAdapter implements Filterable{
private ArrayList<String> mStringList;
private ArrayList<String> mStringFilterList;
private LayoutInflater mInflater;
private ValueFilter valueFilter;
public ValueAdapter(ArrayList<String> mStringList,Context context) {
this.mStringList=mStringList;
this.mStringFilterList=mStringList;
mInflater=LayoutInflater.from(context);
getFilter();
}
//How many items are in the data set represented by this Adapter.
@Override
public int getCount() {
return mStringList.size();
}
//Get the data item associated with the specified position in the data set.
@Override
public Object getItem(int position) {
return mStringList.get(position);
}
//Get the row id associated with the specified position in the list.
@Override
public long getItemId(int position) {
return position;
}
//Get a View that displays the data at the specified position in the data set.
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder viewHolder;
if(convertView==null) {
viewHolder=new Holder();
convertView=mInflater.inflate(R.layout.list_item,null);
viewHolder.nameTv=(TextView)convertView.findViewById(R.id.txt_listitem);
convertView.setTag(viewHolder);
}else{
viewHolder=(Holder)convertView.getTag();
}
viewHolder.nameTv.setText(mStringList.get(position).toString());
return convertView;
}
private class Holder{
TextView nameTv;
}
//Returns a filter that can be used to constrain data with a filtering pattern.
@Override
public Filter getFilter() {
if(valueFilter==null) {
valueFilter=new ValueFilter();
}
return valueFilter;
}
private class ValueFilter extends Filter {
//Invoked in a worker thread to filter the data according to the constraint.
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results=new FilterResults();
if(constraint!=null && constraint.length()>0){
ArrayList<String> filterList=new ArrayList<String>();
for(int i=0;i<mStringFilterList.size();i++){
if(mStringFilterList.get(i).contains(constraint)) {
filterList.add(mStringFilterList.get(i));
}
}
results.count=filterList.size();
results.values=filterList;
}else{
results.count=mStringFilterList.size();
results.values=mStringFilterList;
}
return results;
}
//Invoked in the UI thread to publish the filtering results in the user interface.
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
mStringList=(ArrayList<String>) results.values;
notifyDataSetChanged();
}
}
}
Activity_search_and_filter_list.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/txt_search"
tools:context=".SearchAndFilterList"
android:hint="Enter text to search" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/list_view"
android:layout_below="@+id/txt_search"></ListView>
</RelativeLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/txt_listitem"/>
</RelativeLayout>
Androidmanifext.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.searchandfilterlistview"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".SearchAndFilterList"
android:label="@string/title_activity_search_and_filter_list" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
آمل أن يساعد هذا الرمز في تطبيق ListView للبحث والتصفية المخصص
أفضل طريقة هي استخدام شريط البحث المدمج أو SearchManager من خلال تجاوز OnSearchRequested في نشاط قابل للبحث. يمكنك تعيين مصدر بيانات للبحث عنه للحصول على الانخفاض التلقائي للنتائج أو يمكنك فقط أخذ المدخلات من المستخدم والبحث بعد. هذه لمحة عامة جيدة عن SearchManager هل يوجد عرض عمل في مشروع API Demos com.example.android.apis.app.searchqueryResult
@Override
public boolean onSearchRequested() {