在Android Wear中的GridViewPager中使用时,布局中的垂直滚动是否被抑制?

时间:2015-03-11 23:40:55

标签: android wear-os

在我的Android Wear应用中,我使用GridViewPager并排显示两个布局,您可以在水平方向之间滑动。一个页面有一个ScrollView和子元素。另一个页面有一个WearableListView的BoxInsetLayout和FrameLayout。如果我在没有GridViewPager的情况下单独显示每个页面,我可以滚动ScrollView中的文本就好了,我可以滚动WearableListView中的项目列表就好了。但是当我将两个页面放在GridViewPager中时,我无法向上或向下滚动元素,至少不在我的Moto360上。 ScrollView会在圆形Android模拟器中垂直滚动,但不会在WearableListView中滚动。

要么我做错了事,要么就是不打算这样做。

我的主要java类有:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.context = this;
    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);
}
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_round, container, false);
            mTextView = (TextView)   view.findViewById(R.id.text);
        }
        else {
            view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.find_page_round, container, false);
            listView =  (WearableListView) view.findViewById(R.id.wearable_list);
            listView.setAdapter(new Adapter(getApplicationContext(), elements));
            listView.setClickListener(WearApplication.this);
        }

        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_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">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="5dp"
        android:paddingRight="15dp"
        android:paddingBottom="60dp"
        android:paddingLeft="15dp"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        style="@style/wear_main_text"/>

    (Other TextView items)

</LinearLayout>
</ScrollView>

find_page_round.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:background="@color/white"
android:layout_height="match_parent"
android:layout_width="match_parent">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:gravity="center_vertical|center_horizontal"
        android:text="Select List"
        style="@style/wear_main_app"/>
    <FrameLayout
        android:id="@+id/frame_layout"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        app:layout_box="left|bottom|right">
        <android.support.wearable.view.WearableListView
            android:id="@+id/wearable_list"
            android:layout_height="match_parent"
            android:layout_width="match_parent">
        </android.support.wearable.view.WearableListView>
    </FrameLayout>
</LinearLayout>
</android.support.wearable.view.BoxInsetLayout>

1 个答案:

答案 0 :(得分:1)

我想我遇到了同样的问题,并设法绕过它(但它并不那么漂亮)。

所以这是我的问题: 我有一个包含DotsPageIndicator和GridViewPager的视图。起初,所有东西都捆绑在RelativeLayout中。但在我的一个GridViewPager页面中,我想使用BoxInsetLayout。但是根据几个StackOverflow的答案我遇到的BoxInsetLayout需要是你活动的根元素。那么我在BoxInsetLayout中将我的DotsPageIndicator和GridViewPager捆绑在一起,但是如果然后在我的一个GridViewPager子项上应用insets(app:layout_box =“all”)它将无效...

为什么它不起作用: 我以某种方式愚蠢到只允许BoxInsetLayout作为Activity的根视图......但是这是规则所以我们必须使用它。但是,似乎你不能在任何级别的视图上应用插入规则,只能在BoxInsetLayout上一层的视图上应用。所以在我的情况下,这意味着我只能将插件应用于DotsPageIndicator和GridViewPager。这不是我想要的。

如何解决此限制: 所以这就是我在布局文件中解决这个限制的方法:

<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"
                                              android:background="@drawable/balance_detail_background_full">

    <View
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_box="all"
        android:background="@android:color/transparent"
        android:id="@+id/dummy_view"/>

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">

        <android.support.wearable.view.DotsPageIndicator
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/view_pager_indicator"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="4dp"/>

        <be.belfius.directmobile.android.wearable.widget.FixedGridViewPager
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/view_pager"/>
    </RelativeLayout>
</android.support.wearable.view.BoxInsetLayout>

因此,对于第一部分,您可以看到我添加了一个带有透明背景的“虚拟”视图,该视图设置了BoxInsetLayout,以便在完美的圆形手表上给我一个漂亮的方形视图。但是在ViewPager子视图中,这不会影响任何内容。 但我接下来要做的是将我的活动中的视图传递给我的ViewPagerAdapter(在我的例子中是一个SingleRowGridPagerAdapter)到我的子视图。

所以在代码中我的onCreate(..)方法看起来像这样:

@Override
public void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.my_layout);

    View dummyBoxInsetView = findViewById(R.id.dummy_view);
    mViewPager = findViewById(R.id.view_pager);
    mViewPagerIndicator = findViewById(R.id.view_pager_indicator);
    mAdapter = new MyViewPagerAdapter(YOUR_PARAMS, dummyBoxInsetView);
    mViewPager.setAdapter(mAdapter);
    mViewPagerIndicator.setPager(mViewPager);
}

在自定义视图寻呼机中,您可以初始化所有子视图(页面),对于您想要的页面,您可以执行以下操作:

public void setReferenceBoxInsetLayoutView(View boxInsetLayoutView) {
    int inboxOffsetLeft = boxInsetLayoutView.getPaddingLeft();
    int inboxOffsetRight = boxInsetLayoutView.getPaddingRight();
    int inboxOffsetTop = boxInsetLayoutView.getPaddingTop();
    int inboxOffsetBottom = boxInsetLayoutView.getPaddingBottom();

    MarginLayoutParams marginLayoutParams = (MarginLayoutParams) mViewThatNeedsOffsets.getLayoutParams();
    marginLayoutParams.leftMargin = inboxOffsetLeft;
    marginLayoutParams.rightMargin = inboxOffsetRight;
    marginLayoutParams.topMargin = inboxOffsetTop;
    marginLayoutParams.bottomMargin = inboxOffsetBottom;
    mViewThatNeedsOffsets.setLayoutParams(marginLayoutParams);
}

因此,您可以看到视图所需的偏移量在BoxInsetLayout的参考视图中设置为边距。如果你只需要左右,或者顶部和底部,甚至一个人都可以自由...现在就在你的手中。

我知道这是一个肮脏的解决方案但是在搜索了几个小时后,它是迄今为止最好的,以我们想要的方式完成圆形手表。

为了提高性能,您可以在布局文件中将虚拟视图(也称为dummyBoxInsetView)可见性设置为“不可见”。这样它仍然可以测量但不会被绘制。没有测试visiblity =“已经消失”,但我想这不会起作用,因为视图不再被测量了。