SearchBar.java revision 0075dfe4e812a633be39018e1d6a85e5c6e58de5
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5 * in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the License
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 * or implied. See the License for the specific language governing permissions and limitations under
12 * the License.
13 */
14package android.support.v17.leanback.widget;
15
16import android.content.Context;
17import android.os.Handler;
18import android.os.SystemClock;
19import android.text.Editable;
20import android.text.TextWatcher;
21import android.util.AttributeSet;
22import android.util.Log;
23import android.view.inputmethod.EditorInfo;
24import android.view.KeyEvent;
25import android.view.MotionEvent;
26import android.view.View;
27import android.widget.RelativeLayout;
28import android.support.v17.leanback.R;
29import android.widget.TextView;
30
31/**
32 * SearchBar is a search widget.
33 */
34public class SearchBar extends RelativeLayout {
35    private static final String TAG = SearchBar.class.getSimpleName();
36    private static final boolean DEBUG = false;
37
38    /**
39     * Listener for search query changes
40     */
41    public interface SearchBarListener {
42
43        /**
44         * Method invoked when the search bar detects a change in the query.
45         *
46         * @param query The current full query.
47         */
48        public void onSearchQueryChange(String query);
49
50        /**
51         * Method invoked when the search query is submitted.
52         *
53         * @param query The query being submitted.
54         */
55        public void onSearchQuerySubmit(String query);
56
57        /**
58         * Method invoked when the IME is being dismissed.
59         *
60         * @param query The query set in the search bar at the time the IME is being dismissed.
61         */
62        public void onKeyboardDismiss(String query);
63    }
64
65    private SearchBarListener mSearchBarListener;
66    private SearchEditText mSearchTextEditor;
67    private String mSearchQuery;
68    private final Handler mHandler = new Handler();
69
70    public SearchBar(Context context) {
71        this(context, null);
72    }
73
74    public SearchBar(Context context, AttributeSet attrs) {
75        this(context, attrs, 0);
76    }
77
78    public SearchBar(Context context, AttributeSet attrs, int defStyle) {
79        super(context, attrs, defStyle);
80        mSearchQuery = "";
81    }
82
83    @Override
84    protected void onFinishInflate() {
85        super.onFinishInflate();
86
87        mSearchTextEditor = (SearchEditText)findViewById(R.id.lb_search_text_editor);
88        mSearchTextEditor.setOnFocusChangeListener(new OnFocusChangeListener() {
89            @Override
90            public void onFocusChange(View view, boolean hasFocus) {
91                if (DEBUG) Log.v(TAG, "onFocusChange " + hasFocus);
92                if (hasFocus) {
93                    showNativeKeyboard();
94                }
95            }
96        });
97        mSearchTextEditor.addTextChangedListener(new TextWatcher() {
98            @Override
99            public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
100
101            }
102
103            @Override
104            public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
105                setSearchQuery(charSequence.toString());
106            }
107
108            @Override
109            public void afterTextChanged(Editable editable) {
110
111            }
112        });
113        mSearchTextEditor.setOnKeyboardDismissListener(
114                new SearchEditText.OnKeyboardDismissListener() {
115                    @Override
116                    public void onKeyboardDismiss() {
117                        if (null != mSearchBarListener) {
118                            mSearchBarListener.onKeyboardDismiss(mSearchQuery);
119                        }
120                    }
121                });
122        mSearchTextEditor.setOnEditorActionListener(new TextView.OnEditorActionListener() {
123            @Override
124            public boolean onEditorAction(TextView textView, int action, KeyEvent keyEvent) {
125                if (EditorInfo.IME_ACTION_SEARCH == action && null != mSearchBarListener) {
126                    mSearchBarListener.onSearchQuerySubmit(mSearchQuery);
127                    return true;
128                }
129                return false;
130            }
131        });
132    }
133
134    @Override
135    protected void onAttachedToWindow() {
136        super.onAttachedToWindow();
137        mHandler.post(new Runnable() {
138            @Override
139            public void run() {
140                mSearchTextEditor.requestFocus();
141                mSearchTextEditor.requestFocusFromTouch();
142            }
143        });
144    }
145
146    /**
147     * Set a listener for when the term search changes
148     * @param listener
149     */
150    public void setSearchBarListener(SearchBarListener listener) {
151        mSearchBarListener = listener;
152    }
153
154    /**
155     * Set the search query
156     * @param query the search query to use
157     */
158    public void setSearchQuery(String query) {
159        if (query.equals(mSearchQuery)) {
160            return;
161        }
162        mSearchQuery = query;
163        if (null != mSearchBarListener) {
164            mSearchBarListener.onSearchQueryChange(mSearchQuery);
165        }
166    }
167
168    /**
169     * Set the hint text shown in the search bar.
170     * @param hint The hint to use.
171     */
172    public void setHint(String hint) {
173        mSearchTextEditor.setHint(hint);
174    }
175
176    protected void showNativeKeyboard() {
177        mHandler.post(new Runnable() {
178            @Override
179            public void run() {
180                mSearchTextEditor.requestFocusFromTouch();
181                mSearchTextEditor.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(),
182                        SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN,
183                        mSearchTextEditor.getWidth(), mSearchTextEditor.getHeight(), 0));
184                mSearchTextEditor.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(),
185                        SystemClock.uptimeMillis(), MotionEvent.ACTION_UP,
186                        mSearchTextEditor.getWidth(), mSearchTextEditor.getHeight(), 0));
187            }
188        });
189    }
190
191}
192