ActionBarAdapter.java revision 8d71f11c70c974518f3482c46a10a5601628a029
108e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov/*
2fcfdffb439ccf1ddef971109b82e782c47161572Dmitri Plotnikov * Copyright (C) 2010 The Android Open Source Project
308e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov *
408e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov * Licensed under the Apache License, Version 2.0 (the "License");
508e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov * you may not use this file except in compliance with the License.
608e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov * You may obtain a copy of the License at
708e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov *
808e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov *      http://www.apache.org/licenses/LICENSE-2.0
908e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov *
1008e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov * Unless required by applicable law or agreed to in writing, software
1108e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov * distributed under the License is distributed on an "AS IS" BASIS,
1208e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1308e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov * See the License for the specific language governing permissions and
1408e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov * limitations under the License.
1508e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov */
1608e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov
1708e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikovpackage com.android.contacts.activities;
1808e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov
193c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwellimport android.animation.ValueAnimator;
201a59cffd839069ce91a9febb8a136442340ab4c8Dmitri Plotnikovimport android.app.ActionBar;
2108e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikovimport android.content.Context;
2235d4aec605ce915ff5c574892a2069a37e0b9a77Makoto Onukiimport android.content.SharedPreferences;
233c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwellimport android.content.res.TypedArray;
2408e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikovimport android.os.Bundle;
2535d4aec605ce915ff5c574892a2069a37e0b9a77Makoto Onukiimport android.preference.PreferenceManager;
266adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwellimport android.text.Editable;
2715ccbb4d22fd65165cacb7970cbe61de1aa9aac4Dmitri Plotnikovimport android.text.TextUtils;
286adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwellimport android.text.TextWatcher;
293c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwellimport android.view.LayoutInflater;
301ee9df6facd2340416d6a33aeb739707643d2fc3Katherine Kuanimport android.view.View;
313c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwellimport android.view.ViewGroup;
32d8a61b7296bf7388505f0211d7ef44700e766193Katherine Kuanimport android.view.inputmethod.InputMethodManager;
331a59cffd839069ce91a9febb8a136442340ab4c8Dmitri Plotnikovimport android.widget.SearchView;
341a59cffd839069ce91a9febb8a136442340ab4c8Dmitri Plotnikovimport android.widget.SearchView.OnCloseListener;
356adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwellimport android.view.View.OnClickListener;
366adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwellimport android.widget.EditText;
373c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwellimport android.widget.Toolbar;
3892a6fdf1b07b8f1447560174e24455fd46aee7cdDmitri Plotnikov
39e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.R;
40e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.activities.ActionBarAdapter.Listener.Action;
41e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Chengimport com.android.contacts.list.ContactsRequest;
42e0b2f1e2d01d1ac52ba207dc7ce76971d853298eChiao Cheng
4308e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov/**
44fcfdffb439ccf1ddef971109b82e782c47161572Dmitri Plotnikov * Adapter for the action bar at the top of the Contacts activity.
4508e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov */
466adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwellpublic class ActionBarAdapter implements OnCloseListener {
4708e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov
4808e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov    public interface Listener {
49311882ab2fc1e9c8264f5892a6d50722b834e348Daniel Lehmann        public abstract class Action {
50311882ab2fc1e9c8264f5892a6d50722b834e348Daniel Lehmann            public static final int CHANGE_SEARCH_QUERY = 0;
51311882ab2fc1e9c8264f5892a6d50722b834e348Daniel Lehmann            public static final int START_SEARCH_MODE = 1;
52311882ab2fc1e9c8264f5892a6d50722b834e348Daniel Lehmann            public static final int STOP_SEARCH_MODE = 2;
53b5760b94bbf56ce348876ec36f4669d20a1530f5Katherine Kuan        }
54b5760b94bbf56ce348876ec36f4669d20a1530f5Katherine Kuan
55311882ab2fc1e9c8264f5892a6d50722b834e348Daniel Lehmann        void onAction(int action);
564d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki
574d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki        /**
584d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki         * Called when the user selects a tab.  The new tab can be obtained using
594d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki         * {@link #getCurrentTab}.
604d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki         */
614d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki        void onSelectedTabChanged();
626adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell
636adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        void onUpButtonPressed();
6408e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov    }
6508e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov
6615ccbb4d22fd65165cacb7970cbe61de1aa9aac4Dmitri Plotnikov    private static final String EXTRA_KEY_SEARCH_MODE = "navBar.searchMode";
6708e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov    private static final String EXTRA_KEY_QUERY = "navBar.query";
6859dc2751d64f60f743b8a9e78186aa5b79dcaf83Isaac Katzenelson    private static final String EXTRA_KEY_SELECTED_TAB = "navBar.selectedTab";
6908e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov
7035d4aec605ce915ff5c574892a2069a37e0b9a77Makoto Onuki    private static final String PERSISTENT_LAST_TAB = "actionBarAdapter.lastTab";
7135d4aec605ce915ff5c574892a2069a37e0b9a77Makoto Onuki
7215ccbb4d22fd65165cacb7970cbe61de1aa9aac4Dmitri Plotnikov    private boolean mSearchMode;
7308e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov    private String mQueryString;
7415ccbb4d22fd65165cacb7970cbe61de1aa9aac4Dmitri Plotnikov
756adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell    private EditText mSearchView;
763c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    /** The view that represents tabs when we are in portrait mode **/
773c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    private View mPortraitTabs;
783c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    /** The view that represents tabs when we are in landscape mode **/
793c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    private View mLandscapeTabs;
806adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell    private View mSearchContainer;
8192a6fdf1b07b8f1447560174e24455fd46aee7cdDmitri Plotnikov
823c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    private int mMaxPortraitTabHeight;
833c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    private int mMaxToolbarContentInsetStart;
843c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell
8508e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov    private final Context mContext;
8635d4aec605ce915ff5c574892a2069a37e0b9a77Makoto Onuki    private final SharedPreferences mPrefs;
8708e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov
8808e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov    private Listener mListener;
8908e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov
904d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki    private final ActionBar mActionBar;
913c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    private final Toolbar mToolbar;
928b8264620f9362e089322d1e3a7cc5620900e6f9Dmitri Plotnikov
93e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki    private boolean mShowHomeIcon;
94e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki
9552aa32db432085ab2cd4864bd1edd1ef843da867Daniel Lehmann    public interface TabState {
963b6a6f6ac9dce6028248ed7a695ed2c76890add8Paul Sliwowski        public static int FAVORITES = 0;
9752aa32db432085ab2cd4864bd1edd1ef843da867Daniel Lehmann        public static int ALL = 1;
9852aa32db432085ab2cd4864bd1edd1ef843da867Daniel Lehmann
995f057fa8a0d1be9529024846c9e69b5764078d2cPaul Soulos        public static int COUNT = 2;
10052aa32db432085ab2cd4864bd1edd1ef843da867Daniel Lehmann        public static int DEFAULT = ALL;
1014d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki    }
1024d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki
10352aa32db432085ab2cd4864bd1edd1ef843da867Daniel Lehmann    private int mCurrentTab = TabState.DEFAULT;
1044d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki
1053c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    public ActionBarAdapter(Context context, Listener listener, ActionBar actionBar,
1063c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell            View portraitTabs, View landscapeTabs, Toolbar toolbar) {
10708e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov        mContext = context;
1081ee9df6facd2340416d6a33aeb739707643d2fc3Katherine Kuan        mListener = listener;
1094d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki        mActionBar = actionBar;
11035d4aec605ce915ff5c574892a2069a37e0b9a77Makoto Onuki        mPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
1113c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        mPortraitTabs = portraitTabs;
1123c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        mLandscapeTabs = landscapeTabs;
1133c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        mToolbar = toolbar;
1143c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        mMaxToolbarContentInsetStart = mToolbar.getContentInsetStart();
115e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki        mShowHomeIcon = mContext.getResources().getBoolean(R.bool.show_home_icon);
116e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki
1176adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        setupSearchView();
1183c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        setupTabs(context);
1197f5220e23b37b76cf484b28c182a0c98749b59e2Maurice Chu    }
1207f5220e23b37b76cf484b28c182a0c98749b59e2Maurice Chu
1213c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    private void setupTabs(Context context) {
1223c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        final TypedArray attributeArray = context.obtainStyledAttributes(
1233c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                new int[]{android.R.attr.actionBarSize});
1243c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        mMaxPortraitTabHeight = attributeArray.getDimensionPixelSize(0, 0);
1253c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        // Hide tabs initially
1263c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        setPortraitTabHeight(0);
1274d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki    }
1284d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki
1296adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell    private void setupSearchView() {
1303c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        final LayoutInflater inflater = (LayoutInflater) mToolbar.getContext().getSystemService(
1313c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                Context.LAYOUT_INFLATER_SERVICE);
1323c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        mSearchContainer = inflater.inflate(R.layout.search_bar_expanded, mToolbar,
1333c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                /* attachToRoot = */ false);
1343c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        mSearchContainer.setVisibility(View.VISIBLE);
1353c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        mToolbar.addView(mSearchContainer);
1363c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell
1376adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        mSearchContainer.setBackgroundColor(mContext.getResources().getColor(
1386adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                R.color.searchbox_background_color));
1396adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        mSearchView = (EditText) mSearchContainer.findViewById(R.id.search_view);
1406adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        mSearchView.setHint(mContext.getString(R.string.hint_findContacts));
1416adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        mSearchView.addTextChangedListener(new SearchTextWatcher());
1426adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        mSearchContainer.findViewById(R.id.search_close_button).setOnClickListener(
1436adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                new OnClickListener() {
1446adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            @Override
1456adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            public void onClick(View v) {
1466adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                mSearchView.setText(null);
1476adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            }
1486adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        });
1496adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        mSearchContainer.findViewById(R.id.search_back_button).setOnClickListener(
1506adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                new OnClickListener() {
1516adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            @Override
1526adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            public void onClick(View v) {
1536adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                if (mListener != null) {
1546adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                    mListener.onUpButtonPressed();
1556adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                }
1566adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            }
1576adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        });
1586adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell    }
1596adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell
1604d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki    public void initialize(Bundle savedState, ContactsRequest request) {
1614d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki        if (savedState == null) {
1624d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki            mSearchMode = request.isSearchMode();
1634d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki            mQueryString = request.getQueryString();
16435d4aec605ce915ff5c574892a2069a37e0b9a77Makoto Onuki            mCurrentTab = loadLastTabPreference();
1654d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki        } else {
1664d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki            mSearchMode = savedState.getBoolean(EXTRA_KEY_SEARCH_MODE);
1674d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki            mQueryString = savedState.getString(EXTRA_KEY_QUERY);
1684d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki
1694d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki            // Just set to the field here.  The listener will be notified by update().
17052aa32db432085ab2cd4864bd1edd1ef843da867Daniel Lehmann            mCurrentTab = savedState.getInt(EXTRA_KEY_SELECTED_TAB);
1714d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki        }
17226dc5592145eeddcd435daf2dae29d8e483f1b7bBrian Attwell        if (mCurrentTab >= TabState.COUNT || mCurrentTab < 0) {
17326dc5592145eeddcd435daf2dae29d8e483f1b7bBrian Attwell            // Invalid tab index was saved (b/12938207). Restore the default.
17426dc5592145eeddcd435daf2dae29d8e483f1b7bBrian Attwell            mCurrentTab = TabState.DEFAULT;
17526dc5592145eeddcd435daf2dae29d8e483f1b7bBrian Attwell        }
1763c877e33cb7fecc7a63af1cf3c25061d53811bf6Katherine Kuan        // Show tabs or the expanded {@link SearchView}, depending on whether or not we are in
1773c877e33cb7fecc7a63af1cf3c25061d53811bf6Katherine Kuan        // search mode.
1786adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        update(true /* skipAnimation */);
1793c877e33cb7fecc7a63af1cf3c25061d53811bf6Katherine Kuan        // Expanding the {@link SearchView} clears the query, so set the query from the
1803c877e33cb7fecc7a63af1cf3c25061d53811bf6Katherine Kuan        // {@link ContactsRequest} after it has been expanded, if applicable.
1813c877e33cb7fecc7a63af1cf3c25061d53811bf6Katherine Kuan        if (mSearchMode && !TextUtils.isEmpty(mQueryString)) {
1823c877e33cb7fecc7a63af1cf3c25061d53811bf6Katherine Kuan            setQueryString(mQueryString);
1833c877e33cb7fecc7a63af1cf3c25061d53811bf6Katherine Kuan        }
1848b8264620f9362e089322d1e3a7cc5620900e6f9Dmitri Plotnikov    }
1858b8264620f9362e089322d1e3a7cc5620900e6f9Dmitri Plotnikov
1861a59cffd839069ce91a9febb8a136442340ab4c8Dmitri Plotnikov    public void setListener(Listener listener) {
1871a59cffd839069ce91a9febb8a136442340ab4c8Dmitri Plotnikov        mListener = listener;
18808e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov    }
18908e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov
1906adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell    private class SearchTextWatcher implements TextWatcher {
1916adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell
1926adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        @Override
1936adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        public void onTextChanged(CharSequence queryString, int start, int before, int count) {
1946adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            if (queryString.equals(mQueryString)) {
1956adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                return;
1966adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            }
1976adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            mQueryString = queryString.toString();
1986adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            if (!mSearchMode) {
1996adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                if (!TextUtils.isEmpty(queryString)) {
2006adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                    setSearchMode(true);
2016adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                }
2026adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            } else if (mListener != null) {
2036adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                mListener.onAction(Action.CHANGE_SEARCH_QUERY);
2046adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            }
2056adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        }
2066adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell
2076adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        @Override
2086adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        public void afterTextChanged(Editable s) {}
2096adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell
2106adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        @Override
2116adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
2126adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell    }
2136adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell
2144d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki    /**
2153c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell     * Save the current tab selection, and notify the listener.
2164d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki     */
21752aa32db432085ab2cd4864bd1edd1ef843da867Daniel Lehmann    public void setCurrentTab(int tab) {
218250ce43794cdf6820f7a13ef0195a566bd0c8c64Makoto Onuki        setCurrentTab(tab, true);
219250ce43794cdf6820f7a13ef0195a566bd0c8c64Makoto Onuki    }
220250ce43794cdf6820f7a13ef0195a566bd0c8c64Makoto Onuki
221250ce43794cdf6820f7a13ef0195a566bd0c8c64Makoto Onuki    /**
2223c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell     * Save the current tab selection.
223250ce43794cdf6820f7a13ef0195a566bd0c8c64Makoto Onuki     */
22452aa32db432085ab2cd4864bd1edd1ef843da867Daniel Lehmann    public void setCurrentTab(int tab, boolean notifyListener) {
2254d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki        if (tab == mCurrentTab) {
2264d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki            return;
2274d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki        }
2284d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki        mCurrentTab = tab;
2294d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki
230250ce43794cdf6820f7a13ef0195a566bd0c8c64Makoto Onuki        if (notifyListener && mListener != null) mListener.onSelectedTabChanged();
23135d4aec605ce915ff5c574892a2069a37e0b9a77Makoto Onuki        saveLastTabPreference(mCurrentTab);
2324d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki    }
2334d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki
23452aa32db432085ab2cd4864bd1edd1ef843da867Daniel Lehmann    public int getCurrentTab() {
2354d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki        return mCurrentTab;
2364d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki    }
2374d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki
2381db00f68b34f6cf7e9d19fedb559cf12f8c05e9cMakoto Onuki    /**
2391db00f68b34f6cf7e9d19fedb559cf12f8c05e9cMakoto Onuki     * @return Whether in search mode, i.e. if the search view is visible/expanded.
2401db00f68b34f6cf7e9d19fedb559cf12f8c05e9cMakoto Onuki     *
2411db00f68b34f6cf7e9d19fedb559cf12f8c05e9cMakoto Onuki     * Note even if the action bar is in search mode, if the query is empty, the search fragment
2421db00f68b34f6cf7e9d19fedb559cf12f8c05e9cMakoto Onuki     * will not be in search mode.
2431db00f68b34f6cf7e9d19fedb559cf12f8c05e9cMakoto Onuki     */
24415ccbb4d22fd65165cacb7970cbe61de1aa9aac4Dmitri Plotnikov    public boolean isSearchMode() {
24515ccbb4d22fd65165cacb7970cbe61de1aa9aac4Dmitri Plotnikov        return mSearchMode;
24608e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov    }
24708e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov
24815ccbb4d22fd65165cacb7970cbe61de1aa9aac4Dmitri Plotnikov    public void setSearchMode(boolean flag) {
24915ccbb4d22fd65165cacb7970cbe61de1aa9aac4Dmitri Plotnikov        if (mSearchMode != flag) {
25015ccbb4d22fd65165cacb7970cbe61de1aa9aac4Dmitri Plotnikov            mSearchMode = flag;
2516adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            update(false /* skipAnimation */);
252f3f933a798c9cfffb1c1c0cc770187b5b0b763ebKatherine Kuan            if (mSearchView == null) {
253f3f933a798c9cfffb1c1c0cc770187b5b0b763ebKatherine Kuan                return;
254f3f933a798c9cfffb1c1c0cc770187b5b0b763ebKatherine Kuan            }
2550b51a8d4539cc516dc2c02948335347d1df8769bDmitri Plotnikov            if (mSearchMode) {
2564ba903cdf132a6be2e5efa33187b18ca8446e503Makoto Onuki                setFocusOnSearchView();
257ab4d29f6a2edbfae008dbaff35f25baad73aa0dfDmitri Plotnikov            } else {
2586adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                mSearchView.setText(null);
2590b51a8d4539cc516dc2c02948335347d1df8769bDmitri Plotnikov            }
260311882ab2fc1e9c8264f5892a6d50722b834e348Daniel Lehmann        } else if (flag) {
261311882ab2fc1e9c8264f5892a6d50722b834e348Daniel Lehmann            // Everything is already set up. Still make sure the keyboard is up
262311882ab2fc1e9c8264f5892a6d50722b834e348Daniel Lehmann            if (mSearchView != null) setFocusOnSearchView();
26308e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov        }
26408e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov    }
26508e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov
26608e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov    public String getQueryString() {
2671db00f68b34f6cf7e9d19fedb559cf12f8c05e9cMakoto Onuki        return mSearchMode ? mQueryString : null;
26808e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov    }
26908e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov
27008e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov    public void setQueryString(String query) {
27108e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov        mQueryString = query;
272f3f933a798c9cfffb1c1c0cc770187b5b0b763ebKatherine Kuan        if (mSearchView != null) {
2736adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            mSearchView.setText(query);
274f3f933a798c9cfffb1c1c0cc770187b5b0b763ebKatherine Kuan        }
27508e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov    }
27608e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov
277e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki    /** @return true if the "UP" icon is showing. */
278e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki    public boolean isUpShowing() {
279e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki        return mSearchMode; // Only shown on the search mode.
280e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki    }
281e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki
2823c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    private void updateDisplayOptionsInner() {
283e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki        // All the flags we may change in this method.
284e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki        final int MASK = ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_HOME
285d84ea5c8b0a8376e7cf80b0e15b65a72fd99d7a9Adam Powell                | ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_CUSTOM;
286e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki
287e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki        // The current flags set to the action bar.  (only the ones that we may change here)
288e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki        final int current = mActionBar.getDisplayOptions() & MASK;
289e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki
290e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki        // Build the new flags...
291e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki        int newFlags = 0;
2926adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        if (mShowHomeIcon && !mSearchMode) {
293e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki            newFlags |= ActionBar.DISPLAY_SHOW_HOME;
294e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki        }
295e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki        if (mSearchMode) {
296e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki            newFlags |= ActionBar.DISPLAY_SHOW_CUSTOM;
2973c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell            mToolbar.setContentInsetsRelative(0, mToolbar.getContentInsetEnd());
2986adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        } else {
2996adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            newFlags |= ActionBar.DISPLAY_SHOW_TITLE;
3003c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell            mToolbar.setContentInsetsRelative(mMaxToolbarContentInsetStart,
3013c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                    mToolbar.getContentInsetEnd());
302e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki        }
303b0d3c7609a21d7432bcac0cf97411d1ff64851baBrian Attwell
3043c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell
305e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki        if (current != newFlags) {
306e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki            // Pass the mask here to preserve other flags that we're not interested here.
307e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki            mActionBar.setDisplayOptions(newFlags, MASK);
308e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki        }
309e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki    }
310e0c66aff27473d0edbd95660b95f0f2a80ab63ecMakoto Onuki
3116adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell    private void update(boolean skipAnimation) {
3126adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        final boolean isIconifiedChanging
3133c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                = (mSearchContainer.getParent() == null) == mSearchMode;
3146adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        if (isIconifiedChanging && !skipAnimation) {
3158d71f11c70c974518f3482c46a10a5601628a029Brian Attwell            mToolbar.removeView(mLandscapeTabs);
3166adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            if (mSearchMode) {
3173c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                addSearchContainer();
3186adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                mSearchContainer.setAlpha(0);
3196adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                mSearchContainer.animate().alpha(1);
3203c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                animateTabHeightChange(mMaxPortraitTabHeight, 0);
3213c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                updateDisplayOptions(isIconifiedChanging);
3226adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            } else {
3236adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                mSearchContainer.setAlpha(1);
3243c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                animateTabHeightChange(0, mMaxPortraitTabHeight);
3256adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                mSearchContainer.animate().alpha(0).withEndAction(new Runnable() {
3266adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                    @Override
3276adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                    public void run() {
3283c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                        updateDisplayOptionsInner();
3293c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                        updateDisplayOptions(isIconifiedChanging);
3303c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                        addLandscapeViewPagerTabs();
3313c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                        mToolbar.removeView(mSearchContainer);
3326adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                    }
3336adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                });
3346adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            }
3356adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            return;
3366adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        }
3376adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        if (isIconifiedChanging && skipAnimation) {
3388d71f11c70c974518f3482c46a10a5601628a029Brian Attwell            mToolbar.removeView(mLandscapeTabs);
3396adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            if (mSearchMode) {
3403c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                setPortraitTabHeight(0);
3413c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                addSearchContainer();
3426adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            } else {
3433c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                setPortraitTabHeight(mMaxPortraitTabHeight);
3443c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                mToolbar.removeView(mSearchContainer);
3453c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                addLandscapeViewPagerTabs();
3466adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            }
3476adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        }
3483c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        updateDisplayOptions(isIconifiedChanging);
3496adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell    }
3506adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell
3513c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    private void addLandscapeViewPagerTabs() {
3523c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        if (mLandscapeTabs != null) {
3533c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell            mToolbar.removeView(mLandscapeTabs);
3543c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell            mToolbar.addView(mLandscapeTabs);
3553c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        }
3563c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    }
3573c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell
3583c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    private void addSearchContainer() {
3593c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        mToolbar.removeView(mSearchContainer);
3603c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        mToolbar.addView(mSearchContainer);
3613c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    }
3623c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell
3633c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    private void updateDisplayOptions(boolean isIconifiedChanging) {
364b5760b94bbf56ce348876ec36f4669d20a1530f5Katherine Kuan        if (mSearchMode) {
3655267367e202dcb39ef0fe912a7be9209548ec436Makoto Onuki            setFocusOnSearchView();
366d8a61b7296bf7388505f0211d7ef44700e766193Katherine Kuan            // Since we have the {@link SearchView} in a custom action bar, we must manually handle
3673c877e33cb7fecc7a63af1cf3c25061d53811bf6Katherine Kuan            // expanding the {@link SearchView} when a search is initiated. Note that a side effect
3683c877e33cb7fecc7a63af1cf3c25061d53811bf6Katherine Kuan            // of this method is that the {@link SearchView} query text is set to empty string.
369b0d82d2703d66b3bd4fe8dc4208cdf6a09f2f4afDaniel Lehmann            if (isIconifiedChanging) {
3706adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                final CharSequence queryText = mSearchView.getText();
3718d5eec3c552c2ac23bc4d3324063627d31582615Yorke Lee                if (!TextUtils.isEmpty(queryText)) {
3726adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                    mSearchView.setText(queryText);
3738d5eec3c552c2ac23bc4d3324063627d31582615Yorke Lee                }
374b0d82d2703d66b3bd4fe8dc4208cdf6a09f2f4afDaniel Lehmann            }
375b5760b94bbf56ce348876ec36f4669d20a1530f5Katherine Kuan            if (mListener != null) {
376b5760b94bbf56ce348876ec36f4669d20a1530f5Katherine Kuan                mListener.onAction(Action.START_SEARCH_MODE);
377c9916d303cc48b4a4ff94ef9c56d7ca5da72c4deDmitri Plotnikov            }
37815ccbb4d22fd65165cacb7970cbe61de1aa9aac4Dmitri Plotnikov        } else {
379b5760b94bbf56ce348876ec36f4669d20a1530f5Katherine Kuan            if (mListener != null) {
380b5760b94bbf56ce348876ec36f4669d20a1530f5Katherine Kuan                mListener.onAction(Action.STOP_SEARCH_MODE);
3814d788fc27ac855bd6e0cec17dff39a18564f0089Makoto Onuki                mListener.onSelectedTabChanged();
382bee8d3bd37edf44c535c0cc401e8d03f095b8328Dmitri Plotnikov            }
38308e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov        }
3843c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        updateDisplayOptionsInner();
38508e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov    }
38608e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov
38708e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov    @Override
3881a59cffd839069ce91a9febb8a136442340ab4c8Dmitri Plotnikov    public boolean onClose() {
38915ccbb4d22fd65165cacb7970cbe61de1aa9aac4Dmitri Plotnikov        setSearchMode(false);
39015ccbb4d22fd65165cacb7970cbe61de1aa9aac4Dmitri Plotnikov        return false;
39108e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov    }
39208e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov
39315ccbb4d22fd65165cacb7970cbe61de1aa9aac4Dmitri Plotnikov    public void onSaveInstanceState(Bundle outState) {
39415ccbb4d22fd65165cacb7970cbe61de1aa9aac4Dmitri Plotnikov        outState.putBoolean(EXTRA_KEY_SEARCH_MODE, mSearchMode);
39515ccbb4d22fd65165cacb7970cbe61de1aa9aac4Dmitri Plotnikov        outState.putString(EXTRA_KEY_QUERY, mQueryString);
39652aa32db432085ab2cd4864bd1edd1ef843da867Daniel Lehmann        outState.putInt(EXTRA_KEY_SELECTED_TAB, mCurrentTab);
397fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov    }
398fa49a66979567894c85fe2489d1375216d67597eDmitri Plotnikov
3995c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan    /**
4005c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan     * Clears the focus from the {@link SearchView} if we are in search mode.
4015c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan     * This will suppress the IME if it is visible.
4025c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan     */
4035c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan    public void clearFocusOnSearchView() {
4045c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan        if (isSearchMode()) {
4055c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan            if (mSearchView != null) {
4065c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan                mSearchView.clearFocus();
4075c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan            }
4085c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan        }
4095c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan    }
4105c3a0a1440625fab859aab420cb08bc0276358a0Katherine Kuan
41109d66a382d1f94618b52fec11ba54d9243a95a18Daniel Lehmann    public void setFocusOnSearchView() {
4124ba903cdf132a6be2e5efa33187b18ca8446e503Makoto Onuki        mSearchView.requestFocus();
4136adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        showInputMethod(mSearchView); // Workaround for the "IME not popping up" issue.
4146adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell    }
4156adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell
4166adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell    private void showInputMethod(View view) {
4176adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        final InputMethodManager imm = (InputMethodManager) mContext.getSystemService(
4186adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell                Context.INPUT_METHOD_SERVICE);
4196adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        if (imm != null) {
4206adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell            imm.showSoftInput(view, 0);
4216adbf1e7870e9de4ad203d334c8786ffca7d123dBrian Attwell        }
4224ba903cdf132a6be2e5efa33187b18ca8446e503Makoto Onuki    }
42335d4aec605ce915ff5c574892a2069a37e0b9a77Makoto Onuki
42452aa32db432085ab2cd4864bd1edd1ef843da867Daniel Lehmann    private void saveLastTabPreference(int tab) {
42552aa32db432085ab2cd4864bd1edd1ef843da867Daniel Lehmann        mPrefs.edit().putInt(PERSISTENT_LAST_TAB, tab).apply();
42635d4aec605ce915ff5c574892a2069a37e0b9a77Makoto Onuki    }
42735d4aec605ce915ff5c574892a2069a37e0b9a77Makoto Onuki
42852aa32db432085ab2cd4864bd1edd1ef843da867Daniel Lehmann    private int loadLastTabPreference() {
42935d4aec605ce915ff5c574892a2069a37e0b9a77Makoto Onuki        try {
43052aa32db432085ab2cd4864bd1edd1ef843da867Daniel Lehmann            return mPrefs.getInt(PERSISTENT_LAST_TAB, TabState.DEFAULT);
43135d4aec605ce915ff5c574892a2069a37e0b9a77Makoto Onuki        } catch (IllegalArgumentException e) {
43235d4aec605ce915ff5c574892a2069a37e0b9a77Makoto Onuki            // Preference is corrupt?
43352aa32db432085ab2cd4864bd1edd1ef843da867Daniel Lehmann            return TabState.DEFAULT;
43435d4aec605ce915ff5c574892a2069a37e0b9a77Makoto Onuki        }
43535d4aec605ce915ff5c574892a2069a37e0b9a77Makoto Onuki    }
4363c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell
4373c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    private void animateTabHeightChange(int start, int end) {
4383c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        if (mPortraitTabs == null) {
4393c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell            return;
4403c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        }
4413c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        final ValueAnimator animator = ValueAnimator.ofInt(start, end);
4423c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
4433c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell            @Override
4443c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell            public void onAnimationUpdate(ValueAnimator valueAnimator) {
4453c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                int value = (Integer) valueAnimator.getAnimatedValue();
4463c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell                setPortraitTabHeight(value);
4473c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell            }
4483c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        });
4493c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        animator.setDuration(100).start();
4503c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    }
4513c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell
4523c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    private void setPortraitTabHeight(int height) {
4533c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        if (mPortraitTabs == null) {
4543c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell            return;
4553c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        }
4563c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        ViewGroup.LayoutParams layoutParams = mPortraitTabs.getLayoutParams();
4573c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        layoutParams.height = height;
4583c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell        mPortraitTabs.setLayoutParams(layoutParams);
4593c763b3a614375a1dbe273feec5a7664cd5939d3Brian Attwell    }
46008e1c4e49947daee26cfc435d01605febb7ae6faDmitri Plotnikov}
461