ViewPager + GridView onItemClick



我在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工作。但是,我的点击事件没有被触发。是因为instantiateItem()方法调用吗?我该怎么绕过这个?

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

因此,在ViewPager中单击有点有趣,因为ViewPager在捕捉单击/运动事件时有点贪婪。一种解决方案涉及覆盖ViewPager的ViewGroup.oInterceptTouchEvent(MotionEvent ev)。然而,这并不总是必要的。具体来说,如果不这样做,我无法为寻呼机设置onClickListener,但为寻呼机内部的视图设置onClick监听器对我来说非常有效(我在末尾附上了一个代码示例)。但是,我从未使用GridView/onItemClickListener完成过此操作。您所做的基本上是为寻呼机内的视图设置一个点击监听器,这是另一层。当你在Android中嵌套东西时,由于系统处理消耗点击的方式,触摸事件的管理变得更加复杂。

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

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

(注意:很明显,这两种解决方案都需要大量的时间,所以在你这样做之前,只要确保你已经仔细检查了任何简单的错误,比如把监听器放在错误的视图上,误读了行为,并认为它在发射时没有发射,等等。)

作为参考,这里有一个instantiateItem方法的版本,它是有效的(这实际上仍在进行中,所以它不是100%漂亮)。"菜单页"视图是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;
}

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

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

你目前的使用方式对我来说有点复杂。所以,我坚持让你尝试一下。按照我的说法,一个示例演示是here

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

最新更新