【问题标题】:SearchView displaying wrong ListView itemsSearchView 显示错误的 ListView 项目
【发布时间】:2016-06-25 15:32:45
【问题描述】:

我的应用中的 SearchView 显示不正确的 ListView 项目时遇到问题。

如果我输入名称: ListView 会按预期显示

如果我输入 Name1: 我会得到条目 1-2

如果我输入 Name 2-11: 我会得到 Name1 的条目


这是一个视觉效果:


据我所知,代码没问题,但应用程序没有按预期工作。有人可以指出我解决这个问题的正确方向吗?


ListView 使用来自以下数据的自定义数组适配器显示:

[{"society_id":1,"name":"Name1","email":"Test@email1","description":"TestDes1"},
{"society_id":2,"name":"Name2","email":"Test@email2","description":"TestDes2"},
{"society_id":3,"name":"Name3","email":"Test@email3","description":"TestDes3"},...]

SocietySearch.java:

public class SocietySearch extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) { //TODO remember notifyDataSetChanged
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_society_search);

        List<Society> societies = new ArrayList<>();
        ServerRequests serverRequest1 = new ServerRequests(SocietySearch.this);
        serverRequest1.GetSocietyDataAsyncTask(societies, new GetSocietyCallback() {

            @Override
            public void done(final List<Society> societies) {
                ListView lv = (ListView) findViewById(R.id.ListView);
                List<ListViewItem> items = new ArrayList<>();
                for (final Society s : societies) {
                    items.add(new ListViewItem() {{
                        ThumbnailResource = R.drawable.test;
                        Title = s.socName;
                        Description = s.socDes;
                    }});
                }
                final CustomListViewAdapter adapter = new CustomListViewAdapter(SocietySearch.this, items, societies);
                lv.setAdapter(adapter);

                SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
                SearchView searchView = (SearchView) findViewById(R.id.search);
                searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
                searchView.setQueryHint("Search..");

                searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
                    @Override
                    public boolean onQueryTextSubmit(String query) {
                        return false;
                    }

                    @Override
                    public boolean onQueryTextChange(String newText) {
                        adapter.getFilter().filter(newText);
                        return false;
                    }
                });
            }
        });
    }

    public class ListViewItem {
        public int ThumbnailResource;
        public String Title;
        public String Description;
    }

CustomListViewAdapter.java:

public class CustomListViewAdapter extends ArrayAdapter {

    LayoutInflater inflater;
    List<SocietySearch.ListViewItem> items;

    public CustomListViewAdapter(Activity context, List<SocietySearch.ListViewItem> items, List<Society> societies) {

        super(context, R.layout.item_row, societies);

        this.items = items;
        this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        //Auto-generated method stub

        ListViewItem item = items.get(position);

        View vi = convertView;

        if (convertView == null)
            vi = inflater.inflate(R.layout.item_row, null);

        ImageView test = (ImageView) vi.findViewById(R.id.imgThumbnail);
        TextView txtTitle = (TextView) vi.findViewById(R.id.txtTitle);
        TextView txtSubTitle = (TextView) vi.findViewById(R.id.txtSubTitle);

        test.setImageResource(item.ThumbnailResource);
        txtTitle.setText(item.Title);
        txtSubTitle.setText(item.Description);


        return vi;
    }
}

Society.java:

public class Society {

    String socName, socEmail, socDes;
    int society_id;

    public Society(int society_id, String socName, String socEmail, String socDes) {

        this.society_id = society_id;
        this.socName = socName;
        this.socEmail = socEmail;
        this.socDes = socDes;

    }

    public String toString() {
        return socName;
    }
}

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="k.unionapp">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

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

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".HomeScreenActivity"
            android:theme="@style/AppTheme.NoActionBar"></activity>
        <activity android:name=".SocietySearch"></activity>
    </application>
</manifest>

【问题讨论】:

    标签: java android listview searchview custom-adapter


    【解决方案1】:

    我相信您的问题可能是因为您保留了内存中的原始列表,并将您的视图绑定到该列表中

    ListViewItem item = items.get(position);
    

    相反,您可能想尝试从适配器本身获取项目,因为Filter 正在更改底层列表

    ListViewItem item = this.getItem(position);
    

    【讨论】:

    • ArrayAdapter中没有这个方法,但是有getItem(int position)
    • 谢谢。复制粘贴错误,已修复
    【解决方案2】:

    您需要在SocietySearch.ListViewItem 类中提供toString 方法的实现,该方法将返回项目名称。

    public class ListViewItem {
        public int ThumbnailResource;
        public String Title;
        public String Description;
    
        @Override
        public String toString(){
            return Title;
        }
    }
    

    ArrayAdapter 中过滤器的默认实现使用此方法将任意项目类型转换为String,然后再将其与搜索查询进行比较。此外,默认实现 - ArrayFilter - 使用查询字符串作为前缀,仅供参考。


    此外,正如其他答案中所述 - 不要在构造函数和 getView 方法中保留原始列表。使用数组适配器本身的getItem方法。

    您可能还想更改类声明以包含自定义类型的项目而不是通用Object

    public class CustomListViewAdapter extends ArrayAdapter<SocietySearch.ListViewItem> {
    

    【讨论】:

    • 不幸的是,我仍然得到相同的结果
    • 全力以赴,用 ArrayAdapter 扩展为我的 super() 提供了错误
    • super(context, R.layout.item_row, societies);,将societies替换为items。为什么构造函数中有不使用的参数?
    • 非常感谢!这很好用,你真的帮助了我。我很感激。
    猜你喜欢
    • 2021-06-26
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    • 2019-04-22
    • 1970-01-01
    • 2018-06-10
    • 1970-01-01
    相关资源
    最近更新 更多