你能在Android Wear的GridViewPager中使用WatchViewStub吗?

你能在Android Wear的GridViewPager中使用WatchViewStub吗?,android,wear-os,Android,Wear Os,我有一个WatchViewStub,它可以独立工作——它在相应的方形或圆形android wear模拟器上显示正确的布局。但是当我尝试在GridViewPager中使用WatchViewStub时,它总是显示方形(或矩形)布局,即使在圆形模拟器上也是如此。能否成功地将两者结合使用 以下是一些代码片段: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceSta

我有一个WatchViewStub,它可以独立工作——它在相应的方形或圆形android wear模拟器上显示正确的布局。但是当我尝试在GridViewPager中使用WatchViewStub时,它总是显示方形(或矩形)布局,即使在圆形模拟器上也是如此。能否成功地将两者结合使用

以下是一些代码片段:

@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>

然后我有两个布局和我的视图。首先是:

阅读\u page\u 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">

阅读\u page\u 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) 从阅读和开始

2) 这两个方法在
视图中的结合方式如下:
dispatchapplywindsets
被调用并检查是否有侦听器;如果是,则仅将
窗口插入
传递给侦听器;如果否,它会将
窗口插图
发送到应用程序窗口插图
上的

3) 在
ViewGroup
(而
GridViewPager
ViewGroup
)中,它迭代子视图并检查插入是否已被使用;如果是,则停止交付

4) 在任何时候,任何
视图
/
视图组
都可以决定停止交付
窗口插图
;当它这样做的时候,任何依赖它的孩子在圆上都不会表现得很好

现在有一些做法:

5) 您可以创建层次结构中任何视图的子类;使用
GridViewPager
执行此操作,并开始尝试覆盖应用程序窗口插图上的
DispatchApplyIndowInSets
。我猜第一个就足够了

6) 在重写
DispatchApplyIndowInSets
时,迭代子项并调用
DispatchApplyIndowInSets
;这样,
WatchViewStub
应使用前面的
isRound()->true
方法接收未更改的
WindowInsets

7) 最后,别忘了调用super.dispatchApplyWinSets(windowInsets)
;您想让
GridViewPager
使用inset执行它所需的操作

唷,很长,但应该会帮助你,也会让你理解为什么事情会以这种方式发生。我认为我们有一个bug可以修复这个
GridViewPager
问题,所以在下一个版本之后,您可能不必处理这个问题。

如前所述,GridViewPager默认使用WindowsInsets回调。解决此问题的方法是手动将其设置为“不按代码执行”:

mGridViewPager.setConsumeWindowInsets(false);
此方法设置一个内部布尔属性,该属性用于insets的dispatcher方法。如图所示:

 public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
    insets = this.onApplyWindowInsets(insets);
    if(this.mOnApplyWindowInsetsListener != null) {
        this.mOnApplyWindowInsetsListener.onApplyWindowInsets(this, insets);
    }

    return this.mConsumeInsets?insets.consumeSystemWindowInsets():insets;
}

最后请注意,这在Support Wearable library的1.3.0版上。我不确定这是否包含在以前的版本中…

感谢您提供的信息,这很有帮助,尽管我正在努力实现您的子类想法-我遇到了一个类强制转换异常,我不确定如何解决。无论如何,这听起来像是Android Wear中的一个bug,所以现在我最好的做法是放弃WatchViewStub方法,让我的布局与rect/round相同,或者找到一种动态确定形状的方法。你看到的例外是什么?你能更新你的问题吗?另一种方法是使用FragmentGridPagerAdapter(它扩展了GridPagerAdapter)并以SomeFragment.newInstance(ListoObjects.get(row))的方式在getFragment(…)中填充片段;然后在SomeFragment的onCreateView中执行WatchViewStub之类的操作。这对我来说很好,我没有任何需要处理WindowInsetts。