Merge "Adjust layout for Slice InputRange" into rvc-dev

This commit is contained in:
tim peng
2020-03-10 03:04:26 +00:00
committed by Android (Google) Code Review
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> <item name="android:background">?android:attr/colorBackgroundFloating</item>
</style> </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"> <style name="ContextualCardSliceViewStyle" parent="SliceViewStyle">
<item name="android:background">@color/contextual_card_background</item> <item name="android:background">@color/contextual_card_background</item>
</style> </style>

View File

@@ -156,4 +156,9 @@ public class MediaOutputGroupPanel implements PanelContent, LocalMediaManager.De
public int getMetricsCategory() { public int getMetricsCategory() {
return SettingsEnums.PANEL_MEDIA_OUTPUT_GROUP; 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.unregisterCallback(this);
mLocalMediaManager.stopScan(); 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 { public interface PanelContent extends Instrumentable {
int VIEW_TYPE_SLIDER = 1;
/** /**
* @return a icon for the title of the Panel. * @return a icon for the title of the Panel.
*/ */
@@ -101,4 +103,11 @@ public interface PanelContent extends Instrumentable {
* @param callback the callback to add. * @param callback the callback to add.
*/ */
default void registerCallback(PanelContentCallback callback) {} 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 { class LocalPanelCallback implements PanelContentCallback {
@Override @Override

View File

@@ -69,7 +69,12 @@ public class PanelSlicesAdapter
public SliceRowViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) { public SliceRowViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
final Context context = viewGroup.getContext(); final Context context = viewGroup.getContext();
final LayoutInflater inflater = LayoutInflater.from(context); 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); return new SliceRowViewHolder(view);
} }
@@ -87,6 +92,11 @@ public class PanelSlicesAdapter
return Math.min(mSliceLiveData.size(), MAX_NUM_OF_SLICES); 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 * 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. * 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() { public int getMetricsCategory() {
return SettingsEnums.PANEL_VOLUME; 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 CharSequence mSubTitle;
private IconCompat mIcon; private IconCompat mIcon;
private int mViewType;
@Override @Override
public IconCompat getIcon() { public IconCompat getIcon() {
@@ -82,4 +83,13 @@ public class FakePanelContent implements PanelContent {
public int getMetricsCategory() { public int getMetricsCategory() {
return SettingsEnums.TESTING; 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; 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.panel.PanelSlicesAdapter.MAX_NUM_OF_SLICES;
import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI; import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.view.LayoutInflater;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.FrameLayout; import android.widget.FrameLayout;
@@ -36,23 +40,31 @@ import androidx.lifecycle.LiveData;
import androidx.slice.Slice; import androidx.slice.Slice;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.panel.PanelSlicesAdapter.SliceRowViewHolder;
import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric; import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment; import org.robolectric.RuntimeEnvironment;
import org.robolectric.android.controller.ActivityController; 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.LinkedHashMap;
import java.util.Map; import java.util.Map;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
@Config(shadows = PanelSlicesAdapterTest.ShadowLayoutInflater.class)
public class PanelSlicesAdapterTest { public class PanelSlicesAdapterTest {
private static LayoutInflater sLayoutInflater;
private Context mContext; private Context mContext;
private PanelFragment mPanelFragment; private PanelFragment mPanelFragment;
private PanelFeatureProvider mPanelFeatureProvider; private PanelFeatureProvider mPanelFeatureProvider;
@@ -104,7 +116,7 @@ public class PanelSlicesAdapterTest {
final PanelSlicesAdapter adapter = final PanelSlicesAdapter adapter =
new PanelSlicesAdapter(mPanelFragment, mData, 0 /* metrics category */); new PanelSlicesAdapter(mPanelFragment, mData, 0 /* metrics category */);
final ViewGroup view = new FrameLayout(mContext); final ViewGroup view = new FrameLayout(mContext);
final PanelSlicesAdapter.SliceRowViewHolder viewHolder = final SliceRowViewHolder viewHolder =
adapter.onCreateViewHolder(view, 0); adapter.onCreateViewHolder(view, 0);
assertThat(adapter.getItemCount()).isEqualTo(MAX_NUM_OF_SLICES); assertThat(adapter.getItemCount()).isEqualTo(MAX_NUM_OF_SLICES);
@@ -119,11 +131,52 @@ public class PanelSlicesAdapterTest {
new PanelSlicesAdapter(mPanelFragment, mData, 0 /* metrics category */); new PanelSlicesAdapter(mPanelFragment, mData, 0 /* metrics category */);
final int position = 0; final int position = 0;
final ViewGroup view = new FrameLayout(mContext); final ViewGroup view = new FrameLayout(mContext);
final PanelSlicesAdapter.SliceRowViewHolder viewHolder = final SliceRowViewHolder viewHolder =
adapter.onCreateViewHolder(view, 0 /* view type*/); adapter.onCreateViewHolder(view, 0 /* view type*/);
adapter.onBindViewHolder(viewHolder, position); adapter.onBindViewHolder(viewHolder, position);
assertThat(viewHolder.isDividerAllowedAbove()).isFalse(); 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;
}
}
} }