سؤال

كيف يمكنني إنشاء شريط بحث حيث يتم عرض النتائج أثناء كتابة النتائج في ListView الذي أبحث عنه؟

على سبيل المثال ، لدي عرض قائمة مع 20 سلاسل. أضغط على مفتاح البحث ويبدو الشريط. أريد عندما أكتب كلمات 3 أو أكثر ، يبدأ البحث في تشغيل النتائج في عرض القائمة (كمرشح: يعرض فقط الأوتار في القائمة التي تطابق ما أكتبه)

هل كانت مفيدة؟

المحلول

لا يمكنك القيام بذلك مع شريط البحث. لكن ListView لديها إمكانية تصفية على المفتاح المضغوط, ، كما هو يتم في جهات الاتصال. يبدأ المستخدم ببساطة الكتابة ويتم تصفية القائمة بعد ذلك. التصفية لا يحب البحث حقًا. إذا كنت تحتوي على كلمة Foo في مكان ما ، فسيتم تصفية OO Foo ، ولكن إذا قمت بكتابة فسيبقى حتى إذا كان عنصر القائمة هو شريط الاتصال.

عليك ببساطة تمكينه:

ListView lv = getListView();
lv.setTextFilterEnabled(true);

لا أعرف كيف يتم ذلك إذا لم يكن لديك لوحة مفاتيح للأجهزة. أنا أستخدم الروبوت وبدأت في الكتابة تبدأ القائمة للتصفية وإظهار النتائج المطابقة فقط.

نصائح أخرى

انا اؤمن ان هذا ما تبحث عنه:

http://www.java2s.com/code/android/2d-graphics/showsalistthatcanbefilteringinplacewithasearchviewinnoniconifiedmode.htm

اطلب من نشاطك تطبيق 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() {
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top