列表视图的搜索功能

Posted

技术标签:

【中文标题】列表视图的搜索功能【英文标题】:Search Functionality for Listview 【发布时间】:2012-09-04 00:39:00 【问题描述】:

我是安卓新手。我只是想为我的应用程序制作一个简单的搜索功能。我的应用程序包含一个ListView 一个EditText 和一个Button 用于搜索。我的 ListView 内容是使用扩展 BaseAdapter 的自定义适配器从数据库中列出的

现在,我想做的是,我想搜索来自ListView 的任何记录,例如,如果我有一些类似的记录

优化、运营、数据挖掘、计算机伦理、计算机体系结构等......

所以,当我输入一些记录名称时,例如op

列表视图应该列出从 op... 开始的记录

而且,我们可以通过点击button 来实现同样的功能吗

有人对此有任何想法吗?提前致谢。

【问题讨论】:

通过***.com/a/11009026/1398150 查看此链接***.com/questions/5220551/… 【参考方案1】:

不久前我问过一个类似的问题。这里:Filtering a ListView with Baseadapter filters text not images。虽然,我的具体问题涉及 GridView,但这个概念(和代码)可以代替 ListView。

注意:这将是一个冗长的帖子,但我认为为了完整起见是必要的(虽然我省略了imports

主要活动(Friends.java

public class Friends extends SherlockActivity 

    // BUNDLE OBJECT TO GET DATA FROM EARLIER ACTIVITY
    Bundle extras;

    // INITIAL ALBUM ID AND NAME
    String initialUserID;

    // THE GRIDVIEW
    GridView gridOfFriends;

    // THE ADAPTER
    FriendsAdapter adapter;

    // ARRAYLIST TO HOLD DATA
    ArrayList<getFriends> arrFriends;

    // LINEARLAYOUT TO SHOW THE FOOTER PROGRESS BAR
    LinearLayout linlaProgressBar;

    // THE EDITTEXT TO FILTER USERS
    EditText filterText;

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

        extras = getIntent().getExtras();

        if (extras.containsKey("USER_ID"))  
            initialUserID = extras.getString("USER_ID");
         else 
            Toast.makeText(
                    getApplicationContext(), 
                    "There was a problem getting your Friends Data. Please hit the back button and try again.", 
                    Toast.LENGTH_SHORT).show();
        

        ActionBar actionBar = getSupportActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setDisplayShowHomeEnabled(true);
        actionBar.setDisplayShowTitleEnabled(true);
        actionBar.setTitle("Your Friends");

        // CAST THE GRIDVIEW
        gridOfFriends = (GridView) findViewById(R.id.gridFriends);

        // INSTANTIATE THE ARRAYLIST
        arrFriends = new ArrayList<getFriends>();

        // CAST THE ADAPTER
        adapter = new FriendsAdapter(Friends.this, arrFriends);

        // CAST THE LINEARLAYOUT THAT HOLDS THE PROGRESS BAR
        linlaProgressBar = (LinearLayout) findViewById(R.id.linlaProgressBar);
        linlaProgressBar.setVisibility(View.GONE);

        // GET THE LOGGED IN USERS FRIENDS DATA
        if (initialUserID != null)  
            new getFriendsData().execute();
         else 
            Toast.makeText(
                    getApplicationContext(), 
                    "There was a problem getting your Friends Data. Please hit the back button and try again.", 
                    Toast.LENGTH_SHORT).show();
        

        // CAST THE EDITTEXT AND SETUP FILTERING
        filterText = (EditText) findViewById(R.id.editFilterList);
        filterText.addTextChangedListener(filterTextWatcher);
    

    private class getFriendsData extends AsyncTask<Void, Void, Void>    

        @Override
        protected void onPreExecute() 

            // SHOW THE BOTTOM PROGRESS BAR (SPINNER) WHILE LOADING THE FRIENDS LIST
            linlaProgressBar.setVisibility(View.VISIBLE);
        

        @Override
        protected Void doInBackground(Void... params) 

            try 
                String query = 
                        "SELECT name, uid, pic_big " +
                        "FROM user " +
                        "WHERE uid in " +
                        "(SELECT uid2 FROM friend WHERE uid1=me()) " +
                        "order by name";
                Bundle paramGetFriendsList = new Bundle();
                paramGetFriendsList.putString("method", "fql.query");
                paramGetFriendsList.putString("query", query);

                String resultFriendsList = Utility.mFacebook.request(paramGetFriendsList);

                JSONArray JAFriends = new JSONArray(resultFriendsList);

                getFriends friends;

                if (JAFriends.length() == 0)    

                 else 
                    for (int i = 0; i < JAFriends.length(); i++) 
                        JSONObject JOFriends = JAFriends.getJSONObject(i);

                        friends = new getFriends();

                        // SET FRIENDS ID
                        if (JOFriends.has("uid"))   
                            friends.setFriendID(JOFriends.getString("uid"));
                         else 
                            friends.setFriendID(null);
                        

                        // SET FRIENDS NAME
                        if (JOFriends.has("name"))  
                            friends.setFriendName(JOFriends.getString("name"));
                         else 
                            friends.setFriendName(null);
                        

                        // SET FRIENDS PROFILE PICTURE
                        if (JOFriends.has("pic_big"))   
                            friends.setFriendProfile(JOFriends.getString("pic_big"));
                         else 
                            friends.setFriendProfile(null);
                        

                        arrFriends.add(friends);

                    
                

             catch (Exception e) 
                e.printStackTrace();
            

            return null;
        

        @Override
        protected void onPostExecute(Void result) 

            // SET THE ADAPTER TO THE GRIDVIEW
            gridOfFriends.setAdapter(adapter);

            // HIDE THE BOTTOM PROGRESS BAR (SPINNER) AFTER LOADING THE FRIENDS LIST
            linlaProgressBar.setVisibility(View.GONE);
        

    

    private TextWatcher filterTextWatcher = new TextWatcher() 

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) 

            adapter.getFilter().filter(s.toString().toLowerCase());
            adapter.notifyDataSetChanged();
        

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) 

        

        @Override
        public void afterTextChanged(Editable s) 

        
    ;

ArrayListgetFriends.java 类:

public class getFriends 

    String friendID;
    String friendName;
    String friendProfile;

    // SET FRIENDS ID
    public void setFriendID(String friendID) 
        this.friendID = friendID;
    

    // GET FRIENDS ID
    public String getFriendID() 
        return friendID;
    

    // SET FRIENDS NAME
    public void setFriendName(String friendName) 
        this.friendName = friendName;
    

    // GET FRIENDS NAME
    public String getFriendName() 
        return friendName;
    

    // SET FRIENDS PROFILE
    public void setFriendProfile(String friendProfile) 
        this.friendProfile = friendProfile;
    

    // GET FRIENDS PROFILE
    public String getFriendProfile() 
        return friendProfile;
    

最后是适配器类 (FriendsAdapter.java)

public class FriendsAdapter extends BaseAdapter implements Filterable 

    ProgressDialog dialog;

    Activity activity;

    LayoutInflater inflater = null;
    ImageLoader imageLoader;

    ArrayList<getFriends> arrayFriends;
    List<getFriends> mOriginalNames;

    FriendsAdapter(Activity a, ArrayList<getFriends> arrFriends) 

        activity = a;

        arrayFriends = arrFriends;

        inflater = (LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        imageLoader = new ImageLoader(activity.getApplicationContext());
    

    public int getCount() 
        return arrayFriends.size();
    

    public Object getItem(int position) 
        return arrayFriends.get(position);
    

    public long getItemId(int position) 
        return position;
    

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

    public View getView(final int position, View convertView, ViewGroup parent) 
        View vi = convertView;
        if (convertView == null)
            vi = inflater.inflate(R.layout.friends_grid_items, null);

        ImageView imgProfilePicture = (ImageView) vi.findViewById(R.id.imgProfilePicture);
        TextView txtUserName = (TextView) vi.findViewById(R.id.txtUserName);
        FrameLayout mainContainer = (FrameLayout) vi.findViewById(R.id.mainContainer);


        txtUserName.setText(arrayFriends.get(position).getFriendName());

        if (arrayFriends.get(position).getFriendProfile() != null) 
            imageLoader.DisplayImage(arrayFriends.get(position).getFriendProfile(),imgProfilePicture);
         else if (arrayFriends.get(position).getFriendProfile() == null) 
            imgProfilePicture.setVisibility(View.GONE);
        

        mainContainer.setOnClickListener(new View.OnClickListener() 

            @Override
            public void onClick(View v) 
                Intent showFriendsProfile = new Intent(activity.getApplicationContext(), UserProfileNew.class);
                showFriendsProfile.putExtra("USER_ID", arrayFriends.get(position).getFriendID());
                showFriendsProfile.putExtra("NAME", arrayFriends.get(position).getFriendName());
                activity.startActivity(showFriendsProfile);
            
        );

        return vi;
    

    @Override
    public Filter getFilter() 

        Filter filter = new Filter() 

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence constraint,
                    FilterResults results) 

                arrayFriends = (ArrayList<getFriends>) results.values;
                notifyDataSetChanged();
            

            @Override
            protected FilterResults performFiltering(CharSequence constraint) 

                FilterResults results = new FilterResults();
                ArrayList<getFriends> FilteredArrayNames = new ArrayList<getFriends>();

                if (mOriginalNames == null) 
                    mOriginalNames = new ArrayList<getFriends>(arrayFriends);
                
                if (constraint == null || constraint.length() == 0) 
                    results.count = mOriginalNames.size();
                    results.values = mOriginalNames;
                 else 
                    constraint = constraint.toString().toLowerCase();
                    for (int i = 0; i < mOriginalNames.size(); i++) 
                        getFriends dataNames = mOriginalNames.get(i);
                        if (dataNames.getFriendName().toLowerCase()
                                .contains(constraint.toString())) 
                            FilteredArrayNames.add(dataNames);
                        
                    

                    results.count = FilteredArrayNames.size();
                    // System.out.println(results.count);

                    results.values = FilteredArrayNames;
                    // Log.e("VALUES", results.values.toString());
                

                return results;
            
        ;

        return filter;
    

您可以在此处使用该概念并替换您的 ListView。我已经在其他地方将它用于 ListView 并且可以正常工作。不幸的是,我不能在公共论坛上泄露该代码。希望这对您有所帮助。同样,毫无疑问,这是一篇很长的帖子,但我相信这是必要的。

【讨论】:

@Newbie_to_android:尝试在 getFilter() 方法中替换上面代码中的位。不过,您可能必须对代码进行一些更改以适应我的代码中的概念。例如,您将使用另一个列表(检查 mOriginalName List)来保存过滤后的数据,然后调用 notifyDataSetChanged() 以显示在您的列表中。 我正在为我的 ArrayList 使用一个名为 getFriends 的自定义类。就像我说的,你必须做一些替换。您可以将您的主要活动代码添加到帖子中吗?我认为这会让事情变得更容易。 在 getFilter() 方法中,尝试将 getFriends 替换为“String” 是的,它工作正常。但是,如果我搜索带有a 字母的任何内容,它将包含字母a 的项目我们不能为这些字母匹配仅起始字母吗? 我也很高兴能在您的指导下处理Filterable 界面。谢谢你。而且,还有一件事,.equlsIgnoreCase 不起作用。如果字符串也在那里,它将不会显示任何内容。但是,我很高兴.contains 对我来说已经足够了。还是谢谢你。【参考方案2】:

检查这个List View with easy searching in Android

【讨论】:

这就是我要寻找的。非常感谢。会尝试让您知道。 感谢您的帮助。我得到了答案。【参考方案3】:

您可以将自动完成器与您的 Editext 一起使用,并使用它来更新您的列表适配器以及 see

<yourEditText>.addTextChangedListener(new TextWatcher() 

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) 
            <requery/filter your adapter then set it to your listview>
            

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) 
                // TODO Auto-generated method stub

            

            @Override
            public void afterTextChanged(Editable s) 
                // TODO Auto-generated method stub

            
        );

【讨论】:

感谢您的帮助。我得到了答案。

以上是关于列表视图的搜索功能的主要内容,如果未能解决你的问题,请参考以下文章

我正在尝试在选项卡活动中实现可搜索的列表视图

django:使用搜索自动生成列表视图(管理员风格)

Unity实用小工具或脚本——可折叠伸缩的多级列表二(带搜索功能)

Unity实用小工具或脚本——可折叠伸缩的多级列表二(带搜索功能)

获取列表视图的arraylist的原始位置

Flutter - 实现 listView 搜索功能