2012-10-10 93 views
3

我有一个ViewPager(我不知道如果有差别)的布局里面一个GridView。ViewPager + GridView控件onItemClick

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工作。但是,我的点击事件没有被解雇。是因为instantiateItem()方法调用?我怎样才能解决这个问题?

我不太明白碎片如何与ViewPager工作还,所以如果这个解决方案涉及切换到基于片段的方法,这将会是巨大的,如果有人能够详细说明。

+0

你可以包括你的'GridItemAdapter'的'getView'函数吗?让我知道你什么时候这样做 –

+0

'getView'函数只是膨胀R.layout.mycustomlayout,但我会尽快发布它,只要我能回家。 – Kgrover

回答

2

因此,点击在ViewPager中有点有趣,因为ViewPager在捕捉点击/动作事件时有点贪婪。 One solution涉及覆盖ViewPagerViewGroup.onInterceptTouchEvent(MotionEvent ev)。但是,这并非总是必要的。具体地讲,我无法设置寻呼机的onClickListener没有这样做,而是寻呼机完美的作品对我的意见设置的onClickListener(我已经把它贴在最后一个代码示例)。不过,我从来没有使用GridView/onItemClickListener做到这一点。你正在做的事情本质上是在你的寻呼机内的视图内部设置一个点击监听器,这是另一层。当你在Android中嵌入事物时,由于系统处理消耗点击的方式,触摸事件变得更加难以管理。

在您的情况的问题是,什么是不将它传递给列表项消耗你的触摸事件。本质上,Android处理触摸事件的方式是当触摸事件发生时,它将它传递给顶层视图的触摸事件处理函数。如果视图处理事件,则它返回true,系统知道该事件已处理并完成。如果视图不想处理事件,它将返回false,并且系统将该事件传递给层次结构中次高的视图。在你的情况下,一些(可能是ViewPager或可能GridView)是使用该事件以往任何时候都击中了你的网格项目之前,所以onItemClickListener永远不会被解雇。

作为测试,如果您可以为GridView(如在整个视图中)设置onClickListener并使其正常工作,则表明问题不在ViewPager。在这种情况下,您可能需要实现自己的GridView版本,并重写它如何处理触摸事件以确保事件将其传递给子项目。但是,如果这不起作用,则需要覆盖ViewPager,如前所述。 (注意:这些解决方案显然都需要大量的时间,所以在你做任何事情之前,只要确保你已经仔细检查了任何简单的错误,比如把Listener放在错误的视图上,误读行为并思考它不发射时,它是等)

仅供参考,这里是一个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; 
} 
+0

感谢您的详细回复!我会尝试实现这一点,并进行更多的调试,并让你知道它是如何工作的。 – Kgrover

+0

看起来我仍然无法让它在GridView中工作。 – Kgrover

+0

这很有趣。 ViewPagers不应该消耗点击次数,但是下一步可能是重写onInterceptTouchEvent并确保它对点击返回false(尽管如此,仍然希望它可以处理滑动操作)。 – matt5784

2

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

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

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

+0

感谢您的意见!我会尽快尝试一下。如果我需要帮助,我希望你能一路帮助我 - 我是新手。 – Kgrover

+0

您能否更好地详细说明您的代码如何与ListView一起使用?我不确定如何使用GridFragment。现在,我给你的赏金,因为你已经提出了一种新的方式。我希望你能帮我实施它。 – Kgrover

+0

那么你可以尝试用GridView替换ListView并使其工作! –

0

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