Merge "Search results page polish" into oc-dr1-dev

This commit is contained in:
TreeHugger Robot
2017-06-27 16:53:52 +00:00
committed by Android (Google) Code Review
7 changed files with 75 additions and 172 deletions

View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 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.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:inset="0dip">
<color android:color="?android:attr/colorBackground" />
</inset>

View File

@@ -13,19 +13,50 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<RelativeLayout
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/search_panel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/search_panel_list_background">
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/material_grey_300">
<android.support.v7.widget.CardView
android:id="@+id/search_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/search_bar_margin"
app:cardCornerRadius="2dp"
app:cardBackgroundColor="?android:attr/colorBackground"
app:cardElevation="2dp">
<Toolbar
android:id="@+id/search_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:contentInsetStart="0dp"
android:contentInsetStartWithNavigation="0dp"
android:theme="?android:attr/actionBarTheme">
<SearchView
android:id="@+id/search_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:iconifiedByDefault="false"
android:imeOptions="actionSearch|flagNoExtractUi"
android:searchIcon="@null"/>
</Toolbar>
</android.support.v7.widget.CardView>
</FrameLayout>
<FrameLayout
android:id="@+id/layout_results"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/feedback_popup"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical">
<!-- Padding is included in the background -->
@@ -68,27 +99,8 @@
</LinearLayout>
<android.support.v7.widget.CardView
android:id="@+id/search_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/search_bar_margin"
app:cardCornerRadius="2dp"
app:cardBackgroundColor="?android:attr/colorBackground"
app:cardElevation="2dp">
<SearchView
android:id="@+id/search_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:iconifiedByDefault="false"
android:imeOptions="actionSearch|flagNoExtractUi"
android:theme="?android:attr/actionBarTheme"/>
</android.support.v7.widget.CardView>
</FrameLayout>
<include layout="@layout/search_feedback"/>
</RelativeLayout>
</LinearLayout>

View File

@@ -1,43 +0,0 @@
/*
* Copyright (C) 2017 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.settings.search;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import com.android.settings.R;
public class HeaderDecorator extends RecyclerView.ItemDecoration {
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
if (parent.getChildAdapterPosition(view) > 0) {
return;
}
Context context = view.getContext();
TypedArray ta = context.obtainStyledAttributes(new int[]{android.R.attr.actionBarSize});
outRect.top = ta.getDimensionPixelSize(0, 0);
ta.recycle();
outRect.top += 2 * context.getResources().getDimensionPixelSize(R.dimen.search_bar_margin);
}
}

View File

@@ -36,6 +36,8 @@ import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.LinearLayout;
import android.widget.SearchView;
import android.widget.TextView;
import android.widget.Toolbar;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
@@ -168,14 +170,32 @@ public class SearchFragment extends InstrumentedFragment implements SearchView.O
mResultsRecyclerView.setAdapter(mSearchAdapter);
mResultsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mResultsRecyclerView.addOnScrollListener(mScrollListener);
mResultsRecyclerView.addItemDecoration(new HeaderDecorator());
mNoResultsView = view.findViewById(R.id.no_results_layout);
mSearchView = view.findViewById(R.id.search_view);
Toolbar toolbar = view.findViewById(R.id.search_toolbar);
getActivity().setActionBar(toolbar);
getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
mSearchView = toolbar.findViewById(R.id.search_view);
mSearchView.setQuery(mQuery, false /* submitQuery */);
mSearchView.setOnQueryTextListener(this);
mSearchView.requestFocus();
// Updating internal views inside SearchView was the easiest way to get this too look right.
// We null-check here so that tests pass since the robotests can't find the internal views.
TextView searchText = mSearchView.findViewById(com.android.internal.R.id.search_src_text);
if (searchText != null) {
searchText.setTextColor(getContext().getColorStateList(
com.android.internal.R.color.text_color_primary));
}
View editFrame = mSearchView.findViewById(com.android.internal.R.id.search_edit_frame);
if (editFrame != null) {
ViewGroup.MarginLayoutParams params =
(ViewGroup.MarginLayoutParams) editFrame.getLayoutParams();
params.setMarginStart(0);
editFrame.setLayoutParams(params);
}
return view;
}

View File

@@ -1,80 +0,0 @@
/*
* Copyright (C) 2017 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.settings.search;
import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import com.android.settings.R;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.when;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class HeaderDecoratorTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private View mView;
@Mock
private RecyclerView mRecyclerView;
@Mock
private RecyclerView.LayoutParams mLayoutParams;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mView.getLayoutParams()).thenReturn(mLayoutParams);
}
@Test
public void testgetItemOffsets_positionZero_headerAdded() {
HeaderDecorator decorator = new HeaderDecorator();
Rect outRect = new Rect();
when(mRecyclerView.getChildAdapterPosition(any(View.class))).thenReturn(0);
when(mView.getContext().obtainStyledAttributes(any(int[].class))
.getDimensionPixelSize(0, 0)).thenReturn(20);
when(mView.getContext().getResources().getDimensionPixelSize(R.dimen.search_bar_margin))
.thenReturn(5);
decorator.getItemOffsets(outRect, mView, mRecyclerView, null);
assertThat(outRect).isEqualTo(new Rect(0, 30, 0, 0));
}
@Test
public void testgetItemOffsets_positionGreaterThanZero_noDecoration() {
HeaderDecorator decorator = new HeaderDecorator();
Rect outRect = new Rect();
when(mRecyclerView.getChildAdapterPosition(any(View.class))).thenReturn(1);
decorator.getItemOffsets(outRect, mView, mRecyclerView, null);
assertThat(outRect).isEqualTo(new Rect(0, 0, 0, 0));
}
}

View File

@@ -32,6 +32,7 @@ import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.testutils.DatabaseTestUtils;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import org.junit.After;
import org.junit.Before;
@@ -66,7 +67,12 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
@Config(manifest = TestConfig.MANIFEST_PATH,
sdk = TestConfig.SDK_VERSION,
shadows = {
SettingsShadowResources.class,
SettingsShadowResources.SettingsShadowTheme.class,
})
public class SearchFragmentTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)

View File

@@ -7,6 +7,7 @@ import static org.robolectric.Shadows.shadowOf;
import static org.robolectric.internal.Shadow.directlyOn;
import android.annotation.DimenRes;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.content.res.Resources.Theme;
@@ -87,6 +88,15 @@ public class SettingsShadowResources extends ShadowResources {
return directlyOn(realResources, Resources.class).getColor(id, theme);
}
@Implementation
public ColorStateList getColorStateList(@ColorRes int id, @Nullable Theme theme)
throws NotFoundException {
if (id == com.android.internal.R.color.text_color_primary) {
return ColorStateList.valueOf(Color.WHITE);
}
return directlyOn(realResources, Resources.class).getColorStateList(id, theme);
}
@Implementation
public Drawable loadDrawable(TypedValue value, int id, Theme theme)
throws NotFoundException {