如何在Android Wear上调整下巴的布局?

问题描述 投票:2回答:2

在具有“下巴”的Android Wear设备上,屏幕尺寸仍然报告为方形,但是您获得此WindowInsets对象,其中包含有关从屏幕裁剪的内容的信息。

我有一个配置屏幕已经正确获取此值,很容易确认,因为我的视图呈现屏幕形状的轮廓。

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的盒子。

java android android-layout
2个回答
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>

0
投票

Android documentation解释了补偿下巴的正确方法。

您不再需要自定义布局,而是使用根布局上的fitsSystemWindow属性来自动调整填充。

预警,如果您的根布局是RelativeLayout,这种技术不起作用,在这种情况下,您需要替换它或将其包装在FrameLayout中。

© www.soinside.com 2019 - 2024. All rights reserved.