3

我在 ViewPager 的布局中有一个 GridView (我不确定这是否有区别)。

inside SampleAdapter for ViewPager{
@Override
        public Object instantiateItem(ViewGroup container, int position) {
            View page = null;
            if (position == 0) {
                page = getLayoutInflater().inflate(R.layout.layoutone,
                        container, false);
            } else {
                page = getLayoutInflater().inflate(R.layout.layouttwo,
                        container, false);
                GridView grid = (GridView) page.findViewById(R.id.gridview);
                grid.setOnItemClickListener(new OnItemClickListener() {

                    @Override
                    public void onItemClick(AdapterView<?> arg0, View arg1,
                            int arg2, long arg3) {

                                  //switch to another activity based on click event

                    }

                });
                grid.setAdapter(new GridItemAdapter(context)); //sets custom gridItemLayout


        container.addView(page);

        return (page);

    }

}

我可以很好地查看网格。自定义布局也按照我的 GridAdapter 工作。但是,我的点击事件没有被触发。是因为 instanceiteItem() 方法调用吗?我怎样才能解决这个问题?

我还不太明白 Fragments 如何与 ViewPager 一起工作,所以如果这个解决方案涉及切换到基于 Fragment 的方法,如果有人能详细说明,那就太好了。

4

3 回答 3

2

所以,在 a 中点击有点有趣ViewPager,因为在ViewPager捕捉点击/动作事件时有点贪婪。一种解决方案涉及覆盖ViewGroup.onInterceptTouchEvent(MotionEvent evViewPager ) 。但是,这并不总是必要的。具体来说,如果不这样做,我无法为寻呼机设置 onClickListener,但是为寻呼机内部的视图设置 onClickListener 对我来说非常有效(我在最后附上了代码示例)。但是,我从来没有这样做过GridView/onItemClickListener。您所做的实际上是为寻呼机内的视图内的视图设置点击侦听器,这是另一层。当您在 Android 中嵌套内容时,由于系统处理消耗点击的方式,触摸事件的管理变得更加复杂。

您遇到的问题是某些东西正在消耗您的触摸事件而没有将其传递给列表项。本质上,Android 处理触摸事件的方式是,当触摸事件发生时,它会将其传递给顶层视图的触摸事件处理函数。如果视图处理了事件,它返回 true 并且系统知道事件已被处理并完成。如果视图不想处理该事件,则返回 false 并且系统将事件传递给层次结构中的下一个最高视图。在您的情况下,某些东西(可能是ViewPager或可能是GridView)在事件击中您的网格项目之前正在消耗该事件,因此 onItemClickListener 永远不会被触发。

作为测试,如果您可以为GridView(如在整个视图中)设置 onClickListener 并使其正常工作,则意味着问题不在于ViewPager. 在这种情况下,您可能需要实现自己的版本GridView并覆盖它处理触摸事件的方式,以确保事件到达子项。但是,如果这不起作用,您将需要覆盖ViewPager,如前所述。

(注意:显然这两种解决方案都需要大量时间,因此在您执行之前,请确保您已仔细检查任何简单错误,例如将侦听器置于错误视图、误读行为并认为它不是射击时等)

作为参考,这里是一个可以工作的 instantiateItem 方法的版本(这实际上仍在进行中,所以它不是 100% 漂亮)。'menupage' 视图是一个LinearLayout.

public Object instantiateItem(View collection, int position) {
    LayoutInflater inflater = (LayoutInflater) collection.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    int page = R.layout.menu_page;
    String meal = "";
    switch (position) {
        case 0:
            meal = "Breakfast!";
            break;
        case 1:
            meal = "Lunch!";
            break;
        case 2:
            meal = "Dinner!";
            break;
    }

    View view = inflater.inflate(page, null);
    TextView mealTitle = (TextView) view.findViewById(R.id.meal_title);
    mealTitle.setText(meal);

    ((ViewPager) collection).addView(view, 0);
    final ViewPager pager = (ViewPager)collection;

    View menupage = view.findViewById(R.id.menu_page_ll);
    menupage.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            int page = ((ViewPager) pager).getCurrentItem();
            Intent i = new Intent(getApplicationContext(), Menus.class);
            i.putExtra("page", page);
            startActivity(i);
        }
    });

    return view;
}
于 2012-10-10T06:20:42.303 回答
2

我会坚持你创建一个单独的Fragment并使用getItem(position)你的ViewPager适配器来发送位置和实例化你的片段。在 Fragment 中,您可以轻松地为您的 Layout 充气并使用GridView.

 @Override
 public Fragment getItem(int position) {
    return GridFragment.newInstance(position);
}

您当前使用的方式对我来说看起来有点复杂。所以,我只是坚持让你尝试一下。一个示例演示就是here我所说的方式。

于 2012-10-19T07:43:09.177 回答
0

您的 listView 中是否有任何可点击的对象?如果您的 listView 或 gridView 项目包含可点击的视图(按钮、复选框等),您的 OnItemClickListener 将不会被调用。

于 2015-03-20T17:51:07.347 回答