在带有" chin"的Android Wear设备上,屏幕尺寸仍然会报告为方形,但您会收到此WindowInsets
对象,其中包含有关从屏幕裁剪的内容的信息。< / p>
我有一个配置屏幕已经正确获取此值,很容易确认,因为我的视图呈现了屏幕形状的轮廓。
public class ConfigView extends FrameLayout {
private Rect lastBounds = new Rect();
private WindowInsets lastWindowInsets;
//... omitting initialisation
@Override
protected void onFinishInflate() {
super.onFinishInflate();
requestApplyInsets();
// omitting other stuff not relevant to this
GridViewPager pager =
(GridViewPager) findViewById(R.id.pager);
DotsPageIndicator dotsPageIndicator =
(DotsPageIndicator) findViewById(R.id.page_indicator);
dotsPageIndicator.setPager(pager);
}
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
WindowInsets result = super.onApplyWindowInsets(insets);
lastWindowInsets = insets;
maybeInitialiseViews();
return result;
}
@Override
protected void onLayout(boolean changed, int left, int top,
int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
lastBounds.set(left, top, right, bottom);
maybeInitialiseViews();
}
private void maybeInitialiseViews() {
if (lastWindowInsets != null && !lastBounds.isEmpty()) {
GridViewPager pager =
(GridViewPager) findViewById(R.id.pager);
if (pager.getAdapter() == null) {
// TODO: Maybe there is a better callback I can rely on
// being done on every layout but not before applying
// insets, but a failure occurs later if we initialise
// the adapter before we have both bits of info.
pager.setAdapter(new ConfigGridPagerAdapter());
}
}
}
}
我现在的问题是组件的定位。布局XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.BoxInsetLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<example.ConfigView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.wearable.view.GridViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
android:nestedScrollingEnabled="false"/>
<android.support.wearable.view.DotsPageIndicator
android:id="@+id/page_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
app:dotFadeWhenIdle="false"/>
</example.ConfigView>
</android.support.wearable.view.BoxInsetLayout>
虽然屏幕被下巴截断,但系统给出了ConfigView
整个320x320的空间。这会将列表的底部以及页面指示器放在屏幕的底部。
我尝试使用填充将它们手动移回,但填充似乎没有效果,我不太清楚为什么。
我还尝试将Config
本身设为BoxInsetLayout
并弄乱了哪一方获得了插图,但这似乎并没有在视觉上改变任何内容。
我尝试将app:layout="bottom"
放在XML中的ConfigView
上,这确实使其适用于下巴布局,但是当没有下巴时会添加不需要的边框。
这应该如何运作?这有点让我感到不舒服。当我在1920x1080显示器上进行编程时,我不需要做任何特别的事情来裁剪1920x1920的盒子。
答案 0 :(得分:6)
我还希望在我的布局底部填充以考虑下巴的大小。我设法通过将所有内容包装在自定义的FrameLayout中并在onApplyWindowInsets()
中设置填充来实现此目的。
public class ChinLayout extends FrameLayout {
public ChinLayout(Context context) {
super(context);
}
public ChinLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ChinLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ChinLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
int chin = insets.getSystemWindowInsetBottom();
setPadding(0, 0, 0, chin);
return insets;
}
}
然后我在我的层次结构的根目录中使用了ChinLayout
:
<?xml version="1.0" encoding="utf-8"?>
<ChinLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- View hierarchy to fit above the chin goes here. -->
</ChinLayout>
答案 1 :(得分:0)
Android documentation中解释了补偿下巴的正确方法。
您不再需要自定义布局,而是使用根布局上的fitsSystemWindow
属性来自动调整填充。
事先警告,如果您的根布局是RelativeLayout
,则此技术不起作用,在这种情况下,您需要替换它或将其包装在FrameLayout
中。