基于HorizontalScrollView
,我在自定义视图中实施长按时遇到问题。
HorizontalScrollView
有一个孩子LinearLayout
,后者又有一个子视图。视图通过OnDraw()
将位图绘制到画布。
我想允许HorizontalScrollView
正常滚动,无论是快还是慢。但是,如果用户在其中一个图像上握住他们的手指(即使滚动),它将立即取消滚动并允许用户对所选图像执行功能。 (在这种特殊情况下,他们会在屏幕上移动图像,但它实际上可以是任意数量的功能。)
我尝试过在每个层(HorizontalScrollView
和View
)内处理事件(true,false,super)的多种组合,但似乎没有一种方法可以100%工作。有些组合大部分都在那里,其他一些组成部分,但它们似乎总是缺少一个或另一个功能(滚动,命中测试等)。
我最接近的是在HorizontalScrollView's
onInterceptTouchEvent()
内返回false,并在View的onTouch()
事件中返回true。这允许滚动并在图像上记录命中测试。但是,它立即将控制权传递回HorizontalScrollView
的onTouch()事件。这使得无法检查图像是否已按下数秒(长按)。
如果我在View的onTouch()
事件中返回true,则命中测试会注册,并且我能够检查用户是否在ACTION_MOVE
内长按了图像。但是,HorizontalScrollView
不会滚动。
我是否遗漏了一些完全明显的东西,或者我只选择了两种不能很好地融合的视图?任何见解都表示赞赏。
答案 0 :(得分:0)
右,
不知道你是否已对此进行了排序,我已将一些碎片混合在一起,我认为按照你的要求进行,如果不是那么嘿嘿。
我有一个在水平滚动条中加载的活动,这可能不是最好的方式,但它对我有用:
HolderActivity类(在HorizontalScrollView类中加载的类)我有:
int selectedItem;
public boolean onLongClick(View v, int position) {
selectedItem = position;
openContextMenu(v);
return true;
}
public boolean onItemClick(int position) {)//do what you want here on click (press)
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
String[] menuItems = {"Menu item 1 text", "Cancel"};
for (int i = 0; i<menuItems.length; i++) {
menu.add(Menu.NONE, i, i, menuItemsRemove[i]);
}
menu.setHeaderTitle("My menu title");
}
你在HorizontalScrollView类的构造函数传递中的我在那里传递一个上下文:
public MyScroller(Context context) {
super(context);
this.context = context;
}
我有一个从ArrayList创建项目的方法,名为setFeatureItems,如下所示:
public void setFeatureItems(ArrayList<MyListEntity> items){}
在这个方法中,我添加了一个GestureDetector,将上下文传递给每个项目,如下所示:
mGestureDetector = new GestureDetector(context, new MyGestureDetector());
MyGestureDetector嵌套类具有对所有重要的parentActivity的引用,如下所示:
class MyGestureDetector extends SimpleOnGestureListener {
@Override
public void onLongPress(MotionEvent arg0) {
parentActivity.onLongClick(MyScroller.this, mActiveFeature);
};
@Override
public boolean onSingleTapUp(MotionEvent arg0) {
parentActivity.onItemClick(mActiveFeature);
return true;
};
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
try {
//right to left
if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
int featureWidth = getMeasuredWidth();
mActiveFeature = (mActiveFeature < (mItems.size() - 1))? mActiveFeature + 1:mItems.size() -1;
smoothScrollTo(mActiveFeature*featureWidth, 0);
return true;
}
//left to right
else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
int featureWidth = getMeasuredWidth();
mActiveFeature = (mActiveFeature > 0)? mActiveFeature - 1:0;
smoothScrollTo(mActiveFeature*featureWidth, 0);
return true;
}
} catch (Exception e) {
Log.e("Fling", "There was an error processing the Fling event:" + e.getMessage());
}
return false;
}
}
我已经从现有的项目中删除了这个,所以可能有遗留物,我没有足够通用,我希望这有意义或有帮助,让我知道如果我可以添加更多细节