ActionBarAdapter.java revision 30cc2916916535a8140637f54925c93189868de5
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.contacts.activities;
18
19import com.android.contacts.R;
20import com.android.contacts.activities.ActionBarAdapter.Listener.Action;
21import com.android.contacts.list.ContactsRequest;
22
23import android.app.ActionBar;
24import android.app.ActionBar.LayoutParams;
25import android.content.Context;
26import android.os.Bundle;
27import android.text.TextUtils;
28import android.view.LayoutInflater;
29import android.view.View;
30import android.widget.SearchView;
31import android.widget.SearchView.OnCloseListener;
32import android.widget.SearchView.OnQueryTextListener;
33
34/**
35 * Adapter for the action bar at the top of the Contacts activity.
36 */
37public class ActionBarAdapter implements OnQueryTextListener, OnCloseListener {
38
39    public interface Listener {
40        public enum Action {
41            CHANGE_SEARCH_QUERY, START_SEARCH_MODE, STOP_SEARCH_MODE
42        }
43
44        void onAction(Action action);
45    }
46
47    private static final String EXTRA_KEY_SEARCH_MODE = "navBar.searchMode";
48    private static final String EXTRA_KEY_QUERY = "navBar.query";
49    private static final String EXTRA_KEY_SELECTED_TAB = "navBar.selectedTab";
50
51    private boolean mSearchMode;
52    private String mQueryString;
53
54    private String mSearchLabelText;
55    private SearchView mSearchView;
56
57    private final Context mContext;
58    private final boolean mAlwaysShowSearchView;
59
60    private Listener mListener;
61
62    private ActionBar mActionBar;
63
64
65    public ActionBarAdapter(Context context, Listener listener) {
66        mContext = context;
67        mListener = listener;
68        mSearchLabelText = mContext.getString(R.string.search_label);
69        mAlwaysShowSearchView = mContext.getResources().getBoolean(R.bool.always_show_search_view);
70    }
71
72    public void onCreate(Bundle savedState, ContactsRequest request, ActionBar actionBar) {
73        mActionBar = actionBar;
74        mQueryString = null;
75
76        if (savedState != null) {
77            mSearchMode = savedState.getBoolean(EXTRA_KEY_SEARCH_MODE);
78            mQueryString = savedState.getString(EXTRA_KEY_QUERY);
79        } else {
80            mSearchMode = request.isSearchMode();
81            mQueryString = request.getQueryString();
82        }
83
84        // Set up search view.
85        View customSearchView = LayoutInflater.from(mContext).inflate(R.layout.custom_action_bar,
86                null);
87        int searchViewWidth = mContext.getResources().getDimensionPixelSize(
88                R.dimen.search_view_width);
89        if (searchViewWidth == 0) {
90            searchViewWidth = LayoutParams.MATCH_PARENT;
91        }
92        LayoutParams layoutParams = new LayoutParams(searchViewWidth, LayoutParams.WRAP_CONTENT);
93        mSearchView = (SearchView) customSearchView.findViewById(R.id.search_view);
94        mSearchView.setQueryHint(mContext.getString(R.string.hint_findContacts));
95        mSearchView.setOnQueryTextListener(this);
96        mSearchView.setOnCloseListener(this);
97        mSearchView.setQuery(mQueryString, false);
98        mActionBar.setCustomView(customSearchView, layoutParams);
99
100        update();
101    }
102
103    public void setListener(Listener listener) {
104        mListener = listener;
105    }
106
107    public boolean isSearchMode() {
108        return mSearchMode;
109    }
110
111    public void setSearchMode(boolean flag) {
112        if (mSearchMode != flag) {
113            mSearchMode = flag;
114            update();
115            if (mSearchView == null) {
116                return;
117            }
118            if (mSearchMode) {
119                setFocusOnSearchView();
120            } else {
121                mSearchView.setQuery(null, false);
122            }
123        }
124    }
125
126    public String getQueryString() {
127        return mQueryString;
128    }
129
130    public void setQueryString(String query) {
131        mQueryString = query;
132        if (mSearchView != null) {
133            mSearchView.setQuery(query, false);
134        }
135    }
136
137    public void update() {
138        if (mSearchMode) {
139            mActionBar.setDisplayShowCustomEnabled(true);
140            if (mAlwaysShowSearchView) {
141                // Tablet -- change the app title for the search mode
142                mActionBar.setTitle(mSearchLabelText);
143            } else {
144                // Phone -- search view gets focus
145                setFocusOnSearchView();
146            }
147            mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
148            if (mListener != null) {
149                mListener.onAction(Action.START_SEARCH_MODE);
150            }
151        } else {
152            mActionBar.setDisplayShowCustomEnabled(mAlwaysShowSearchView);
153            mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
154            mActionBar.setTitle(null);
155            if (mListener != null) {
156                mListener.onAction(Action.STOP_SEARCH_MODE);
157            }
158        }
159    }
160
161    @Override
162    public boolean onQueryTextChange(String queryString) {
163        // TODO: Clean up SearchView code because it keeps setting the SearchView query,
164        // invoking onQueryChanged, setting up the fragment again, invalidating the options menu,
165        // storing the SearchView again, and etc... unless we add in the early return statements.
166        if (queryString.equals(mQueryString)) {
167            return false;
168        }
169        mQueryString = queryString;
170        if (!mSearchMode) {
171            if (!TextUtils.isEmpty(queryString)) {
172                setSearchMode(true);
173            }
174        } else if (mListener != null) {
175            mListener.onAction(Action.CHANGE_SEARCH_QUERY);
176        }
177
178        return true;
179    }
180
181    @Override
182    public boolean onQueryTextSubmit(String query) {
183        return true;
184    }
185
186    @Override
187    public boolean onClose() {
188        setSearchMode(false);
189        return false;
190    }
191
192    public void onSaveInstanceState(Bundle outState) {
193        outState.putBoolean(EXTRA_KEY_SEARCH_MODE, mSearchMode);
194        outState.putString(EXTRA_KEY_QUERY, mQueryString);
195        outState.putInt(EXTRA_KEY_SELECTED_TAB, mActionBar.getSelectedNavigationIndex());
196    }
197
198    public void onRestoreInstanceState(Bundle savedState) {
199        mSearchMode = savedState.getBoolean(EXTRA_KEY_SEARCH_MODE);
200        mQueryString = savedState.getString(EXTRA_KEY_QUERY);
201        int selectedTab = savedState.getInt(EXTRA_KEY_SELECTED_TAB);
202        if (selectedTab >= 0) {
203            mActionBar.setSelectedNavigationItem(selectedTab);
204        }
205    }
206
207    private void setFocusOnSearchView() {
208        mSearchView.requestFocus();
209        mSearchView.setIconified(false); // Workaround for the "IME not popping up" issue.
210    }
211}
212