Adjust layout for Slice InputRange

-Make title to slider aligned
-Add test cases

Bug: 147462114
Test: make -j50 RunSettingsRoboTests
Change-Id: Ib1d076f77eae75e4f861a80873117b6254729fe5
This commit is contained in:
Tim Peng
2020-03-01 11:34:16 +08:00
parent 5a4257deb4
commit db7d61d0a2
10 changed files with 145 additions and 3 deletions

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2020 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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.slice.widget.SliceView
android:id="@+id/slice_view"
style="@style/SliceViewSliderStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="8dp"
android:paddingEnd="8dp"/>
</LinearLayout>

View File

@@ -512,6 +512,17 @@
<item name="android:background">?android:attr/colorBackgroundFloating</item>
</style>
<style name="SliceViewSliderStyle">
<item name="rowStyle">@style/SliceRowSliderStyle</item>
<item name="android:background">?android:attr/colorBackgroundFloating</item>
</style>
<style name="SliceRowSliderStyle" parent="SliceRowStyle">
<!-- Align text with slider -->
<item name="titleStartPadding">12dp</item>
<item name="subContentStartPadding">12dp</item>
</style>
<style name="ContextualCardSliceViewStyle" parent="SliceViewStyle">
<item name="android:background">@color/contextual_card_background</item>
</style>

View File

@@ -156,4 +156,9 @@ public class MediaOutputGroupPanel implements PanelContent, LocalMediaManager.De
public int getMetricsCategory() {
return SettingsEnums.PANEL_MEDIA_OUTPUT_GROUP;
}
@Override
public int getViewType() {
return PanelContent.VIEW_TYPE_SLIDER;
}
}

View File

@@ -240,4 +240,9 @@ public class MediaOutputPanel implements PanelContent, LocalMediaManager.DeviceC
mLocalMediaManager.unregisterCallback(this);
mLocalMediaManager.stopScan();
}
@Override
public int getViewType() {
return PanelContent.VIEW_TYPE_SLIDER;
}
}

View File

@@ -30,6 +30,8 @@ import java.util.List;
*/
public interface PanelContent extends Instrumentable {
int VIEW_TYPE_SLIDER = 1;
/**
* @return a icon for the title of the Panel.
*/
@@ -101,4 +103,11 @@ public interface PanelContent extends Instrumentable {
* @param callback the callback to add.
*/
default void registerCallback(PanelContentCallback callback) {}
/**
* @return a view type to customized it. 0 for default layout.
*/
default int getViewType() {
return 0;
}
}

View File

@@ -411,6 +411,10 @@ public class PanelFragment extends Fragment {
};
}
int getPanelViewType() {
return mPanel.getViewType();
}
class LocalPanelCallback implements PanelContentCallback {
@Override

View File

@@ -69,7 +69,12 @@ public class PanelSlicesAdapter
public SliceRowViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
final Context context = viewGroup.getContext();
final LayoutInflater inflater = LayoutInflater.from(context);
final View view = inflater.inflate(R.layout.panel_slice_row, viewGroup, false);
View view;
if (viewType == PanelContent.VIEW_TYPE_SLIDER) {
view = inflater.inflate(R.layout.panel_slice_slider_row, viewGroup, false);
} else {
view = inflater.inflate(R.layout.panel_slice_row, viewGroup, false);
}
return new SliceRowViewHolder(view);
}
@@ -87,6 +92,11 @@ public class PanelSlicesAdapter
return Math.min(mSliceLiveData.size(), MAX_NUM_OF_SLICES);
}
@Override
public int getItemViewType(int position) {
return mPanelFragment.getPanelViewType();
}
/**
* Return the available data from the adapter. If the number of Slices over the max number
* allowed, the list will only have the first MAX_NUM_OF_SLICES of slices.

View File

@@ -73,4 +73,9 @@ public class VolumePanel implements PanelContent {
public int getMetricsCategory() {
return SettingsEnums.PANEL_VOLUME;
}
@Override
public int getViewType() {
return PanelContent.VIEW_TYPE_SLIDER;
}
}

View File

@@ -44,6 +44,7 @@ public class FakePanelContent implements PanelContent {
private CharSequence mSubTitle;
private IconCompat mIcon;
private int mViewType;
@Override
public IconCompat getIcon() {
@@ -82,4 +83,13 @@ public class FakePanelContent implements PanelContent {
public int getMetricsCategory() {
return SettingsEnums.TESTING;
}
public void setViewType(int viewType) {
mViewType = viewType;
}
@Override
public int getViewType() {
return mViewType;
}
}

View File

@@ -16,19 +16,23 @@
package com.android.settings.panel;
import static com.android.settings.panel.PanelContent.VIEW_TYPE_SLIDER;
import static com.android.settings.panel.PanelSlicesAdapter.MAX_NUM_OF_SLICES;
import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.FrameLayout;
@@ -36,23 +40,31 @@ import androidx.lifecycle.LiveData;
import androidx.slice.Slice;
import com.android.settings.R;
import com.android.settings.panel.PanelSlicesAdapter.SliceRowViewHolder;
import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.android.controller.ActivityController;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import java.util.LinkedHashMap;
import java.util.Map;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = PanelSlicesAdapterTest.ShadowLayoutInflater.class)
public class PanelSlicesAdapterTest {
private static LayoutInflater sLayoutInflater;
private Context mContext;
private PanelFragment mPanelFragment;
private PanelFeatureProvider mPanelFeatureProvider;
@@ -104,7 +116,7 @@ public class PanelSlicesAdapterTest {
final PanelSlicesAdapter adapter =
new PanelSlicesAdapter(mPanelFragment, mData, 0 /* metrics category */);
final ViewGroup view = new FrameLayout(mContext);
final PanelSlicesAdapter.SliceRowViewHolder viewHolder =
final SliceRowViewHolder viewHolder =
adapter.onCreateViewHolder(view, 0);
assertThat(adapter.getItemCount()).isEqualTo(MAX_NUM_OF_SLICES);
@@ -119,11 +131,52 @@ public class PanelSlicesAdapterTest {
new PanelSlicesAdapter(mPanelFragment, mData, 0 /* metrics category */);
final int position = 0;
final ViewGroup view = new FrameLayout(mContext);
final PanelSlicesAdapter.SliceRowViewHolder viewHolder =
final SliceRowViewHolder viewHolder =
adapter.onCreateViewHolder(view, 0 /* view type*/);
adapter.onBindViewHolder(viewHolder, position);
assertThat(viewHolder.isDividerAllowedAbove()).isFalse();
}
@Test
public void onCreateViewHolder_viewTypeSlider_verifyLayout() {
final PanelSlicesAdapter adapter =
new PanelSlicesAdapter(mPanelFragment, mData, 0);
final ViewGroup view = new FrameLayout(mContext);
final ArgumentCaptor<Integer> intArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
adapter.onCreateViewHolder(view, VIEW_TYPE_SLIDER);
verify(sLayoutInflater).inflate(intArgumentCaptor.capture(), eq(view), eq(false));
assertThat(intArgumentCaptor.getValue()).isEqualTo(R.layout.panel_slice_slider_row);
}
@Test
public void onCreateViewHolder_viewTypeDefault_verifyLayout() {
final PanelSlicesAdapter adapter =
new PanelSlicesAdapter(mPanelFragment, mData, 0);
final ViewGroup view = new FrameLayout(mContext);
final ArgumentCaptor<Integer> intArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
adapter.onCreateViewHolder(view, 0);
verify(sLayoutInflater).inflate(intArgumentCaptor.capture(), eq(view), eq(false));
assertThat(intArgumentCaptor.getValue()).isEqualTo(R.layout.panel_slice_row);
}
@Implements(LayoutInflater.class)
public static class ShadowLayoutInflater {
@Implementation
public static LayoutInflater from(Context context) {
final LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (inflater == null) {
throw new AssertionError("LayoutInflater not found.");
}
sLayoutInflater = spy(inflater);
return sLayoutInflater;
}
}
}