dispatchApplyWindowInsets

dispatchApplyWindowInsets

我有一个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>

然后我有两个布局和我的观点。他们开始于:
读取页面目录.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">

阅读第/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">

我有相同类型的布局设置,用于查找页面存根、查找页面直线和查找页面圆。

最佳答案

如果WatchViewStub没有显示圆形布局,则表示它没有正确接收WindowInsets对象。一定是在路上的某个地方吃的。
你可以试着把它修好。方法是(首先是一些理论):
1)首先阅读关于GridViewPagerView.dispatchApplyWindowInsets
2)这两个方法在aView.onApplyWindowInsets中的绑定方式是:调用View并检查是否有侦听器;如果是,则只将dispatchApplyWindowInsets传递给侦听器;如果不是,则将WindowInsets传递给WindowInsets
3)在aonApplyWindowInsets(且ViewGroup是aGridViewPager)中,它遍历子代并检查插入是否被消耗;如果是,则停止传递它们;
4)在任何时候,任何ViewGroup/View都可以决定停止传送ViewGroup;当它停止传送时,任何依赖它的孩子都不会在回合上表现正常;
现在来练习一下:
5)可以创建层次结构中任何视图的子类;使用WindowInsets执行此操作,并开始尝试覆盖GridViewPagerdispatchApplyWindowInsets。我猜第一个就够了。
6)在重写onApplyWindowInsets时,遍历子级并调用dispatchApplyWindowInsets给每个子级;这样,dispatchApplyWindowInsets就应该使用前面的WatchViewStub方法接收未更改的WindowInsets
7)最后,不要忘了调用isRound()->true;您想让super.dispatchApplyWindowInsets(windowInsets)使用insets做它需要的事情。
嗯,很长时间了,但是应该能帮助你,也能让你理解为什么事情是这样发生的。我认为我们有一个bug可以修复这个GridViewPager问题,所以也许在下一个版本发布之后,您就不必处理这个问题了。

10-04 23:13