眾人登山圍攏教師,見他異樣神情皆不解。紛紛問道:“你看什么?渾沌干啥?”教師答:“下棋?!薄吧钌綍缫埃c誰下棋?”教師沉默不語。良久,沉甸甸道出一字:“天!”
俗人淺見,喳喳追問:“贏了還是輸了?”
教師細(xì)細(xì)數(shù)目。數(shù)至右下角,見到那個決定勝負(fù)的劫。渾沌長跪于地,充當(dāng)一枚黑子,恰恰劫勝!教師崇敬渾沌精神,激情澎湃。他雙手握拳沖天高舉,喊得山野震蕩,林木悚然——
“勝天半子!”
最近很喜歡“勝天半子”,故引用原文結(jié)尾作為本篇開頭,也勉勵自己。上周的安卓開發(fā)遇到在ActionBar上添加搜索欄的問題,然而現(xiàn)在Toolbar大行其道,導(dǎo)致這方面的資源比較少,所以我花了很大的力氣慢慢調(diào)教。以下是自己的一點(diǎn)心得。
ActionBar是比較老的組件,不能支持SearchView,所以我選擇了EditView作為我搜索欄的Search Bar。因?yàn)橐恍┥聿挥杉旱脑蛑荒苁褂肁ctionBar的同學(xué)們,一定是能感同身受我只能選擇EditView的糾結(jié)的 :( 。作為一個完整的搜索欄,Search Bar里的清空按鈕和整個搜索欄的推出按鈕也是必不可少的。以下是我用純JAVA代碼寫的整個搜索欄的樣子:
整個搜索欄放在一個LinearLayout里
//ADD A SEARCH HEADER INSTEAD OF THE OLD HEADER, AFTER CLICKING SEARCH BUTTON
LinearLayout searchHeader = new LinearLayout(context);
searchHeader.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
searchHeader.setOrientation(LinearLayout.HORIZONTAL);
searchHeader.setBackgroundColor(Color.BLACK);
searchHeader.setVisibility(View.GONE);
在這之前我有個搜索圖標(biāo)設(shè)置了點(diǎn)擊跳轉(zhuǎn)搜索欄的功能,很簡單我就不放出來了。這里是整個搜索欄的框架,之所以用LinearLayout是因?yàn)樗梢宰詣訖M向排列,比RelativeLayout省去很多布置的代碼。
然后就是EditView:
Search Bar
//ADD A SEARCH BAR IN SEARCH HEADER, WHICH SHOWS AFTER CLICKING SEARCH BUTTON
EditText search = new EditText(mainActivity);
search.setInputType(InputType.TYPE_CLASS_TEXT);
search.setSingleLine();
search.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
search.setHint("Search");
//ADD A SEARCH ICON INSIDE THE SEARCH BAR
Drawable searchIcon = context.getResources().getDrawable(R.drawable.places_ic_search);
search.setCompoundDrawablesWithIntrinsicBounds(searchIcon, null, null, null);
LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, 8);// Create lp for setting up margins
lp2.setMargins(50, 20, 0, 20);
search.setLayoutParams(lp2);
search.setPadding(5, 5, 5, 5);
search.setBackgroundColor(Color.WHITE);
search.setTextColor(Color.BLACK);
這里
search.setSingleLine();
與
search.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
是這個搜索欄能實(shí)現(xiàn)功能的關(guān)鍵。其他的都是一下外觀上的東西。比如那個Drawable就是一個放大鏡的圖標(biāo),放到搜索欄的最左邊。接下來是里面的Clear按鈕,負(fù)責(zé)清楚文本和收回鍵盤:
Close Button
//ADD A CLOSE BUTTON IN SEARCH HEADER, WHICH SHOWS AFTER CLICKING SEARCH BUTTON
ImageButton closeButton = new ImageButton(mainActivity);
closeButton.setBackgroundColor(Color.WHITE);
closeButton.setColorFilter(Color.GRAY);
closeButton.setScaleType(ImageView.ScaleType.FIT_CENTER);
closeButton.setImageResource(R.drawable.delete_filled);
LinearLayout.LayoutParams lp1 = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, 1);// Create lp for setting up margins
lp1.setMargins(0, 20, 0, 20);
closeButton.setLayoutParams(lp1);
closeButton.setVisibility(View.GONE);
這里R.drawable.delete_filled是我自定義的圖標(biāo),大家可以使用ic_delete這種自帶圖標(biāo)。最后是關(guān)掉整個搜索欄的Cancel按鈕:
Cancel Button
//ADD A CANCEL BUTTON IN SEARCH HEADER, WHICH SHOWS AFTER CLICKING SEARCH BUTTON
Button cancelButton = new Button(mainActivity);
String cancelText = "Cancel";
SpannableString content = new SpannableString(cancelText);
content.setSpan(new UnderlineSpan(), 0, cancelText.length(), 0);
cancelButton.setText(content);
cancelButton.setTypeface(LVATabUtilities.latoRegular);
cancelButton.setLayoutParams(new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, 2));
cancelButton.setPadding(5, 5, 5, 5);
cancelButton.setTextColor(Color.parseColor(LVATabUtilities.getAppProperty("HighlightHEX")));
cancelButton.setBackgroundColor(Color.BLACK);`
為了做得跟IOS像一點(diǎn),我在文本上加了下劃線。
##最后是把他們都放到LinearLayout里面去
`searchHeader.addView(search);
searchHeader.addView(closeButton);
searchHeader.addView(cancelButton);
這里還有一點(diǎn)是,因?yàn)槲矣玫腖inearLayout,所以可以按權(quán)重分配各部分的大小,所以上述代碼里SearchBar : CloseButton : CancelButton = 8 : 1 : 2。 他們的高度必須是Match_Parent, 寬度既不是Match_Parent也不是Wrap_Content, 而是0。這樣做是為了固定他們的大小,而不會因?yàn)槲谋具^長導(dǎo)致整個搜索欄變形。這樣我們的搜索欄外觀就完成了,然而萬里長征也才走完了第一步。
接下來是實(shí)現(xiàn)這個搜索欄的功能。我們首先從簡單的開始。
CloseButton的功能是清空文本和收回鍵盤
//ADD CLOSE BUTTON'S FUNCTIONALITY
closeButton.setVisibility(View.VISIBLE);
closeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
search.setText("");
closeButton.setVisibility(View.GONE);
hideKeyboard();
}
});
CancelButton的功能是收回搜索欄和強(qiáng)制退出鍵盤
public static void clickOnCancelButton(final Button button, final ImageButton imageButton, final LinearLayout linearLayout){
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
imageButton.setVisibility(View.VISIBLE);
linearLayout.setVisibility(View.GONE);
removeFragmentFromCurrentViewPagerTab("SearchView");
hideSoftKeyboard(button);
}
});
}
上面的removeFragment方法是把我當(dāng)年搜索所添加的Fragment再關(guān)掉,以此達(dá)到“關(guān)掉搜索界面” :)。怎么remove我就不貼代碼了,因?yàn)槭俏覀兙唧w的app功能,只要做到這個思想就行了。
這個是自己寫的強(qiáng)制退出鍵盤的方法,和上面CloseButton不同,用系統(tǒng)自帶的hideKeyBoard()不能在Cancel時使用。
public static void hideSoftKeyboard(Button button) {
InputMethodManager imm = (InputMethodManager) mainActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(button.getWindowToken(), 0);
}
在某個位置調(diào)用方法實(shí)現(xiàn)功能
//ADD A CLICKLISTENER FOR CANCEL BUTTON, WHICH RETURNS BACK TO NORMAL SCREEM
clickOnCancelButton(cancelButton, searchButton, searchHeader);
最后就是數(shù)據(jù)的處理,這需要根據(jù)自己的情況量身定做?;镜乃悸肪褪钦业阶约哼@個Fragment的Adapter,在里面創(chuàng)建一個方法。然后把數(shù)據(jù)在里面處理了在調(diào)用到展示的Fragment頁面中來。Adapter里的方法我就不放出來了,也沒有參考價值。最后我們需要一個TextWacther監(jiān)聽EditText的所有動作,以下是它的代碼:
在EditText中加入TextWatcher
//ADD A TEXTCHANGEDLISTENER FOR SEARCH BAR
TextWatcher textWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
//NOTHING
}
@Override
public void onTextChanged(final CharSequence s, int start, int before, int count) {
//這里定義SearchView和SearchViewAdapter
//ADD CLOSE BUTTON'S FUNCTIONALITY
closeButton.setVisibility(View.VISIBLE);
closeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
search.setText("");
closeButton.setVisibility(View.GONE);
hideKeyboard();
}
});
//ADD SEARCH'S FUNCTIONALITY
search.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
//這行用定義好的SearchView和SearchViewAdapter寫處理數(shù)據(jù)的代碼
detachAndAttachCurrentFragment();
hideKeyboard();
return true;
}
return false;
}
});
//REPLACE CURRENT FRAGMENT
removeFragmentFromCurrentViewPagerTab();
}
@Override
public void afterTextChanged(Editable s) {
//NOTHING
}
};
search.addTextChangedListener(textWatcher);
這樣大體上我們就大功告成啦。這里detachAndAttachCurrentFragment()和removeFragmentFromCurrentViewPagerTab()是我自定義的方法。一個是用來刷新頁面,一個是移除現(xiàn)在的頁面(因?yàn)槲覀円砑铀阉鞯玫降捻撁妫?/p>