在 Android Wear 上实现 GridViewPager 的正确方法是什么? [英] What is the correct way to implement a GridViewPager on Android Wear?

查看:17
本文介绍了在 Android Wear 上实现 GridViewPager 的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现 GridViewPager,以便可以在 2 个独特的视图之间切换.到目前为止,我根本无法添加任何视图.下面是我的代码

I'm trying to implement a GridViewPager so I can switch between 2 unique views. So far I haven't been able to add any views at all. Below is my code

public class Gridder extends Activity {

private TextView mTextView;
GridViewPager gridViewPager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_gridder);
    final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
    final LayoutInflater inflater = getLayoutInflater();
    stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
        @Override
        public void onLayoutInflated(WatchViewStub stub) {
            gridViewPager = (GridViewPager) findViewById(R.id.pager);
            gridViewPager.setAdapter(new MyGridViewPagerAdapter());
            gridViewPager.addView(inflater.inflate(R.layout.selector_generic, stub));;
        }
    });
}

private class MyGridViewPagerAdapter extends GridPagerAdapter {
    @Override
    protected void destroyItem(ViewGroup arg0, int arg1, int arg2, Object arg3) {
    }

    @Override
    public int getColumnCount(int arg0) {
        return 1;
    }

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

    @Override
    protected Object instantiateItem(ViewGroup arg0, int arg1, int arg2) {
        return null;
    }

    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
        return false;
    }
}

在主视图存根的矩形子视图中,我有一个 GridViewPager 和 id pager,正如我上面提到的那样:

In the rectangle child of the main view stub, I have a GridViewPager with the id pager, exactly as I referenced above:

<android.support.wearable.view.GridViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:keepScreenOn="true" />

此代码引发非法状态异常并报告我的子视图已经有父视图.见下文

This code throws an illegal state exception and reports that my child view already has a parent. See below

07-16 14:44:40.847  12940-12940/com.larvalabs.weartest E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.larvalabs.weartest, PID: 12940
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
        at android.view.ViewGroup.addViewInner(ViewGroup.java:3561)
        at android.view.ViewGroup.addView(ViewGroup.java:3414)
        at android.support.wearable.view.GridViewPager.addView(GridViewPager.java:1088)
        at android.view.ViewGroup.addView(ViewGroup.java:3359)
        at android.view.ViewGroup.addView(ViewGroup.java:3335)
        at com.larvalabs.weartest.Gridder$1.onLayoutInflated(Gridder.java:30)
        at android.support.wearable.view.WatchViewStub.inflate(WatchViewStub.java:133)
        at android.support.wearable.view.WatchViewStub.onMeasure(WatchViewStub.java:141)
        at android.view.View.measure(View.java:16648)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
        at android.view.View.measure(View.java:16648)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5125)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2321)
        at android.view.View.measure(View.java:16648)
        at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1959)
        at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1145)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1340)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1032)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5657)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
        at android.view.Choreographer.doCallbacks(Choreographer.java:574)
        at android.view.Choreographer.doFrame(Choreographer.java:544)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5026)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
        at dalvik.system.NativeStart.main(Native Method)

推荐答案

Stacktrace解释:

首先 - 以下行是错误的:

Stacktrace explanation:

First of all - the following line is wrong:

gridViewPager.addView(inflater.inflate(R.layout.selector_generic, stub));

inflate(int resource, ViewGroup root)
root!=null
相同inflate(int resource, ViewGroup root, boolean attachToRoot)最后一个参数为 true.

所以根据 文档 它将从 resource 扩展视图并将其附加到 root -> 然后返回一个 root.

inflate(int resource, ViewGroup root)
with root!=null is the same as
inflate(int resource, ViewGroup root, boolean attachToRoot) with last argument as true.

So according to the documentation it will inflate view from resource and attach it to root -> then return a root.

这将尝试将新膨胀的视图附加到 stub,然后尝试附加 stub(结果来自 inflate() 并指定 root) 到 gridViewPager.但是 stub 已经有一个父级(它已经附加到您活动中的视图层次结构中).所以这是对stacktrace的解释:)
请注意,您不应该通过 .addView() 方法将视图添加到 gridViewPager - 您应该通过适配器执行此操作,并且应该删除该行.

this will try to attach newly inflated view to stub, and then try to attach stub (result from inflate() with specified root) to the gridViewPager. But stub already has a parent (it's already attached to the view hierarchy in your activity). So this is an explanation of stacktrace:)
Please note that you should NOT add views to gridViewPager via .addView() methods - you should do it via adapter instead and that line should be removed.

这里是GridPagerAdapter的简单实现;

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

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

    @Override
    protected Object instantiateItem(ViewGroup container, int row, int col) {
        final View view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.grid_view_pager_item, container, false);
        final TextView textView = (TextView) view.findViewById(R.id.textView);
        textView.setText(String.format("Page:
%1$s, %2$s", row, col));
        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;
    }
}

grid_view_pager_item.xml的内容:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_gravity="center_vertical"
        android:gravity="center"
        android:background="#4400ff00"
        android:textColor="#000000"
        android:textSize="26sp"/> 

</FrameLayout>

这是 2x2 网格的最终结果.两个屏幕处于静止状态,另外两个在页面半滚动时被描绘出来:)

Here is a final result of 2x2 grid. Two screens are in still state and two are pictured during the pages being half-scrolled:)


这只是一个使用标准GridPagerAdapter的例子.如果您想要更高级的,使用 FragmentGridPagerAdapterCardFragments 和页面背景 - 请参阅平台示例中的 GridViewPager 示例:
{sdk_root}/samples/android-20/wearable/GridViewPager

This is just an example of using standard GridPagerAdapter. If you want more advanced one, with usage of FragmentGridPagerAdapter, CardFragments and pages backgrounds - please see the GridViewPager example located in platform samples:
{sdk_root}/samples/android-20/wearable/GridViewPager

这篇关于在 Android Wear 上实现 GridViewPager 的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆