你可以在GridViewPager for Android Wear中使用WatchViewStub吗?

时间:2015-03-10 22:35:09

标签: android wear-os

我有一个可以自行运行的WatchViewStub - 它在相应的方形或圆形安卓模拟器上显示正确的布局。但是当我尝试在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>

然后我有两个布局与我的观点。他们从:

开始

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设置了相同类型的布局。

2 个答案:

答案 0 :(得分:2)

如果WatchViewStub没有显示圆形布局,则表示它没有正确接收WindowInsets对象。 GridViewPager必须在途中消费它。

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

1)首先阅读View.dispatchApplyWindowInsetsView.onApplyWindowInsets

2)这两个方法在View中绑定的方式是:dispatchApplyWindowInsets被调用并检查是否有任何监听器;如果是,则仅将WindowInsets传递给侦听器;如果不是,则会将WindowInsets传递给onApplyWindowInsets

3)在ViewGroupGridViewPagerViewGroup)中,它遍历子项并检查是否使用了insets;如果是,它会停止提供它们;

4)任何时候任何View / ViewGroup都可以决定停止发送WindowInsets;当它发生时,任何依赖它的孩子都不会在圆形上表现得很好;

现在做了一些练习:

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

6)覆盖dispatchApplyWindowInsets重叠儿童并致电dispatchApplyWindowInsets给他们每个人;这种方式WatchViewStub应该会使用之前的WindowInsets方法获得未经更改的isRound()->true

7)最后,别忘了给super.dispatchApplyWindowInsets(windowInsets)打电话;你想让GridViewPager用插图做他们需要的东西。

P,很长,但应该帮助你,并且让你理解为什么事情正在发生的事情发生。我认为我们有一个错误可以解决这个GridViewPager问题,所以也许在下一个版本发布之后你不必处理这个问题。

答案 1 :(得分:0)

@gruszczy所述,GridViewPager默认使用WindowsInsets回调。解决此问题的方法是手动将其设置为不通过代码执行:

mGridViewPager.setConsumeWindowInsets(false);

此方法设置内部布尔属性,该属性用于insets的调度程序方法。从这里可以看出:

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

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

最后一点,这是在支持可穿戴库的1.3.0版本上。我不确定这是否包含在以前的版本中......