diff options
author | Simon Dai <sdai@google.com> | 2019-06-20 14:26:34 -0700 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2019-06-20 14:26:34 -0700 |
commit | 21384955e8c83dbb70098a981e1925fc43318191 (patch) | |
tree | fc98ac9ef7931e323872dd19679aa6cc61fbe2dc | |
parent | 620745687b85e9e749570ff203a38a18dda0a584 (diff) | |
parent | 0f5f0bbf031cf0880503e65e0714a8a0deecb74e (diff) | |
download | Media-21384955e8c83dbb70098a981e1925fc43318191.tar.gz |
Merge "Update search bar widget" into pi-car-dev
am: 0f5f0bbf03
Change-Id: Iede730aef80fd0aa441a37c5cca4ed337e808988
-rw-r--r-- | res/layout/appbar_view.xml | 13 | ||||
-rw-r--r-- | res/layout/search_bar.xml | 52 | ||||
-rw-r--r-- | res/values/colors.xml | 1 | ||||
-rw-r--r-- | res/values/dimens.xml | 2 | ||||
-rw-r--r-- | res/values/strings.xml | 2 | ||||
-rw-r--r-- | src/com/android/car/media/MediaActivity.java | 4 | ||||
-rw-r--r-- | src/com/android/car/media/widgets/AppBarView.java | 77 | ||||
-rw-r--r-- | src/com/android/car/media/widgets/SearchBar.java | 132 |
8 files changed, 211 insertions, 72 deletions
diff --git a/res/layout/appbar_view.xml b/res/layout/appbar_view.xml index 5f53224..232db86 100644 --- a/res/layout/appbar_view.xml +++ b/res/layout/appbar_view.xml @@ -47,21 +47,18 @@ android:id="@+id/tabs" style="@style/AppBarTabStyle"/> - <EditText - android:id="@+id/search_bar" + <com.android.car.media.widgets.SearchBar + android:id="@+id/search_bar_container" android:layout_height="0dp" android:layout_width="0dp" android:layout_marginStart="@dimen/appbar_view_nav_button_width" - android:hint="@string/search_hint" - android:inputType="text" - android:singleLine="true" - android:imeOptions="actionDone" + android:layout_marginEnd="@dimen/app_switch_widget_width" android:visibility="gone" - android:cursorVisible="false" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@id/row_separator" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintEnd_toStartOf="@+id/search"/> + app:layout_constraintEnd_toEndOf="parent"> + </com.android.car.media.widgets.SearchBar> <ImageView android:id="@+id/search" diff --git a/res/layout/search_bar.xml b/res/layout/search_bar.xml new file mode 100644 index 0000000..43041d9 --- /dev/null +++ b/res/layout/search_bar.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright 2019 The Android Open Source Project + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<merge + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + <com.android.car.media.common.MediaAppSelectorWidget + android:id="@+id/app_icon_container" + android:layout_width="@dimen/appbar_view_icon_touch_target_size" + android:layout_height="@dimen/appbar_view_icon_touch_target_size" + android:padding="@dimen/app_switch_widget_icon_padding" + android:orientation="horizontal" + android:gravity="center" + android:background="@drawable/appbar_view_icon_background" + app:switchingEnabled="false"/> + + <EditText + android:id="@+id/search_bar" + android:layout_height="match_parent" + android:layout_width="match_parent" + android:paddingLeft="@dimen/appbar_view_icon_touch_target_size" + android:layout_marginLeft="@dimen/appbar_view_search_margin" + android:hint="@string/search_hint" + android:textColorHint="@color/search_hint_text_color" + android:inputType="text" + android:singleLine="true" + android:imeOptions="actionDone" + android:cursorVisible="false"/> + + <ImageView + android:id="@+id/search_close" + android:layout_width="@dimen/appbar_view_icon_touch_target_size" + android:layout_height="@dimen/appbar_view_icon_touch_target_size" + android:layout_marginLeft="@dimen/appbar_view_search_margin" + android:padding="@dimen/appbar_view_icon_padding" + android:background="@drawable/appbar_view_icon_background" + android:src="@drawable/ic_close"/> +</merge>
\ No newline at end of file diff --git a/res/values/colors.xml b/res/values/colors.xml index 25a86bc..d7a6046 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -37,6 +37,7 @@ <!-- appbar_view.xml --> <color name="appbar_view_icon_tint">@color/primary_app_icon_color</color> <color name="appbar_view_settings_tint">@color/uxr_button_image_color_selector</color> + <color name="search_hint_text_color">#33FFFFFF</color> <!-- fragment_metadata.xml --> <color name="fragment_metadata_queue_divider_color">@*android:color/car_list_divider_light diff --git a/res/values/dimens.xml b/res/values/dimens.xml index c1b9c85..5231544 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -78,6 +78,8 @@ <dimen name="appbar_view_control_buttons_spacing">@*android:dimen/car_padding_3</dimen> <dimen name="appbar_view_control_buttons_margin_end">@*android:dimen/car_padding_2</dimen> <dimen name="appbar_view_title_margin_start">@*android:dimen/car_padding_2</dimen> + <!-- negative margin to overlap icons on search bar --> + <dimen name="appbar_view_search_margin">-96dp</dimen> <!-- browse_state.xml --> <dimen name="browse_state_progress_height">@*android:dimen/car_double_line_list_item_height diff --git a/res/values/strings.xml b/res/values/strings.xml index 2b7b18d..c5d557c 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -31,7 +31,7 @@ <!-- Media template title --> <string name="media_app_title">Media</string> <!-- Search input hint text. [CHAR LIMIT=20] --> - <string name="search_hint">Search</string> + <string name="search_hint">Search songs, artists, and more...</string> <!-- Error Fragment error message [CHAR LIMIT=100] --> <string name="default_error_message">Unknown application error</string> <!-- Title to display when in playback view. [CHAR LIMIT=50] --> diff --git a/src/com/android/car/media/MediaActivity.java b/src/com/android/car/media/MediaActivity.java index 942c2d6..7515e70 100644 --- a/src/com/android/car/media/MediaActivity.java +++ b/src/com/android/car/media/MediaActivity.java @@ -63,6 +63,7 @@ import com.android.car.media.common.playback.PlaybackViewModel; import com.android.car.media.common.source.MediaSource; import com.android.car.media.common.source.MediaSourceViewModel; import com.android.car.media.widgets.AppBarView; +import com.android.car.media.widgets.SearchBar; import java.util.List; import java.util.Objects; @@ -200,6 +201,9 @@ public class MediaActivity extends FragmentActivity implements BrowseFragment.Ca MediaAppSelectorWidget appSelector = findViewById(R.id.app_switch_container); appSelector.setFragmentActivity(this); + SearchBar searchBar = findViewById(R.id.search_bar_container); + searchBar.setFragmentActivity(this); + searchBar.setAppBarListener(mAppBarListener); mEmptyFragment = new EmptyFragment(); MediaBrowserViewModel mediaBrowserViewModel = getRootBrowserViewModel(); diff --git a/src/com/android/car/media/widgets/AppBarView.java b/src/com/android/car/media/widgets/AppBarView.java index ce604f6..3bfd06b 100644 --- a/src/com/android/car/media/widgets/AppBarView.java +++ b/src/com/android/car/media/widgets/AppBarView.java @@ -3,17 +3,11 @@ package com.android.car.media.widgets; import android.annotation.Nullable; import android.content.Context; import android.graphics.drawable.Drawable; -import android.text.Editable; -import android.text.TextUtils; -import android.text.TextWatcher; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; @@ -46,7 +40,7 @@ public class AppBarView extends ConstraintLayout { private boolean mHasSettings; private boolean mShowSettings; private View mSearchButton; - private EditText mSearchText; + private SearchBar mSearchBar; private MediaAppSelectorWidget mAppSelector; private Context mContext; private int mMaxTabs; @@ -170,42 +164,7 @@ public class AppBarView extends ConstraintLayout { mSettingsButton.setOnClickListener(view -> onSettingsClicked()); mSearchButton = findViewById(R.id.search); mSearchButton.setOnClickListener(view -> onSearchClicked()); - - mSearchText = findViewById(R.id.search_bar); - mSearchText.setOnFocusChangeListener( - (view, hasFocus) -> { - if (hasFocus) { - mSearchText.setCursorVisible(true); - ((InputMethodManager) - context.getSystemService(Context.INPUT_METHOD_SERVICE)) - .showSoftInput(view, 0); - } else { - mSearchText.setCursorVisible(false); - ((InputMethodManager) - context.getSystemService(Context.INPUT_METHOD_SERVICE)) - .hideSoftInputFromWindow(view.getWindowToken(), 0); - } - }); - mSearchText.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { - } - - @Override - public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { - } - - @Override - public void afterTextChanged(Editable editable) { - onSearch(editable.toString()); - } - }); - mSearchText.setOnEditorActionListener((v, actionId, event) -> { - if (actionId == EditorInfo.IME_ACTION_DONE) { - mSearchText.setCursorVisible(false); - } - return false; - }); + mSearchBar = findViewById(R.id.search_bar_container); mTitle = findViewById(R.id.title); mArrowBack = getResources().getDrawable(R.drawable.ic_arrow_back, null); @@ -234,7 +193,7 @@ public class AppBarView extends ConstraintLayout { mListener.onBack(); break; case SEARCHING: - hideSearchBar(); + mSearchBar.showSearchBar(false); case PLAYING: mListener.onCollapse(); break; @@ -255,13 +214,6 @@ public class AppBarView extends ConstraintLayout { mListener.onSearchSelection(); } - private void onSearch(String query) { - if (mListener == null || TextUtils.isEmpty(query)) { - return; - } - mListener.onSearch(query); - } - /** * Sets a listener of this application bar events. In order to avoid memory leaks, consumers * must reset this reference by setting the listener to null. @@ -373,43 +325,42 @@ public class AppBarView extends ConstraintLayout { mNavIconContainer.setVisibility(View.GONE); setShowTabs(false); mTitle.setVisibility(View.GONE); - hideSearchBar(); + mSearchBar.showSearchBar(false); showSettings(true); + mAppSelector.setVisibility(View.VISIBLE); break; case BROWSING: mNavIcon.setImageDrawable(mArrowBack); mNavIconContainer.setVisibility(View.GONE); setShowTabs(hasTabs); mTitle.setVisibility(showTitle ? View.VISIBLE : View.GONE); - hideSearchBar(); + mSearchBar.showSearchBar(false); mSearchButton.setVisibility(mSearchSupported ? View.VISIBLE : View.GONE); showSettings(true); + mAppSelector.setVisibility(View.VISIBLE); break; case STACKED: mNavIcon.setImageDrawable(mArrowBack); mNavIconContainer.setVisibility(View.VISIBLE); setShowTabs(false); mTitle.setVisibility(View.VISIBLE); - hideSearchBar(); + mSearchBar.showSearchBar(false); mSearchButton.setVisibility(mSearchSupported ? View.VISIBLE : View.GONE); showSettings(true); + mAppSelector.setVisibility(View.VISIBLE); break; case PLAYING: break; case SEARCHING: - mNavIcon.setImageDrawable(mCollapse); + mNavIcon.setImageDrawable(mArrowBack); mNavIconContainer.setVisibility(View.VISIBLE); setShowTabs(false); mTitle.setVisibility(View.GONE); - mSearchText.setVisibility(View.VISIBLE); - mSearchText.requestFocus(); - showSettings(true); + mSearchBar.showSearchBar(true); + mSearchButton.setVisibility(View.GONE); + showSettings(false); + mAppSelector.setVisibility(View.GONE); break; } } - - private void hideSearchBar() { - mSearchText.setVisibility(View.GONE); - mSearchText.getText().clear(); - } } diff --git a/src/com/android/car/media/widgets/SearchBar.java b/src/com/android/car/media/widgets/SearchBar.java new file mode 100644 index 0000000..0a5e09a --- /dev/null +++ b/src/com/android/car/media/widgets/SearchBar.java @@ -0,0 +1,132 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.car.media.widgets; + +import android.content.Context; +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; + +import androidx.fragment.app.FragmentActivity; + +import com.android.car.media.R; +import com.android.car.media.common.MediaAppSelectorWidget; + +/** + * This widget represents a search bar that shows the media source's icon as part of the search bar + */ +public class SearchBar extends LinearLayout { + + private final MediaAppSelectorWidget mAppIcon; + private final EditText mSearchText; + private final ImageView mCloseIcon; + + private AppBarView.AppBarListener mListener; + + public SearchBar(Context context) { + this(context, null); + } + + public SearchBar(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public SearchBar(Context context, AttributeSet attrs, int defStyleAttr) { + this(context, attrs, defStyleAttr, 0); + } + + public SearchBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + + LayoutInflater inflater = LayoutInflater.from(context); + inflater.inflate(R.layout.search_bar, this, true); + + mSearchText = findViewById(R.id.search_bar); + mCloseIcon = findViewById(R.id.search_close); + mCloseIcon.setOnClickListener(view -> mSearchText.getText().clear()); + mAppIcon = findViewById(R.id.app_icon_container); + + mSearchText.setOnFocusChangeListener( + (view, hasFocus) -> { + if (hasFocus) { + mSearchText.setCursorVisible(true); + ((InputMethodManager) + context.getSystemService(Context.INPUT_METHOD_SERVICE)) + .showSoftInput(view, 0); + } else { + mSearchText.setCursorVisible(false); + ((InputMethodManager) + context.getSystemService(Context.INPUT_METHOD_SERVICE)) + .hideSoftInputFromWindow(view.getWindowToken(), 0); + } + }); + mSearchText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + } + + @Override + public void afterTextChanged(Editable editable) { + onSearch(editable.toString()); + } + }); + mSearchText.setOnEditorActionListener((v, actionId, event) -> { + if (actionId == EditorInfo.IME_ACTION_DONE) { + mSearchText.setCursorVisible(false); + } + return false; + }); + } + + /** Calling this is required so the widget can show the icon of the primary media source. */ + public void setFragmentActivity(FragmentActivity activity) { + + mAppIcon.setFragmentActivity(activity); + } + + public void setAppBarListener(AppBarView.AppBarListener listener) { + mListener = listener; + } + + public void showSearchBar(boolean visible) { + if (visible) { + setVisibility(VISIBLE); + mSearchText.requestFocus(); + } else{ + setVisibility(GONE); + mSearchText.getText().clear(); + } + } + + private void onSearch(String query) { + if (mListener == null || TextUtils.isEmpty(query)) { + return; + } + mListener.onSearch(query); + } +} |