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

Tre*_*kaz 2 java android android-layout

在具有"下巴"的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());
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我现在的问题是组件的定位.布局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>
Run Code Online (Sandbox Code Playgroud)

虽然屏幕被下巴截断,但系统已经给出ConfigView了整个320x320的空间.这会将列表的底部以及页面指示器放在屏幕的底部.我尝试使用填充将它们手动移回,但填充似乎没有效果,我不太清楚为什么.

我也试过让Config自己成为一个BoxInsetLayout混乱哪一方得到插图,但这似乎并没有在视觉上改变任何东西.

我试图把app:layout="bottom"ConfigViewXML中,这也使它成为下巴布局工作,但后来增加了不必要的边界时,有没有下巴.

这应该怎么样?它有点让我觉得这不仅仅是有效的.当我在1920x1080显示器上编程时,我不需要做任何特殊的事情来裁剪1920x1920的盒子.

小智 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我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>
Run Code Online (Sandbox Code Playgroud)