zoukankan      html  css  js  c++  java
  • 详细解读Android中的搜索框(一)—— 简单小例子

    这次开的是一个讲解SearchView的栏目,第一篇主要是给一个小例子,让大家对这个搜索视图有一个了解,之后再分布细化来说。

    目标:

    我们先来定个目标,我们通过搜索框来输入要搜索的联系人名字,输入的时候下面的listview就展现出候选的人。

    思路:

    1.要得到联系人数据,就需要有访问联系人的权限

    2.必须通过ContentResolver来得到操作联系人名单的指针

    3.每次输入一个字的时候就应该触发一次搜索,并且能将搜索的结果展示出来

    4.既然要进行搜索,那么就要用到SQL语句

    实现:

    1. 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"
        tools:context="${relativePackage}.${activityClass}" >
    
        <SearchView
            android:id="@+id/search"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#F0F0F0F0" >
        </SearchView>
    
        <ListView
            android:id="@android:id/list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:transcriptMode="normal"
            android:layout_below="@id/search"/>
    
    </RelativeLayout>

    我们看到listview放在了searchview的下面,这个searchview在高版本api中才提供,如果是想要兼容低版本的话,需要用support包中的控件,使用方式完全一致,但个人觉得在2015年了,没必要兼容2.x版本的系统了。

    2. 在manifest(清单)中对activity进行设定

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.kale.searchview"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-permission android:name="android.permission.READ_CONTACTS"/>  
        
        <uses-sdk
            android:minSdkVersion="11"
            android:targetSdkVersion="18" />
    
        <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" 
                android:windowSoftInputMode = "adjustPan">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
                <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>

    主要的代码片段:

        <activity
                android:windowSoftInputMode = "adjustPan">
           ……
                <intent-filter>  
                    <action android:name="android.intent.action.SEARCH" />  
                </intent-filter>  
      
                <meta-data  
                    android:name="android.app.searchable"  
                    android:resource="@xml/searchable" />  
            </activity>

    这里设定了activity的输入法模式,用的是不挤压窗口的模式,这个在之后的文章中会说道,现在只需要知道这个模式会让输入法弹出时,不会挤压activity窗体就行。然后我们定义了过滤器,写了一个action,这是用search必须的。最后是写一个xml文件,用来描述searchview的行为。

    3. 配置搜索模式

    res/xml/searchable.xml

    <?xml version="1.0" encoding="utf-8"?>
    <!-- 配置搜索模式 -->
    <searchable xmlns:android="http://schemas.android.com/apk/res/android"
        android:label="contactsList"
        android:hint="@string/search_hint"
        android:searchMode="queryRewriteFromText" />

    4.java代码

    4.1 产生可以操作联系人对象的指针,并且通过它构建listview的适配器

    这段代码先产生指针对象,然后初始化listview的适配器,这样listview默认就能展示联系人的名字数据了。然后我优化了操作,让listview在滑动时隐藏软键盘,这个代码写的比较简陋,在实际运用时需要多多优化。不错意思已经达到了。

    // 得到联系人名单的指针
            mCursor = getContentResolver().query(RawContacts.CONTENT_URI, PROJECTION, null, null, null);
            // 通过传入mCursor,将联系人名字放入listView中。
            mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, mCursor,
                    new String[] { RawContacts.DISPLAY_NAME_PRIMARY }, new int[] { android.R.id.text1 }, 0);
    
            mListView = (ListView) findViewById(android.R.id.list);
            mListView.setAdapter(mAdapter);
            mListView.setOnScrollListener(new OnScrollListener() {
    
                @Override
                public void onScrollStateChanged(AbsListView view, int scrollState) {
                    // TODO 自动生成的方法存根
                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    if (imm != null) {
                        imm.hideSoftInputFromWindow(mListView.getWindowToken(), 0); // 输入法如果是显示状态,那么就隐藏输入法
                    }
                }
    
                @Override
                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                    
                }
            });

    4.2 找到searchView对象,并进行设定

    这里的设定就是设定一些焦点啥的,没啥可说的。具体在使用时自行调整吧

      mSearchView = (SearchView) findViewById(R.id.search);
            mSearchView.setIconifiedByDefault(true);
            mSearchView.onActionViewExpanded();// 写上此句后searchView初始是可以点击输入的状态,如果不写,那么就需要点击下放大镜,才能出现输入框
            mSearchView.setFocusable(false);// 是否获取焦点
            mSearchView.clearFocus();
            // mSearchView.setIconifiedByDefault(true);

    4.3 给searchview绑定监听器(重要)

    searchview有一个重要的监听器,它可以在searchView中文字改变或者是用户提交搜索时触发。

    mSearchView.setOnQueryTextListener(new OnQueryTextListener() {
    
                private String TAG = getClass().getSimpleName();
    
                /*
                 * 在输入时触发的方法,当字符真正显示到searchView中才触发,像是拼音,在舒服法组词的时候不会触发
                 * 
                 * @param queryText
                 * 
                 * @return false if the SearchView should perform the default action
                 * of showing any suggestions if available, true if the action was
                 * handled by the listener.
                 */
                @Override
                public boolean onQueryTextChange(String queryText) {
                    Log.d(TAG, "onQueryTextChange = " + queryText);
    
                   // TODO:当searchview中文字改变时进行的操作
                    return true;
                }
    
                /*
                 * 输入完成后,提交时触发的方法,一般情况是点击输入法中的搜索按钮才会触发。表示现在正式提交了
                 * 
                 * @param queryText
                 * 
                 * @return true to indicate that it has handled the submit request.
                 * Otherwise return false to let the SearchView handle the
                 * submission by launching any associated intent.
                 */
                @Override
                public boolean onQueryTextSubmit(String queryText) {
                    Log.d(TAG, "onQueryTextSubmit = " + queryText);
    
                    // TODO:当用户提交搜索结果时,需要进行的操作return true;
                }
            });

    4.4 在监听器中进行我们需要的处理

    我们现在可以针对不同的事件进行不同的处理了,在用户输入时要不断的查询联系人,这个查询的时间很快,所以不用做异步。查询到结果后显示到listview中,也就是跟新下适配器的数据。当用户提交后,隐藏软键盘,开始搜索。之后的操作就没去做了^_^

    mSearchView.setOnQueryTextListener(new OnQueryTextListener() {
    
                private String TAG = getClass().getSimpleName();
    
                /*
                 * 在输入时触发的方法,当字符真正显示到searchView中才触发,像是拼音,在舒服法组词的时候不会触发
                 * 
                 * @param queryText
                 * 
                 * @return false if the SearchView should perform the default action
                 * of showing any suggestions if available, true if the action was
                 * handled by the listener.
                 */
                @Override
                public boolean onQueryTextChange(String queryText) {
                    Log.d(TAG, "onQueryTextChange = " + queryText);
    
                    String selection = RawContacts.DISPLAY_NAME_PRIMARY + " LIKE '%" + queryText + "%' " + " OR "
                            + RawContacts.SORT_KEY_PRIMARY + " LIKE '%" + queryText + "%' ";
                    // String[] selectionArg = { queryText };
                    mCursor = getContentResolver().query(RawContacts.CONTENT_URI, PROJECTION, selection, null, null);
                    mAdapter.swapCursor(mCursor); // 交换指针,展示新的数据
                    return true;
                }
    
                /*
                 * 输入完成后,提交时触发的方法,一般情况是点击输入法中的搜索按钮才会触发。表示现在正式提交了
                 * 
                 * @param queryText
                 * 
                 * @return true to indicate that it has handled the submit request.
                 * Otherwise return false to let the SearchView handle the
                 * submission by launching any associated intent.
                 */
                @Override
                public boolean onQueryTextSubmit(String queryText) {
                    Log.d(TAG, "onQueryTextSubmit = " + queryText);
    
                    if (mSearchView != null) {
                        // 得到输入管理对象
                        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                        if (imm != null) {
                            // 这将让键盘在所有的情况下都被隐藏,但是一般我们在点击搜索按钮后,输入法都会乖乖的自动隐藏的。
                            imm.hideSoftInputFromWindow(mSearchView.getWindowToken(), 0); // 输入法如果是显示状态,那么就隐藏输入法
                        }
                        mSearchView.clearFocus(); // 不获取焦点
                    }
                    return true;
                }
            });

    源码下载:http://download.csdn.net/detail/shark0017/8362209

    参考自:http://blog.csdn.net/lihenair/article/details/27527827

  • 相关阅读:
    HDU 1124 Factorial(简单数论)
    29.QT主窗口加widget
    28.开始画面和异形窗口
    27.Qt时钟
    26.QT颜色与布局
    25.QT进度条
    146.正则表达式
    24.qint64转QString 以及获取文件属性
    23.QFile遍历
    22.监视文件
  • 原文地址:https://www.cnblogs.com/tianzhijiexian/p/4224732.html
Copyright © 2011-2022 走看看