简体   繁体   English

在操作栏中搜索无法与列表视图的自定义适配器一起正常使用

[英]Search in Action bar not working properly with custom adapter for listview

Well, i am trying to make an activity which will have a listView and will be searchable by the Action bar search option. 好吧,我正在尝试进行一个具有listView的活动,并且可以通过操作栏搜索选项进行搜索。

If, i use the default arraylist of android, it just works fine. 如果我使用android的默认arraylist,它就可以正常工作。

But when i am trying to use my own adapter which extends baseAdapter, it is not working properly( doesn't search properly). 但是,当我尝试使用自己的扩展baseAdapter的适配器时,它无法正常工作(无法正确搜索)。

My total code is in the below link. 我的总代码在下面的链接中。

Link for my App 链接到我的应用

Can someone please help me regarding the issue? 有人可以帮我解决这个问题吗?

The codes are:: 代码是:

Manifest:: 表现::

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.example.mysearchapp"
 android:versionCode="1"
 android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="14"
    android:targetSdkVersion="21" />

 <application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".SecondActivity"
        android:label="@string/title_activity_second" >
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />

        </intent-filter>

        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable" />

    </activity>
 </application>
</manifest>

Menu(res/menu/second.xml):: 菜单(RES /菜单/ second.xml)::

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
    android:id="@+id/action_search"
    android:actionViewClass="android.widget.SearchView"
    android:icon="@drawable/ic_launcher"
    android:showAsAction="always"
    android:title="Search"/>

</menu>

Layout(res/layout):: 布局(RES /布局)::

<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"
tools:context="${relativePackage}.${activityClass}" >

 <ListView
    android:id="@+id/listview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:cacheColorHint="#00000000" />

 </RelativeLayout>

searchable.xml(in res/xml):: searchable.xml(在res / xml中)::

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
  android:hint="search..."
  android:label="@string/app_name" />

The custom Adapter:: 自定义适配器::

        public class ImageAdapter extends BaseAdapter implements Filterable
{
        private Context context;
        private ArrayList<String> originalData = null;
        ArrayList<String> filteredData = null;

        ValueFilter valueFilter = new ValueFilter();

        public ImageAdapter(Context context, ArrayList<String> mobileValues) 
 {
            this.context = context;
            this.originalData = mobileValues;
            this.filteredData = mobileValues;
        }

        @Override
        public int getCount() {
            return filteredData.size();
        }

        @Override
        public Object getItem(int position) {
            return filteredData.get(position);
        }

        @Override
        public long getItemId(int position) {
            return filteredData.indexOf(getItem(position));
        }

        public View getView(int position, View convertView, ViewGroup parent) 
 {

            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            View gridView;

            if (convertView == null) {

                gridView = new View(context);

                // get layout from mobile.xml
                gridView = inflater.inflate(R.layout.city_list_item, null);

                // set value into textview
                TextView textView = (TextView) gridView
                        .findViewById(R.id.grid_item_label);
                textView.setText(originalData.get(position));

                // set image based on selected text
                // ImageView imageView = (ImageView)
                // gridView.findViewById(R.id.grid_item_image);

                // imageView.setImageResource(R.drawable.city_image);

            } else {
                gridView = (View) convertView;
            }

            return gridView;
        }

        @Override
        public void notifyDataSetChanged() {
            super.notifyDataSetChanged();
        }

        @Override
        public Filter getFilter() {
            return valueFilter;
        }

        private class ValueFilter extends Filter {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                String filterString = constraint.toString().toUpperCase();

                FilterResults results = new FilterResults();

                /*
                 * if (constraint != null && constraint.length() > 0) {
                 */
                final ArrayList<String> lst = ImageAdapter.this.originalData;
                int count = lst.size();

                final ArrayList<String> filterList = new ArrayList<String>(count);

                String filterableString;

                for (int i = 0; i < count; i++) {
                    filterableString = lst.get(i);

                    if ((filterableString.toUpperCase()).contains(filterString)) {

                        filterList.add(filterableString);
                    }
                }
                results.count = filterList.size();
                results.values = filterList;
                /* } *//*
                         * else { results.count = mStringFilterList.size();
                         * results.values = mStringFilterList; }
                         */
                return results;

            }

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence constraint,
                    FilterResults results) {
                filteredData = (ArrayList<String>) results.values;
                notifyDataSetChanged();
            }

        }
    }

And the activity:: 活动:

    public class SecondActivity extends Activity {

        // ArrayAdapter<String> myAdapter;
        ImageAdapter myAdapter;
        ListView listView;
        // String[] dataArray = new String[] {"India","Androidhub4you", "Pakistan",
        // "Srilanka", "Nepal", "Japan"};
        private ArrayList<String> dataArray = new ArrayList<String>();

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_second);

            dataArray.add("India");
            dataArray.add("Androidhub4you");
            dataArray.add("Pakistan");
            dataArray.add("Srilanka");
            dataArray.add("Nepal");
            dataArray.add("Japan");

            listView = (ListView) findViewById(R.id.listview);
            // myAdapter = new ArrayAdapter<String>(this,
            // android.R.layout.simple_list_item_1, dataArray);
            myAdapter = new ImageAdapter(SecondActivity.this, dataArray);
            listView.setAdapter(myAdapter);
            listView.setTextFilterEnabled(true);

            listView.setOnItemClickListener(new OnItemClickListener() {

                @Override
                public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                        long arg3) {

                    System.out.println(arg2 + " --postion");
                }
            });
        }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.second, menu);

            SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
            SearchView searchView = (SearchView) menu.findItem(R.id.action_search)
                    .getActionView();

            searchView.setSearchableInfo(searchManager
                    .getSearchableInfo(getComponentName()));
            searchView.setIconifiedByDefault(false);

            SearchView.OnQueryTextListener textChangeListener = new SearchView.OnQueryTextListener() {
                @Override
                public boolean onQueryTextChange(String newText) {
                    // this is your adapter that will be filtered
                    myAdapter.getFilter().filter(newText);
                    System.out.println("on text chnge text: " + newText);
                    return true;
                }

                @Override
                public boolean onQueryTextSubmit(String query) {
                    // this is your adapter that will be filtered
                    myAdapter.getFilter().filter(query);
                    System.out.println("on query submit: " + query);
                    return true;
                }
            };
            searchView.setOnQueryTextListener(textChangeListener);

            return super.onCreateOptionsMenu(menu);

        }
    }

In your adapter move this 在您的适配器中移动它

TextView textView = (TextView) gridView.findViewById(R.id.grid_item_label);
textView.setText(originalData.get(position));

right before the return statement. 就在return语句之前。

How the getView method works: getView方法如何工作:

If a view is already available take that view, if it is not available make a new one. 如果一个视图已经可用,请使用该视图;如果不可用,请重新创建一个视图。 Now that the adapter has a view, load it with data. 现在适配器已经有了视图,可以将其加载数据。

Full code 完整代码

public View getView(int position, View convertView, ViewGroup parent) {
    View gridView;

    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        // gridView = new View(context); // this line is useless, you're overwriting the variable on the next line

        // inflate new layout
        // gridView = inflater.inflate(R.layout.city_list_item, null); // wrong
        gridView = inflater.inflate(R.layout.city_list_item, parent, false); // right
    } else {
        // reuse previously created view
        gridView = (View) convertView;
    }

    // set value into textview
    TextView textView = (TextView) gridView.findViewById(R.id.grid_item_label);
    textView.setText(originalData.get(position));

    // set image based on selected text
    //ImageView imageView = (ImageView) gridView.findViewById(R.id.grid_item_image);
    //imageView.setImageResource(R.drawable.city_image);

    // finding views all over again is not effective, google "viewholder"

    return gridView;
}

EDIT: 编辑:

The correct item to load comes not from the original data set but from the filtered one. 要加载的正确项目不是来自原始数据集,而是来自经过过滤的数据集。 After implementing String getItem(int) method properly always call this method inside your View getView(int, View, parent) . 正确实现String getItem(int)方法后,请始终在您的View getView(int, View, parent)内部调用此方法。

textView.setText(getItem(position));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM