專案需求討論-標題欄上的搜尋功能

青蛙要fly發表於2017-06-06

今天講的就是一個很簡單的具體開始時候遇到的需求,在標題欄中實現搜尋功能,而且美工要求需要實現下面GIF圖的效果,我就實現了下,可能不是最好的,有哪裡可以更方便請大家指出。正好仔細的講解了下SearchView和Toolbar。希望大家看看我哪裡是不是講錯了。哈哈。

專案需求討論-標題欄上的搜尋功能

1.先拋開搜尋功能,我們看如何單純實現下圖的標題欄的介面:

專案需求討論-標題欄上的搜尋功能
標題欄

因為我平常專案中的標題欄使用的是Toolbar。當然大家在這個需求上面,用個其他型別的ViewGroup也是一樣的。大家知道,Toolbar也是繼承ViewGroup的,

public class Toolbar extends ViewGroup {

}複製程式碼

所以使用方法也是和一般的ViewGroup一樣。

<android.support.v7.widget.Toolbar
        android:id="@+id/common_toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary">

    <TextView
        android:id="@+id/tool_bar_choose"
        style="@style/TabTitleStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="待審批" />

    <ImageView
        android:id="@+id/start_search"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:src="@drawable/search_icon" />    


</android.support.v7.widget.Toolbar>複製程式碼

沒錯,我們就是直接在Toolbar中放置子元素,為了把標題TextView放置在正中間,使用android:layout_gravity="center",然後因為搜尋按鈕是在右邊,對ImageView使用android:layout_gravity="right"

這時候有人會問了,那左邊的返回按鈕呢。怎麼沒寫在佈局中。
因為返回按鈕有二種方式來進行處理顯示,我們分別來說明:

  1. 在Activity中寫上程式碼:

    Toolbar toolbar = (Toolbar) findViewById(R.id.common_toolbar);
    if(toolbar != null){
     toolbar.setNavigationIcon(R.drawable.toolbar_back_icon);
     toolbar.setNavigationOnClickListener(v -> finish());
    }複製程式碼

    在Activity中獲取到了Toolbar的物件,然後設定Navigation圖示及Navigation的點選事件即可。

  2. 同樣在是在Activity中寫上程式碼:

    //先讓返回箭頭出現
    Toolbar toolbar = (Toolbar) findViewById(R.id.common_toolbar);
    setSupportActionBar(toolbar);
    ActionBar bar = getSupportActionBar();
    bar.setDisplayHomeAsUpEnabled(true);複製程式碼

    這時候出現的返回箭頭是系統原生的,是這樣的:

    專案需求討論-標題欄上的搜尋功能

    跟我們原來的需求的返回圖示不同,所以我們也有二種方法來進行修改:

    1. 在我們引入的Appbar的theme中新增一個Item,將設計師給我們的圖放進去
      <item name="android:homeAsUpIndicator">@drawable/web_detail_back</item>
    2. 在我們的Toolbar中新增屬性
      app:navigationIcon="@drawable/web_detail_back"
      記得要在根佈局中新增xmlns:app="http://schemas.android.com/apk/res-auto"

我們新增了返回圖示後,我們就需要給他點選事件,這裡也有二種實現方式:

  1. 覆寫onOptionsItemSelected方法:
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                break;
        }
        return true;
    }複製程式碼
  2. 在AndroidManifest.xml中對當前Activity中新增,宣告該Activity的父Activity是哪個,然後按返回的時候就跳到那個父Activity中。
    <activity android:name=".modules.view.activity.ApproveActivity">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".modules.view.activity.LoginActivity" />
    </activity>複製程式碼

2.實現搜尋框功能

我們上面說過Toolbar實際上就是一個ViewGroup,所以我就想到可以讓Toolbar中包含一個FragmentLayout,然後在這個上面的標題的標題及搜尋圖示按鈕上面,覆蓋了一層我們要的SearchView,然後預設是隱藏的,點選搜尋圖示按鈕後讓SearchView顯示就可以了。其實的確很簡單。

我們的佈局程式碼就變成了:(ps:因為我用的是百分比佈局,所以Framelayout變為了PercentFrameLayout,LinearLayout變為了PercentLinearLayout)

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@color/colorPrimary">

    <android.support.percent.PercentFrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">


        <TextView
            android:id="@+id/tool_bar_choose"
            style="@style/TabTitleStyle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:drawablePadding="10dp"
            android:drawableRight="@drawable/more_unfold"
            android:text="待審批" />

        <ImageView
            android:visibility="gone"
            android:id="@+id/start_search"
            android:layout_width="40dp"
            android:layout_height="match_parent"
            android:layout_gravity="right"
            android:scaleType="center"
            android:src="@drawable/search_icon" />

        <com.chint.pay.widget.PercentLinearLayout
            android:id="@+id/search_group"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:visibility="gone"
            >

            <android.support.v7.widget.SearchView
                android:id="@+id/search_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/search_view_background"
                app:layout_heightPercent="70%"
                android:queryHint="請輸入姓名或者手機號"
                app:layout_widthPercent="85%" />

            <TextView
                android:id="@+id/cancel_search"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center"
                android:text="取消"
                android:textColor="@android:color/white"
                android:textSize="14sp" />

        </com.chint.pay.widget.PercentLinearLayout>
    </android.support.percent.PercentFrameLayout>

</android.support.v7.widget.Toolbar>複製程式碼

好的,看佈局程式碼,就知道在第一步中的標題欄的佈局的上面,覆蓋了一層橫向佈局,用來顯示SearchView和取消按鈕,該介面預設是隱藏的,只有當按了搜尋圖示按鈕,再讓這個橫向佈局顯示,蓋在上面,(當然同時也可以讓原來的標題和搜尋圖示按鈕隱藏)。

專案需求討論-標題欄上的搜尋功能


這本來是我們想要的效果,但是當我執行了程式碼後,我看到生成的介面是這樣的:

專案需求討論-標題欄上的搜尋功能

原來,Toolbar自帶的左邊的按鈕,是預設先佔了它的位置,然後剩下的面積再是放我們自己定義的FrameLayout,所以我們的FrameLayout總體就先往右邊偏移了。這時候又因為我們的標題是FrameLayout的中間,所以標題也整體往右邊便宜了。那豈不是都不能實現了??該怎麼處理呢??答案當然是有方法處理。(這B裝的我好累。)


我們可以直接在ToolBar中,自己在左邊新增一個ImageView,然後圖片設為返回的圖示,然後給這個ImageView新增點選事件就OK了。所以我們在上面的佈局程式碼中的PercentFrameLayout中再新增一個ImageView元素:

<android.support.percent.PercentFrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/tool_back"
        android:layout_width="30dp"
        android:scaleType="center"
        android:layout_marginLeft="-5dp"
        android:layout_height="match_parent"
        android:src="@drawable/toolbar_back_icon"
        android:layout_gravity="center_vertical"
        />

    .....
    .....
    .....
    .....

</android.support.percent.PercentFrameLayout>複製程式碼

這下我們的佈局整個都實現了。只要對相應的按鈕實現點選事件,控制相關控制元件的顯示及隱藏即可。


3.SearchView的顯示及鍵盤彈出

SearchView基礎我就不重複了,先附上其他大神寫的SearchView的相關基礎知識:
搜尋框(SearchView)的功能與用法
詳細解讀Android中的搜尋框(三)—— SearchView

我們看到,在GIF圖中,當我點選了搜尋圖示按鈕的時候,SearchView 的Visible設為顯示狀態,同時鍵盤出現,然後當我點選取消按鈕的時候,SearchView 的Visible設為隱藏狀態,同時鍵盤消失,SearView的顯示和隱藏這個大家都只要,只要呼叫SearchView.setVisibility方法即可。那鍵盤呢,其實不用特意去設定鍵盤的彈出及隱藏。
我這邊是使用了SearchView的onActionViewCollapsed及onActionViewExpanded方法

onActionViewExpanded方法:
初始SearchView是否已經是展開的狀態
寫上此句後searchView初始展開的,也就是是可以點選輸入的狀態,如果不寫,那麼就需要點選下放大鏡,才能展開出現輸入框。
同理,onActionViewCollapsed正好相反。

因為設定他們的展開與不展開,正好會自動呼叫鍵盤的顯示和隱藏。所以我們這裡正好呼叫這二個方法:

switch (view.getId()) {
    case R.id.start_search:
        searchGroup.setVisibility(View.VISIBLE);
        startSearch.setVisibility(View.GONE);
        searchView.onActionViewExpanded();
        break;

    case R.id.cancel_search:
        searchGroup.setVisibility(View.GONE);
        startSearch.setVisibility(View.VISIBLE);
        searchView.onActionViewCollapsed();
        break;
}複製程式碼

這裡還要對SearchView 呼叫:

searchView.setIconifiedByDefault(false);複製程式碼

專案需求討論-標題欄上的搜尋功能
未呼叫setIconifiedByDefault(false)

專案需求討論-標題欄上的搜尋功能
呼叫setIconifiedByDefault(false)

從上面圖片可以看到,設為false和true的區別在於輸入的游標的顯示位置,如果為true,設游標在放大鏡的前面,而且,當你輸入文字後,放大鏡也會不見,設為false,則游標在放大鏡後面,輸入文字,放大鏡也不會消失。

同時記得對SearchView設定搜尋事件:

searchView.setOnQueryTextListener(this);複製程式碼

Activity 實現SearchView.OnQueryTextListener介面,覆寫相關方法:

@Override
public boolean onQueryTextSubmit(String query) {
    Toast.makeText(aty, "你搜尋了:" + query, Toast.LENGTH_SHORT).show();
    return false;
}

@Override
public boolean onQueryTextChange(String newText) {
    return false;
}複製程式碼

這樣就結束了。哈哈,希望大家不要亂噴我。有錯請留言。O(∩_∩)O


補充1:

感謝大家下面留言指出錯誤,說是標題並沒有居中,我用AS的佈局工具看了,沒有居中的原因如下圖所示:

專案需求討論-標題欄上的搜尋功能

Toolbar的自己本身左邊padding的一部分值,所以我們只需要給Toolbar加上
app:contentInsetStart="0dp"屬性即可,加上該屬性後,我們可以看到如下的佈局了。

專案需求討論-標題欄上的搜尋功能

相關文章