Android——輕松打造搜索頁(yè)

前言

項(xiàng)目需要艾少,要求自定義一個(gè)searchview卡乾,其實(shí)Android自帶的就有這個(gè)控件,而且做得很好缚够,還有一些是通過修改樣式來(lái)打造说订,筆者更喜歡把它抽出來(lái)成為一個(gè)控件,這樣在以后的使用中會(huì)方便很多潮瓶,于是在網(wǎng)上找了找資料陶冷,綜合各大神的代碼,給出自己的解決方案毯辅。有不準(zhǔn)確的地方埂伦,歡迎各位指出,筆者加以改正思恐,共同學(xué)習(xí)沾谜。
上效果圖:

d18fbe8a-cdae-4cf3-a5de-91652e50e700.gif

1、這個(gè)搜索框控件的布局并不是很復(fù)雜胀莹,左上方那個(gè)搜索的小圖片是個(gè)ImageView基跑,中間是EditText,最右邊的小垃圾桶是個(gè)ImageView描焰,只是在未輸入搜索內(nèi)容的時(shí)候visibility為gone媳否,而搜索框下方是個(gè)gridview,gridview放的是搜索的熱詞荆秦,顯示搜索內(nèi)容的是一個(gè)webview篱竭,gridview是蓋在webview上面的,之前有小伙伴問我怎么蓋在另外一個(gè)控件上步绸,原理很簡(jiǎn)單掺逼,把gridview的xml布局代碼寫在webview的xml布局代碼下方就行。瓤介。吕喘。(很簡(jiǎn)單但是很有效)
2赘那、這種由幾個(gè)控件組成的自定義控件首先要做的是寫布局文件,布局文件沒什么好說(shuō)的氯质,上代碼:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

 android:layout_width="match_parent"

 android:layout_height="match_parent"

 >

 <LinearLayout

 android:orientation="horizontal"

 android:layout_width="match_parent"

 android:id="@+id/search_area"

 android:background="@drawable/rect_gray"

 android:layout_height="wrap_content">

 <ImageView

 android:layout_marginLeft="10dp"

 android:src="@android:drawable/ic_menu_search"

 android:id="@+id/search_iv_search"

 android:layout_gravity="left|center_vertical"

 android:layout_width="wrap_content"

 android:layout_height="wrap_content"/>

 <EditText

 android:id="@+id/search_et_input"

 android:layout_gravity="center_vertical"

 android:layout_margin="10dp"

 android:layout_width="0dp"

 android:layout_weight="1"

 android:layout_height="wrap_content"

 android:textSize="16sp"

 android:background="@null"

 android:imeOptions="actionSearch"

 android:inputType="text"

 android:textCursorDrawable="@null"

 android:hint="Google search"/>

 <ImageView

 android:visibility="gone"

 android:layout_marginRight="10dp"

 android:src="@android:drawable/ic_menu_delete"

 android:id="@+id/search_iv_delete"

 android:layout_gravity="right|center_vertical"

 android:layout_width="wrap_content"

 android:layout_height="wrap_content"/>

 </LinearLayout>

 <WebView

 android:layout_width="match_parent"

 android:layout_height="match_parent"

 android:layout_below="@id/search_area"

 android:id="@+id/search_wv_result"

 />

 <GridView

 android:layout_below="@id/search_area"

 android:background="@drawable/rect_gray"

 android:numColumns="2"

 android:id="@+id/search_lv_tips"

 android:layout_width="match_parent"

 android:layout_height="wrap_content">

 </GridView >

</RelativeLayout>

3漓概、布局代碼中就可以猜測(cè)到,我們將在一個(gè)LinearLayout或者一個(gè)RelativeLayout中去操作病梢,我們讓這個(gè)自定義控件繼承自LinearLayout(當(dāng)然也可以繼承自RelativeLayout),這里可能需要頻繁的調(diào)用開始搜索的代碼梁肿,去做搜索onSearch()方法里的內(nèi)容蜓陌,還有就是每次搜索的時(shí)候都要隱藏鍵盤,
至于這個(gè)EditChangedListener吩蔑,只是為了在在輸入過程中動(dòng)態(tài)的一些操作 钮热,筆者也是第一次使用TextWatcher。有g(shù)ridview的地方就免不了adapter烛芬,通過外部設(shè)置給自定義控件一個(gè)adapter
直接上代碼吧:

public class YankeeSearchView extends LinearLayout implements View.OnClickListener {
 private EditText etInput;

 private ImageView ivDelete;

 private ImageView ivSearch;

 private Context mContext;

 private GridView lvTips;

 private WebView wvSearch;

 private ArrayAdapter<String> mHintAdapter;

 private SearchViewListener mListener;

 public YankeeSearchView(Context context, AttributeSet attrs) {

 super(context, attrs);

 mContext = context;

 LayoutInflater.from(context).inflate(R.layout.search_layout, this);

 initViews();

 }

 private void initViews() {

 etInput = (EditText) findViewById(R.id.search_et_input);

 ivDelete = (ImageView) findViewById(R.id.search_iv_delete);

 ivSearch=(ImageView) findViewById(R.id.search_iv_search);

 lvTips = (GridView) findViewById(R.id.search_lv_tips);

 wvSearch= (WebView) findViewById(R.id.search_wv_result);

 wvSearch.setOnTouchListener(new OnTouchListener() {

 @Override

 public boolean onTouch(View v, MotionEvent event) {

 lvTips.setVisibility(GONE);

 return false;

 }

 });

 lvTips.setOnItemClickListener(new AdapterView.OnItemClickListener() {

 @Override

 public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {

 String text = lvTips.getAdapter().getItem(i).toString();

 etInput.setText(text);

 etInput.setSelection(text.length());

 lvTips.setVisibility(View.GONE);

 notifyStartSearching(text);

 }

 });

 ivDelete.setOnClickListener(this);

 ivSearch.setOnClickListener(this);

 etInput.addTextChangedListener(new EditChangedListener());

 etInput.setOnClickListener(this);

 etInput.setOnEditorActionListener(new TextView.OnEditorActionListener() {

 @Override

 public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {

 if (actionId == EditorInfo.IME_ACTION_SEARCH) {

 lvTips.setVisibility(GONE);

 notifyStartSearching(etInput.getText().toString());

 }

 return true;

 }

 });

 }

 private void notifyStartSearching(String text){

 if (mListener != null) {

 mListener.onSearch(etInput.getText().toString());

 }

 InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);

 imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);

 }

 public void setTipsHintAdapter(ArrayAdapter<String> adapter) {

 this.mHintAdapter = adapter;

 if (lvTips.getAdapter() == null) {

 lvTips.setAdapter(mHintAdapter);

 }

 }

 private class EditChangedListener implements TextWatcher {

 @Override

 public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {

 }

 @Override

 public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {

 if (!"".equals(charSequence.toString())) {

 ivDelete.setVisibility(VISIBLE);

 lvTips.setVisibility(VISIBLE);

 } else {

 ivDelete.setVisibility(GONE);

 if (mHintAdapter != null) {

 lvTips.setAdapter(mHintAdapter);

 }

 lvTips.setVisibility(GONE);

 }

 }

 @Override

 public void afterTextChanged(Editable editable) {

 }

 }

 @Override

 public void onClick(View view) {

 switch (view.getId()) {

 case R.id.search_et_input:

 lvTips.setVisibility(VISIBLE);

 break;

 case R.id.search_iv_delete:

 etInput.setText("");

 ivDelete.setVisibility(GONE);

 break;

 case R.id.search_iv_search:

 lvTips.setVisibility(GONE);

 notifyStartSearching(etInput.getText().toString());

 break;

 }

 }

 public void setSearchViewListener(SearchViewListener listener) {

 mListener = listener;

 }

 public interface SearchViewListener {

 void onSearch(String text);

 }

 public void setWebViewUrl(String url){

 if (url!=null){

 wvSearch.loadUrl(url);

 wvSearch.setWebViewClient(new WebViewClient() {

 @Override

 public boolean shouldOverrideUrlLoading(WebView view, String url) {

 view.loadUrl(url);

 return true;

 }

 });

 }

 }

}

4隧期、代碼里都是一些隱藏顯示的操作,比較重要的是對(duì)外的接口赘娄,還有就是setWebViewUrl()方法仆潮,用來(lái)對(duì)輸入內(nèi)容展開搜索。構(gòu)造函數(shù)里傳入了三個(gè)參數(shù)遣臼,傳入一個(gè)布局文件性置,如果要自定義item,可以寫一個(gè)adapter揍堰,demo中為了簡(jiǎn)單鹏浅,使用的是Android自帶的只有一個(gè)textview的布局,而adapter使用的是ArrayAdapter<String>屏歹,再有就是通過簡(jiǎn)單修改代碼就可以把gridview替換成ListView隐砸,筆者不操作了

5、至于調(diào)用蝙眶,在activity_main布局文件中只要添加:

<com.yankee.yankeesearchview.YankeeSearchView

 android:id="@+id/main_search_layout"

 android:layout_width="match_parent"

 android:layout_height="wrap_content"/>

6季希、在activity中,通過給searchview設(shè)置listener復(fù)寫onSearch()方法幽纷,在方法里操作胖眷,別忘了通過setTipsHintAdapter()方法設(shè)置adapter:

public class MainActivity extends AppCompatActivity{

 private YankeeSearchView searchView;

 private ArrayAdapter<String> hintAdapter;

 private List<String> hintData;

 private static int HINT_SIZE=6;

 @Override

 protected void onCreate(Bundle savedInstanceState) {

 super.onCreate(savedInstanceState);

 setContentView(R.layout.activity_main);

 initData();

 initView();

 }

 private void initView() {

 searchView = (YankeeSearchView) findViewById(R.id.main_search_layout);

 searchView.setSearchViewListener(new YankeeSearchView.SearchViewListener() {

 @Override

 public void onSearch(String text) {

 Toast.makeText(MainActivity.this, "Search Complete", Toast.LENGTH_SHORT).show();

 searchView.setWebViewUrl("https://www.baidu.com/baidu?ie=utf-8&wd="+text);

 }

 });

 searchView.setTipsHintAdapter(hintAdapter);

 }

 private void initData() {

 hintData = new ArrayList<>(HINT_SIZE);

 for (int i = 1; i <= HINT_SIZE; i++) {

 hintData.add("Rio Olympic Games");

 }

 hintAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, hintData);

 }

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市霹崎,隨后出現(xiàn)的幾起案子珊搀,更是在濱河造成了極大的恐慌,老刑警劉巖尾菇,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件境析,死亡現(xiàn)場(chǎng)離奇詭異囚枪,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)劳淆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門链沼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人沛鸵,你說(shuō)我怎么就攤上這事括勺。” “怎么了曲掰?”我有些...
    開封第一講書人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵疾捍,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我栏妖,道長(zhǎng)乱豆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任吊趾,我火速辦了婚禮宛裕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘论泛。我一直安慰自己揩尸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開白布屁奏。 她就那樣靜靜地躺著疲酌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪了袁。 梳的紋絲不亂的頭發(fā)上朗恳,一...
    開封第一講書人閱讀 49,749評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音载绿,去河邊找鬼粥诫。 笑死,一個(gè)胖子當(dāng)著我的面吹牛崭庸,可吹牛的內(nèi)容都是我干的怀浆。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼怕享,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼执赡!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起函筋,我...
    開封第一講書人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤沙合,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后跌帐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體首懈,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡绊率,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了究履。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滤否。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖最仑,靈堂內(nèi)的尸體忽然破棺而出藐俺,到底是詐尸還是另有隱情,我是刑警寧澤泥彤,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布欲芹,位于F島的核電站,受9級(jí)特大地震影響全景,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜牵囤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一爸黄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧揭鳞,春花似錦炕贵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至乓梨,卻和暖如春鳖轰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背扶镀。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工蕴侣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留没咙,地道東北人寒瓦。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓捅位,卻偏偏與公主長(zhǎng)得像胳徽,于是被迫代替她去往敵國(guó)和親撤防。 傳聞我的和親對(duì)象是個(gè)殘疾皇子俏站,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,735評(píng)論 25 707
  • 內(nèi)容抽屜菜單ListViewWebViewSwitchButton按鈕點(diǎn)贊按鈕進(jìn)度條TabLayout圖標(biāo)下拉刷新...
    皇小弟閱讀 46,721評(píng)論 22 665
  • 金雞雄踞榕西南研乒, 浮生閑來(lái)邀師友止吁; 一杯香茗來(lái)助力什乙, 輕松游遍大半山挽封; 綠意盎然冬自退, 鳥語(yǔ)花香耳目聞臣镣; 飛珠濺...
    華閩南博虎閱讀 326評(píng)論 0 0
  • 前言 閱讀優(yōu)秀的開源項(xiàng)目是提高編程能力的有效手段场仲,我們能夠從中開拓思維和悦、拓寬視野,學(xué)習(xí)到很多不同的設(shè)計(jì)思想以及最佳...
    瀟瀟瀟瀟瀟瀟瀟閱讀 3,226評(píng)論 5 37
  • 第二組 429351861 我與他相識(shí)在2013年初渠缕,他是來(lái)自大山的孩子鸽素,純樸,孝順亦鳞。 我開始理財(cái)要追溯到七年前的...
    安兒CC閱讀 141評(píng)論 0 6