OnSwipeListener 和 ExpandableListView 点击无法识别
OnSwipeListener and ExpandableListView click not recognized
我在识别 onGroup 对我的可扩展列表视图的点击时遇到了问题。我正在为我的组视图使用自定义滑动侦听器以实现滑动目的。现在我只想在按下组的同时展开组,似乎我找不到在组视图上注册 OnTouch 和 onGroupClick 的正确方法。我在不滑动时调用 false,以便可以识别其他手势(例如正常点击和长按),但我的组没有响应点击,因此没有扩展。
现在我的 Swipe 侦听器工作正常,但 OnGroupClick 未被调用且未扩展。当我从 getGroupView() 方法中删除我的 OnSwipeListener 时,实际的展开工作正常。
我的自定义滑动监听器:
public class OnSwipeListener implements View.OnTouchListener
{
private final GestureDetector gestureDetector = new GestureDetector(new GestureListener());
public boolean onTouch(final View v, final MotionEvent event)
{
return gestureDetector.onTouchEvent(event);
}
private final class GestureListener extends GestureDetector.SimpleOnGestureListener
{
private static final int SWIPE_THRESHOLD = 70;
private static final int SWIPE_VELOCITY_THRESHOLD = 70;
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
{
boolean result = false;
try
{
float diffY = e2.getY() - e1.getY();
float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) > Math.abs(diffY))
{
if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD)
{
if (diffX > 0)
{
result = onSwipeRight();
}
else
{
result = onSwipeLeft();
}
}
}
else
{
if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD)
{
if (diffY > 0)
{
result = onSwipeBottom();
}
else
{
result = onSwipeTop();
}
}
}
}
catch (Exception exception)
{
exception.printStackTrace();
}
return result;
}
}
public boolean onSwipeRight()
{
return false;
}
public boolean onSwipeLeft()
{
return false;
}
public boolean onSwipeTop()
{
return false;
}
public boolean onSwipeBottom()
{
return false;
}
}
我的可扩展列表视图及其组点击侦听器设置:
expandable_list_view = (ExpandableListView) findViewById(R.id.activity_profile_expandable_listview);
setGroupParents(); setChildData();
ExpandableListAdapter adapter = new ExpandableListAdapter(this, parentItems, childItems);
expandable_list_view.setAdapter(adapter);
expandable_list_view.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener()
{
@Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id)
{
parent.smoothScrollToPosition(groupPosition);
if (parent.isGroupExpanded(groupPosition))
{
parent.collapseGroup(groupPosition);
} else {
parent.expandGroup(groupPosition);
}
return false;
}
});
最后从我的可扩展列表视图的自定义适配器中获取 GroupView:
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent)
{
if (convertView == null)
{
convertView = inflater.inflate(R.layout.layout_activity_expandableitem, null);
}
final View converted_view = convertView;
final LinearLayout front_view = (LinearLayout) converted_view.findViewById(R.id.layout_activity_expandableitem_front_view); front_view.setTag(Position.CENTER);
final LinearLayout behind_view = (LinearLayout) converted_view.findViewById(R.id.layout_activity_expandableitem_behind_view);
final View confirmation_view = inflater.inflate(R.layout.slide_profile, null); confirmation_view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
final View cancel_view = inflater.inflate(R.layout.slide_cancel, null); cancel_view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
// Set onTouchListener
front_view.setOnClickListener(null);
front_view.setOnTouchListener(new OnSwipeListener()
{
@Override
public boolean onSwipeRight()
{
Position position = (Position) front_view.getTag();
if (position == Position.CENTER)
{
behind_view.removeAllViews();
behind_view.addView(confirmation_view);
showConfirmation(front_view);
front_view.setTag(Position.RIGHT);
}
else if (position == Position.LEFT)
{
//behind_view.removeAllViews();
showCenter(front_view, Position.RIGHT);
front_view.setTag(Position.CENTER);
}
return true;
}
@Override
public boolean onSwipeLeft()
{
Position position = (Position) front_view.getTag();
if (position == Position.CENTER)
{
behind_view.removeAllViews();
behind_view.addView(cancel_view);
showInfo(front_view);
front_view.setTag(Position.LEFT);
}
else if (position == Position.RIGHT)
{
//behind_view.removeAllViews();
showCenter(front_view, Position.LEFT);
front_view.setTag(Position.CENTER);
}
return true;
}
});
// Return the view
return converted_view;
感谢您提供有关如何解决此问题的任何想法。
您可以尝试我自己实施的 following 解决方案,并确保它有效。不过,我使用的是 onClickListener
而不是 SwipeListener
。希望能帮到您解决问题。
事情是这样的:
- 当您设置
OnGroupClick
时,它被设置为 whole listview
(每行 not) listview
的实施将 "figure out" 当您触摸 listView
时点击了哪一行
- 当您设置 SwipeListener 时,您将其附加到 行。
- 当两者都设置时,该行先于整个
listview
并将处理(消耗)触摸事件,而触摸事件又不会到达列表视图(这就是为什么您让它们在分开时工作)。
您可以选择:
- 子类
ListView
并实现 onInterceptTouchEvent()
。这样,您的 listview
将始终能够 "see" 触摸事件并对其进行操作。 (请注意,您可能会遇到同时检测到滑动和点击的情况)。
- 实现您自己的
ListView
,其 OnTouch
将负责识别哪一行具有交互、识别滑动手势(通过您的侦听器)和点击事件,并决定哪个先例。
我在识别 onGroup 对我的可扩展列表视图的点击时遇到了问题。我正在为我的组视图使用自定义滑动侦听器以实现滑动目的。现在我只想在按下组的同时展开组,似乎我找不到在组视图上注册 OnTouch 和 onGroupClick 的正确方法。我在不滑动时调用 false,以便可以识别其他手势(例如正常点击和长按),但我的组没有响应点击,因此没有扩展。
现在我的 Swipe 侦听器工作正常,但 OnGroupClick 未被调用且未扩展。当我从 getGroupView() 方法中删除我的 OnSwipeListener 时,实际的展开工作正常。
我的自定义滑动监听器:
public class OnSwipeListener implements View.OnTouchListener
{
private final GestureDetector gestureDetector = new GestureDetector(new GestureListener());
public boolean onTouch(final View v, final MotionEvent event)
{
return gestureDetector.onTouchEvent(event);
}
private final class GestureListener extends GestureDetector.SimpleOnGestureListener
{
private static final int SWIPE_THRESHOLD = 70;
private static final int SWIPE_VELOCITY_THRESHOLD = 70;
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
{
boolean result = false;
try
{
float diffY = e2.getY() - e1.getY();
float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) > Math.abs(diffY))
{
if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD)
{
if (diffX > 0)
{
result = onSwipeRight();
}
else
{
result = onSwipeLeft();
}
}
}
else
{
if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD)
{
if (diffY > 0)
{
result = onSwipeBottom();
}
else
{
result = onSwipeTop();
}
}
}
}
catch (Exception exception)
{
exception.printStackTrace();
}
return result;
}
}
public boolean onSwipeRight()
{
return false;
}
public boolean onSwipeLeft()
{
return false;
}
public boolean onSwipeTop()
{
return false;
}
public boolean onSwipeBottom()
{
return false;
}
}
我的可扩展列表视图及其组点击侦听器设置:
expandable_list_view = (ExpandableListView) findViewById(R.id.activity_profile_expandable_listview);
setGroupParents(); setChildData();
ExpandableListAdapter adapter = new ExpandableListAdapter(this, parentItems, childItems);
expandable_list_view.setAdapter(adapter);
expandable_list_view.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener()
{
@Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id)
{
parent.smoothScrollToPosition(groupPosition);
if (parent.isGroupExpanded(groupPosition))
{
parent.collapseGroup(groupPosition);
} else {
parent.expandGroup(groupPosition);
}
return false;
}
});
最后从我的可扩展列表视图的自定义适配器中获取 GroupView:
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent)
{
if (convertView == null)
{
convertView = inflater.inflate(R.layout.layout_activity_expandableitem, null);
}
final View converted_view = convertView;
final LinearLayout front_view = (LinearLayout) converted_view.findViewById(R.id.layout_activity_expandableitem_front_view); front_view.setTag(Position.CENTER);
final LinearLayout behind_view = (LinearLayout) converted_view.findViewById(R.id.layout_activity_expandableitem_behind_view);
final View confirmation_view = inflater.inflate(R.layout.slide_profile, null); confirmation_view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
final View cancel_view = inflater.inflate(R.layout.slide_cancel, null); cancel_view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
// Set onTouchListener
front_view.setOnClickListener(null);
front_view.setOnTouchListener(new OnSwipeListener()
{
@Override
public boolean onSwipeRight()
{
Position position = (Position) front_view.getTag();
if (position == Position.CENTER)
{
behind_view.removeAllViews();
behind_view.addView(confirmation_view);
showConfirmation(front_view);
front_view.setTag(Position.RIGHT);
}
else if (position == Position.LEFT)
{
//behind_view.removeAllViews();
showCenter(front_view, Position.RIGHT);
front_view.setTag(Position.CENTER);
}
return true;
}
@Override
public boolean onSwipeLeft()
{
Position position = (Position) front_view.getTag();
if (position == Position.CENTER)
{
behind_view.removeAllViews();
behind_view.addView(cancel_view);
showInfo(front_view);
front_view.setTag(Position.LEFT);
}
else if (position == Position.RIGHT)
{
//behind_view.removeAllViews();
showCenter(front_view, Position.LEFT);
front_view.setTag(Position.CENTER);
}
return true;
}
});
// Return the view
return converted_view;
感谢您提供有关如何解决此问题的任何想法。
您可以尝试我自己实施的 following 解决方案,并确保它有效。不过,我使用的是 onClickListener
而不是 SwipeListener
。希望能帮到您解决问题。
事情是这样的:
- 当您设置
OnGroupClick
时,它被设置为 wholelistview
(每行 not)listview
的实施将 "figure out" 当您触摸listView
时点击了哪一行
- 当您设置 SwipeListener 时,您将其附加到 行。
- 当两者都设置时,该行先于整个
listview
并将处理(消耗)触摸事件,而触摸事件又不会到达列表视图(这就是为什么您让它们在分开时工作)。
您可以选择:
- 子类
ListView
并实现onInterceptTouchEvent()
。这样,您的listview
将始终能够 "see" 触摸事件并对其进行操作。 (请注意,您可能会遇到同时检测到滑动和点击的情况)。 - 实现您自己的
ListView
,其OnTouch
将负责识别哪一行具有交互、识别滑动手势(通过您的侦听器)和点击事件,并决定哪个先例。