我在 ListView 的每一行中都有一个 ViewPager。它工作正常,当用户使用滑动手势时它会更改其中的 View ,但它会阻止调用 ListView 的 onItemClick 方法。我知道 ViewPager 是罪魁祸首,因为当我隐藏它时,会调用 onItemClick,所以这就是我正在尝试的:
我创建了一个 ViewGroup 作为行 (RowView)。此 ViewGroup 已覆盖 onInterceptTouchEvent 以避免 ViewPager 在我检测到点击时处理进一步的触摸事件。但是 onItemClick 回调仍然没有被调用。并且列表选择器不会在点击时显示。我希望这两个功能起作用。
这是来自 RowView 的 onInterceptTouchEvent 的样子:
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int actionMasked = ev.getActionMasked();
switch(actionMasked) {
case MotionEvent.ACTION_DOWN:
Log.d("RowView", "OnInterceptTouchEvent - Down");
tapDetector.onTouchEvent(ev);
return false;
case MotionEvent.ACTION_CANCEL:
Log.d("RowView", "OnInterceptTouchEvent - Cancel");
tapDetector.onTouchEvent(ev);
break;
case MotionEvent.ACTION_UP:
if(tapDetector.onTouchEvent(ev)) {
Log.d("RowView", "OnInterceptTouchEvent - UP!");
return true;
}
break;
}
return super.onInterceptTouchEvent(ev);
}
有什么解决这个问题的建议吗?
编辑:有关当 ViewPager 处于 Activity 状态时如何不调用 MainActivity 中的 onItemClick 的无效示例(Lollipop 列表选择器也未出现)
MainActivity
ListView listView = (ListView) findViewById(R.id.main_list);
listView.setAdapter(new MainListAdapter(this, 30));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d(TAG, "onItemClick: " + position);
}
});
List item XML:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="80dp"
android:descendantFocusability="blocksDescendants"
>
<TextView
android:id="@+id/row_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
/>
<android.support.v4.view.ViewPager
android:id="@+id/row_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"
/>
</RelativeLayout>
List adapter:
public class MainListAdapter extends BaseAdapter {
private Context context;
private LayoutInflater inflater;
private int count;
public MainListAdapter(Context context, int count) {
this.context = context;
this.inflater = LayoutInflater.from(context);
this.count = count;
}
@Override
public int getCount() {
return count;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
holder = new ViewHolder();
convertView = createRow(parent, holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setText(Integer.toString(position));
int randomPages = (int) (new Random().nextDouble()*5+2);
holder.viewPager.setAdapter(new NumAdapter(context, randomPages));
return convertView;
}
private View createRow(ViewGroup parent, ViewHolder holder) {
View view = inflater.inflate(R.layout.row_main_listview, parent, false);
holder.textView = (TextView) view.findViewById(R.id.row_num);
holder.viewPager = (ViewPager) view.findViewById(R.id.row_viewpager);
view.setTag(holder);
return view;
}
private static class ViewHolder {
public TextView textView;
public ViewPager viewPager;
}
}
ViewPager's Adapter:
public class NumAdapter extends PagerAdapter {
private LayoutInflater inflater;
private int count;
public NumAdapter(Context context, int count) {
this.inflater = LayoutInflater.from(context);
this.count = count;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
TextView textView = (TextView) inflater.inflate(R.layout.page_viewpager, container, false);
textView.setText("Page " + position);
container.addView(textView);
return textView;
}
@Override
public int getCount() {
return count;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
}
最佳答案
我认为重写 listview onintercepter 比重写 viewgroup 更好。
简单的 TouchEvent 流程:
Acitivity触摸事件->viewgroup.dispatchtouchevent->viewgroup.intercepter..->view.dispatchtouch...->.....
在本例中是 list.dispatch 调用。将事件抛给 ViewPager.dispatch。但在 ViewPager.dispatchtouchevent 之前,调用 ListView.intercepterTouchEvent。
如果 dispatchTouchEvent 返回 false 调用父 View 的 TouchEvent 但返回 true 调用流程下降。
如果 intercepterTouchEvent 返回 true 不调用子 dispatchTouchEvent 但返回 false 调用子 dispatchTouchEvent 。
所以 listview.intercepterTouchEvent 返回 true,调用 onItemClick。
因此,如果 listView.intercepterTouchEvent 返回 true,则不会滑动 viewPager 项。
您可以通过 2 种方式了解用户的 Action 滑动或点击。
TouchEvent 和 guesturedetector..
在 ListView 的 IntercepterTouchEvent(Event ev);
VelocityTracker mVelocityTracker;
PointF mLastPoint;
public mListView(Context context) {
super(context);
init();
}
public mListView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public mListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init(){
mLastPoint = new PointF();
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if(mVelocityTracker == null)
mVelocityTracker = VelocityTracker.obtain();
mVelocityTracker.addMovement(ev);
switch (ev.getAction()){
case MotionEvent.ACTION_MOVE:
mVelocityTracker.computeCurrentVelocity(100);
int x = (int)Math.abs(mVelocityTracker.getXVelocity());
int move_x = (int)Math.abs(ev.getX() - mLastPoint.x);
Log.d("ListView","speed : " + x +" move_x : " + move_x);
//here x is drag speed. (pixel/s)
// change value left right both value you want speed and move amount
if(move_x < 100 || x <100) {
mLastPoint.set(ev.getX(), ev.getY());
return true;
}
break;
case MotionEvent.ACTION_DOWN:
mLastPoint.set(ev.getX(), ev.getY());
break;
case MotionEvent.ACTION_UP:
mVelocityTracker.recycle();mVelocityTracker = null;
break;
}
return super.onInterceptTouchEvent(ev);
}
您可以滑动速度大约 100 或移动量 100 像素。如果不执行点击事件。
希望这篇文字能帮到你......
并添加编辑一些代码。
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if(mVelocityTracker == null)
mVelocityTracker = VelocityTracker.obtain();
mVelocityTracker.addMovement(ev);
switch (ev.getAction()){
case MotionEvent.ACTION_MOVE:
mVelocityTracker.computeCurrentVelocity(10);
int x = (int)Math.abs(mVelocityTracker.getXVelocity());
int move_x = (int)Math.abs(ev.getX() - mLastPoint.x);
int move_y = (int)Math.abs(ev.getY() - mLastPoint.y);
Log.d("ListView","speed : " + x +" move_x : " + move_x + " move_y : "+ move_y);
if(move_x < move_y || x < 10) {
mLastPoint.set(ev.getX(), ev.getY());
return true;
}else if(move_x > move_y){
return false;
}
break;
case MotionEvent.ACTION_DOWN:
mLastPoint.set(ev.getX(), ev.getY());
break;
case MotionEvent.ACTION_UP:
break;
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.d("ListView", "dispatch");
switch (ev.getAction()){
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_UP:
if(mVelocityTracker != null){mVelocityTracker.recycle();mVelocityTracker = null;}
break;
}
return super.dispatchTouchEvent(ev);;
}
关于android - ListView 行内的 ViewPager 阻止触发 onItemClick,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29622098/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是
我正在学习Rails,并阅读了关于乐观锁的内容。我已将类型为integer的lock_version列添加到我的articles表中。但现在每当我第一次尝试更新记录时,我都会收到StaleObjectError异常。这是我的迁移:classAddLockVersionToArticle当我尝试通过Rails控制台更新文章时:article=Article.first=>#我这样做:article.title="newtitle"article.save我明白了:(0.3ms)begintransaction(0.3ms)UPDATE"articles"SET"title"='dwdwd
我有一个rubyonrails应用程序。我按照facebook的说明添加了一个像素。但是,要跟踪转化,Facebook要求您将页面置于达到预期结果时出现的转化中。即,如果我想显示客户已注册,我会将您注册后转到的页面作为成功对象进行跟踪。我的问题是,当客户注册时,在我的应用程序中没有登陆页面。该应用程序将用户带回主页。它在主页上显示了一条消息,所以我想看看是否有一种方法可以跟踪来自Controller操作而不是实际页面的转化。我需要计数的Action没有页面,它们是ControllerAction。是否有任何人都知道的关于如何执行此操作的gem、文档或最佳实践?这是进入布局文件的像素
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d
我想写一点“Deprecate-It”库并经常使用“method_added”回调。但是现在我注意到在包含模块时不会触发此回调。是否有任何回调或变通方法,以便在某些内容包含到自身时通知类“Foobar”?用于演示的小Demo:#IncludingModulswon'ttriggermethod_addedcallbackmoduleInvisibleMethoddefinvisible"Youwon'tgetacallbackfromme"endendclassFoobardefself.method_added(m)puts"InstanceMethod:'#{m}'addedto'
我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文
我正在构建一个网络应用程序自动化框架,旨在允许:当然是自动化任务轻松构建测试场景我正在使用Capybara与浏览器通信,我有一个组件库,其中包含许多辅助函数(login_to_the_back_office、create_customer等)。现在我希望我的组件可以独立使用,也可以在RSpec测试中使用。这意味着我的组件(包含在库中)没有环绕describe...it...默认情况下会阻塞,但在测试使用它们时它们会在某个时候出现,因此它们应该使用expect和friend尽可能多。我关注了rspec's.shouldfails(outsidedescribe/itblock)inRub
以下代码使用了触发器运算符。(1..10).each{|x|print"#{x},"ifx==3..x==5}为什么结果是3,4,5?我觉得应该是3,4。如教程中所述,此表达式在x==3时为真,并一直为真,直到x==5。如果“5”的计算结果为false,如何打印它?谁能为我澄清一下? 最佳答案 来自“TheRubyProgrammingLanguage”的重要链接是:4.6.9.1Booleanflip-flopsWhenthe..and...operatorsareusedinaconditional,suchasanifstat