ViewPager + GridView onItemClick

时间:2012-10-10 05:46:37

标签: java android android-viewpager

我在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);

    }

}

我可以很好地查看Grid。自定义布局也按照我的GridAdapter工作。但是,我的点击事件没有被触发。是因为instantiateItem()方法调用吗?我怎么能绕过这个?

我还不太了解Fragments如何使用ViewPager,所以如果这个解决方案涉及切换到基于Fragment的方法,那么如果有人可以详细说明那就太棒了。

3 个答案:

答案 0 :(得分:2)

因此,点击在ViewPager中有点滑稽,因为ViewPager在捕捉点击/动作事件方面有点贪心。 One solution涉及覆盖ViewPager的{​​{3}}。但是,这并不总是必要的。具体来说,我无法在没有这样做的情况下为寻呼机设置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;
}

答案 1 :(得分:2)

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

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

您使用的当前方式对我来说看起来有点复杂。所以,我会坚持你试试看。对于我说的方式,示例演示为here

答案 2 :(得分:0)

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