summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Dai <sdai@google.com>2019-06-20 14:26:34 -0700
committerandroid-build-merger <android-build-merger@google.com>2019-06-20 14:26:34 -0700
commit21384955e8c83dbb70098a981e1925fc43318191 (patch)
treefc98ac9ef7931e323872dd19679aa6cc61fbe2dc
parent620745687b85e9e749570ff203a38a18dda0a584 (diff)
parent0f5f0bbf031cf0880503e65e0714a8a0deecb74e (diff)
downloadMedia-21384955e8c83dbb70098a981e1925fc43318191.tar.gz
Merge "Update search bar widget" into pi-car-dev
am: 0f5f0bbf03 Change-Id: Iede730aef80fd0aa441a37c5cca4ed337e808988
-rw-r--r--res/layout/appbar_view.xml13
-rw-r--r--res/layout/search_bar.xml52
-rw-r--r--res/values/colors.xml1
-rw-r--r--res/values/dimens.xml2
-rw-r--r--res/values/strings.xml2
-rw-r--r--src/com/android/car/media/MediaActivity.java4
-rw-r--r--src/com/android/car/media/widgets/AppBarView.java77
-rw-r--r--src/com/android/car/media/widgets/SearchBar.java132
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);
+ }
+}