android - 您可以在 Android Wear 的 GridViewPager 中使用 WatchViewStub 吗?

标签 android wear-os

我有一个单独运行良好的 WatchViewStub - 它在适当的方形或圆形 android wear 模拟器上显示正确的布局。但是,当我尝试在 GridViewPager 中使用 WatchViewStub 时,即使在圆形模拟器上,它也始终显示正方形(或矩形)布局。两者结合使用是否可以成功?

下面是一些代码 fragment :

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_wear);

    GridViewPager pager = (GridViewPager) findViewById(R.id.activity_wear_pager);
    pager.setAdapter(new gridViewPagerAdapter());

    DotsPageIndicator dotsPageIndicator = (DotsPageIndicator) findViewById(R.id.activity_wear_page_indicator);
    dotsPageIndicator.setPager(pager);
}

这是 gridViewPagerAdapter:

private class gridViewPagerAdapter extends GridPagerAdapter {
    @Override
    public int getColumnCount(int arg0) { return 2; }

    @Override
    public int getRowCount() { return 1; }

    @Override
    protected Object instantiateItem(ViewGroup container, int row, int col) {
        View view = null;

        if (col == 0) {
            view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.read_page_stub, container, false);
            WatchViewStub stub = (WatchViewStub) view.findViewById(R.id.read_page_stub);
            stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
                @Override
                public void onLayoutInflated(WatchViewStub stub) {
                }
            });
        }
        else {
            view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.find_page_stub, container, false);
            WatchViewStub stub = (WatchViewStub) view.findViewById(R.id.find_page_stub);
            stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
                @Override
                public void onLayoutInflated(WatchViewStub stub) {
                }
            });
        }

        container.addView(view);
        return view;
    }

    @Override
    protected void destroyItem(ViewGroup container, int row, int col, Object view) {
        container.removeView((View)view);
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view==object;
    }
}

这里是 activity_wear.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <android.support.wearable.view.GridViewPager
        android:id="@+id/activity_wear_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:keepScreenOn="true"/>

    <android.support.wearable.view.DotsPageIndicator
        android:id="@+id/activity_wear_page_indicator"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|bottom">
    </android.support.wearable.view.DotsPageIndicator>

</FrameLayout>

这里是 read_page_stub.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.WatchViewStub
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/read_page_stub"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:rectLayout="@layout/read_page_rect"
    app:roundLayout="@layout/read_page_round"
    tools:context=".WearApplication"
    tools:deviceIds="wear">
</android.support.wearable.view.WatchViewStub>

然后我有两个布局和我的 View 。他们开始于:

read_page_rect.xml:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/scroll"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".WearApplication"
    tools:deviceIds="wear_square">

read_page_round.xml:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/scroll"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".WearApplication"
    tools:deviceIds="wear_round">

我为 find_page_stub、find_page_rect 和 find_page_round 设置了相同类型的布局。

最佳答案

如果 WatchViewStub 没有显示圆形布局,则意味着它没有正确接收到 WindowInsets 对象。 GridViewPager 必须在途中某处使用它。

您可以尝试修复它。这样做的方法是(首先是一些理论):

1) 首先阅读关于 View.dispatchApplyWindowInsets 的内容和 View.onApplyWindowInsets

2) 这两个方法在 View 中的关联方式是这样的: dispatchApplyWindowInsets 被调用并检查是否有监听器;如果是,它只将 WindowInsets 传递给 listener;如果不是,它会将 WindowInsets 传递给 onApplyWindowInsets

3) 在 ViewGroup 中(GridViewPager 是一个 ViewGroup),它迭代子项并检查 insets 是否被消耗;如果是,它会停止传送它们;

4) 在任何时候,任何View/ViewGroup 都可以决定停止传送WindowInsets;当它这样做时,任何依赖它的 child 都不会在回合中表现得很好;

现在一些练习:

5) 您可以为层次结构中的任何 View 创建子类;使用 GridViewPager 执行此操作并开始尝试覆盖 dispatchApplyWindowInsetsonApplyWindowInsets。我的猜测是第一个应该足够了。

6) 在 dispatchApplyWindowInsets 的重写中迭代子级并调用 dispatchApplyWindowInsets 给他们中的每一个;这样 WatchViewStub 应该接收未改变的 WindowInsets 和之前的 isRound()->true 方法

7) 最后,不要忘记调用 super.dispatchApplyWindowInsets(windowInsets);你想让 GridViewPager 做它需要的插图。

哎呀,很长,但应该对您有所帮助,还可以让您了解事情发生的原因。我认为我们有一个 bug 可以修复这个 GridViewPager 问题,所以也许在下一个版本之后你就不必处理这个了。

关于android - 您可以在 Android Wear 的 GridViewPager 中使用 WatchViewStub 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28975375/

相关文章:

android - Proguard 混淆和渲染脚本

javascript - 为什么我的 AdMob 横幅广告在 Expo Client 中显示,但在最终版本中却没有显示?

java - Android Wear 追加到 textView 会使应用程序崩溃

java - 如何在 WearOS 应用上直接访问互联网

wear-os - 边缘滑动和应用程序退出 Android Wear 2.0

Android Flickr Json 缓存图像

java - 修改进度条资源图片

android - 在 ListView 中选择时更改 ListItem View

android - 可穿戴 ListView 标题

android - 动态添加项目到 FragmentGridPagerAdapter