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

标签 java android android-layout

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

我有一个配置屏幕,它已经正确地获取了这个值,很容易确认,因为我的 View 呈现了屏幕形状的轮廓。

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的空间。这会将列表底部和页面指示器置于屏幕底部之外。 我尝试使用 padding 手动将它们移动回来,但 padding 似乎没有效果,我不太清楚为什么。

我也试过让 Config 本身成为一个 BoxInsetLayout 并弄乱哪一侧获得插图,但这似乎并没有在视觉上改变任何东西。

我尝试将 app:layout="bottom" 放在 XML 中的 ConfigView 上,这确实使其适用于下巴布局,但随后添加了不需要的边框没有下巴的时候。

这应该如何运作?这让我有点烦恼,这不仅有效。当我在 1920x1080 显示器上编程时,我不需要做任何特别的事情来裁剪 1920x1920 框。

最佳答案

我还希望填充布局的底部以考虑下巴的大小。我设法通过将所有内容包装在自定义的 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>

关于java - 如何在 Android Wear 上调整下巴布局?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35107436/

相关文章:

android - 以编程方式将 Textview 选取框

android - 如何在布局中使用相同的 css "negative margin"技术?

java - 读取一行忽略特殊值

java - JPA 应用程序管理的持久性上下文数据源配置与 java 没有持久性 xml 文件

android - 从 PlaceAutocomplete 中删除 "Powered by google"

java - 2d手游开发: OpenGL ES 2. 0还是cocos2d-x?

java - 如何以编程方式设置RelativeLayout的layout_constraintTop_toBottomOf “parent”? (安卓)

java - 支柱 2 警告 : The default value expression contains "+" evaluated to 'nullnull'

java - 为什么我们首先需要 isPrimitive() ?

java - 通过在自定义 View 的 onDraw 中设置单位矩阵来抵消 Canvas