今天講的就是一個很簡單的具體開始時候遇到的需求,在標題欄中實現搜尋功能,而且美工要求需要實現下面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"
。
這時候有人會問了,那左邊的返回按鈕呢。怎麼沒寫在佈局中。
因為返回按鈕有二種方式來進行處理顯示,我們分別來說明:
在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的點選事件即可。
同樣在是在Activity中寫上程式碼:
//先讓返回箭頭出現 Toolbar toolbar = (Toolbar) findViewById(R.id.common_toolbar); setSupportActionBar(toolbar); ActionBar bar = getSupportActionBar(); bar.setDisplayHomeAsUpEnabled(true);複製程式碼
這時候出現的返回箭頭是系統原生的,是這樣的:
跟我們原來的需求的返回圖示不同,所以我們也有二種方法來進行修改:- 在我們引入的Appbar的theme中新增一個Item,將設計師給我們的圖放進去
<item name="android:homeAsUpIndicator">@drawable/web_detail_back</item>
- 在我們的Toolbar中新增屬性
app:navigationIcon="@drawable/web_detail_back"
記得要在根佈局中新增xmlns:app="http://schemas.android.com/apk/res-auto"
- 在我們引入的Appbar的theme中新增一個Item,將設計師給我們的圖放進去
我們新增了返回圖示後,我們就需要給他點選事件,這裡也有二種實現方式:
- 覆寫
onOptionsItemSelected
方法:@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: finish(); break; } return true; }複製程式碼
- 在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);複製程式碼
從上面圖片可以看到,設為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"
屬性即可,加上該屬性後,我們可以看到如下的佈局了。