gpt4 book ai didi

android - ListView 行内的 ViewPager 阻止触发 onItemClick

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:23:28 25 4
gpt4 key购买 nike

我在 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 调用父 ViewTouchEvent 但返回 true 调用流程下降。

如果 intercepterTouchEvent 返回 true 不调用子 dispatchTouchEvent 但返回 false 调用子 dispatchTouchEvent 。所以 listview.intercepterTouchEvent 返回 true,调用 onItemClick

因此,如果 listView.intercepterTouchEvent 返回 true,则不会滑动 viewPager 项。

您可以通过 2 种方式了解用户的 Action 滑动或点击。TouchEventguesturedetector..

在 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com