ViewPager里面的ListView行prevents onItemClick被解雇 [英] ViewPager inside ListView row prevents onItemClick to be fired

查看:181
本文介绍了ViewPager里面的ListView行prevents onItemClick被解雇的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ListView的每一行内的ViewPager。它工作正常,它改变了看法里面,当用户使用滑动手势,但它prevents被称为ListView的onItemClick方法。我知道ViewPager是因为当我隐藏它,在onItemClick称为罪魁祸首,所以这是我想:

我创建了一个ViewGroup中要行(RowView)。这ViewGroup中有 onInterceptTouchEvent 重写,以避免ViewPager处理进一步触摸事件时,我发现一个点击。但onItemClick回调仍然没有被调用。而列表选择不上点击或者显示。我想这两个特点的工作。

这是如何从RowView的onInterceptTouchEvent如下:

  @覆盖
公共布尔onInterceptTouchEvent(MotionEvent EV){
    INT actionMasked = ev.getActionMasked();
    开关(actionMasked){
        案例MotionEvent.ACTION_DOWN:
            Log.d(RowView,OnInterceptTouchEvent  - 下);
            tapDetector.onTouchEvent(EV);
            返回false;
        案例MotionEvent.ACTION_CANCEL:
            Log.d(RowView,OnInterceptTouchEvent  - 取消);
            tapDetector.onTouchEvent(EV);
            打破;
        案例MotionEvent.ACTION_UP:
            如果(tapDetector.onTouchEvent(EV)){
                Log.d(RowView,OnInterceptTouchEvent  -  UP!);
                返回true;
            }
            打破;
    }

    返回super.onInterceptTouchEvent(EV);
}
 

任何建议,以解决此问题?

修改:不工作的例子关于如何onItemClick在MainActivity不叫当ViewPager有效(棒棒堂列表选择不出现任何)

  

MainActivity

 的ListView ListView的=(的ListView)findViewById(R.id.main_list);
listView.setAdapter(新MainListAdapter(这一点,30));
listView.setOnItemClickListener(新AdapterView.OnItemClickListener(){
    @覆盖
    公共无效onItemClick(适配器视图<>母公司视图中查看,INT位置,长的id){
        Log.d(TAG,onItemClick:+位置);
    }
});
 

  

列表项的XML:

 < RelativeLayout的
    的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =match_parent
    机器人:layout_height =80dp
    机器人:descendantFocusability =blocksDescendants
    >

    <的TextView
        机器人:ID =@ + ID / row_num
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT
        机器人:layout_alignParentBottom =真
        机器人:layout_alignParentRight =真
        机器人:layout_alignParentEnd =真
        />

    < android.support.v4.view.ViewPager
        机器人:ID =@ + ID / row_viewpager
        机器人:layout_width =match_parent
        机器人:layout_height =match_parent
        机器人:能见度=看见
        />
< / RelativeLayout的>
 

  

清单适配器:

 公共类MainListAdapter扩展了BaseAdapter {
    私人上下文的背景下;
    私人LayoutInflater充气;
    私人诠释计数;

    公共MainListAdapter(上下文的背景下,诠释计数){
        this.context =背景;
        this.inflater = LayoutInflater.from(上下文);
        this.count =计数;
    }

    @覆盖
    公众诠释getCount将(){
        返回计数;
    }

    @覆盖
    公共对象的getItem(INT位置){
        返回的位置;
    }

    @覆盖
    众长getItemId(INT位置){
        返回的位置;
    }

    @覆盖
    公共查看getView(INT位置,查看convertView,ViewGroup中父){
        ViewHolder持有人;

        如果(convertView == NULL){
            持有人=新ViewHolder();
            convertView = createRow(母公司持有);
        } 其他 {
            支架=(ViewHolder)convertView.getTag();
        }

        holder.textView.setText(Integer.toString(位置));
        INT randomPages =(INT)(新的随机()nextDouble()* 5 + 2);
        holder.viewPager.setAdapter(新NumAdapter(上下文,randomPages));

        返回convertView;
    }

    私人查看createRow(ViewGroup中父,ViewHolder持有人){
        查看查看= inflater.inflate(R.layout.row_main_listview,父母,假);
        holder.textView =(TextView中)view.findViewById(R.id.row_num);
        holder.viewPager =(ViewPager)view.findViewById(R.id.row_viewpager);
        view.setTag(保持器);

        返回查看;
    }

    私有静态类ViewHolder {
        公众的TextView TextView的;
        公共ViewPager viewPager;
    }
}
 

  

ViewPager的适配器:

 公共类NumAdapter扩展PagerAdapter {
    私人LayoutInflater充气;
    私人诠释计数;

    公共NumAdapter(上下文的背景下,诠释计数){
        this.inflater = LayoutInflater.from(上下文);
        this.count =计数;
    }

    @覆盖
    公共对象instantiateItem(ViewGroup中的容器,INT位置){
        TextView中的TextView =(TextView中)inflater.inflate(R.layout.page_viewpager,集装箱,假);
        textView.setText(页面+位置);
        container.addView(TextView的);
        返回的TextView;
    }

    @覆盖
    公众诠释getCount将(){
        返回计数;
    }

    @覆盖
    公共布尔isViewFromObject(查看为arg0,对象ARG1){
        返回将arg0 == ARG1;
    }

    @覆盖
    公共无效destroyItem(ViewGroup中的容器,INT位置,Object对象){
        container.removeView((查看)对象);
    }
}
 

解决方案

这是我做了什么终于来管理这虽然列表选择不工作。这可以改善,但是,就目前而言,这是我喜欢它是如何工作的唯一的解决方法。

 公共类CustomListView扩展的ListView实现AbsListView.OnScrollListener {
    / *
     *用于检测水龙头
     * /
    私人GestureDetector tapDetector;
    / *
     *由于我们需要设置我们自己的OnScrollListener,这种存储一个
     *使用外,如果有的话
     * /
    私人OnScrollListener onScrollListener;

    私人布尔isScrolling = FALSE;

    公共CustomListView(上下文的背景下){
        超(上下文);
        initView(上下文);
    }

    公共CustomListView(上下文的背景下,ATTRS的AttributeSet){
        超(背景下,ATTRS);
        initView(上下文);
    }

    公共CustomListView(上下文的背景下,ATTRS的AttributeSet,诠释defStyleAttr){
        超(背景下,ATTRS,defStyleAttr);
        initView(上下文);
    }

    @TargetApi(Build.VERSION_ codeS.LOLLIPOP)
    公共CustomListView(上下文的背景下,ATTRS的AttributeSet,诠释defStyleAttr,诠释defStyleRes){
        超(背景下,ATTRS,defStyleAttr,defStyleRes);
        initView(上下文);
    }

    私人无效initView(上下文的背景下){
        tapDetector =新GestureDetector(上下文,新TapListener());
        super.setOnScrollListener(本);
    }

    @覆盖
    公共无效setOnScrollListener(OnScrollListener onScrollListener){
        this.onScrollListener = onScrollListener;
    }

    @覆盖
    公共布尔dispatchTouchEvent(MotionEvent EV){
        布尔isTap = tapDetector.onTouchEvent(EV);

        如果(ev.getActionMasked()== MotionEvent.ACTION_UP){
            //不要进行点击,如果ListView控件是滚动
            //所以它能够停止滚动
            如果(isTap&安培;&安培;!isScrolling&安培;&安培; hasOnItemClickListener()){
                INT itemPosition = pointToPosition((int)的ev.getX(),(int)的ev.getY());
                performItemClick(这一点,itemPosition,getItemIdAtPosition(itemPosition));
            }
        }

        返回super.dispatchTouchEvent(EV);
    }

    公共布尔hasOnItemClickListener(){
        返回getOnItemClickListener()!= NULL;
    }

    @覆盖
    公共无效onScrollStateChanged(AbsListView观点,诠释scrollState){
        isScrolling = scrollState = OnScrollListener.SCROLL_STATE_IDLE!;

        如果(this.onScrollListener!= NULL){
            onScrollListener.onScrollStateChanged(查看,scrollState);
        }
    }

    @覆盖
    公共无效onScroll(AbsListView观点,诠释firstVisibleItem,诠释visibleItemCount,诠释totalItemCount){
        如果(this.onScrollListener!= NULL){
            onScrollListener.onScroll(查看,firstVisibleItem,visibleItemCount,totalItemCount);
        }
    }
 

I have a ViewPager inside every row of a ListView. It works fine, it changes the views inside it when the user use the swipe gesture, but it prevents the ListView's onItemClick method to be called. I know that the ViewPager is the culprit because when I hide it, the onItemClick is called, so this is what I am trying:

I have created a ViewGroup to be the row (RowView). This ViewGroup has onInterceptTouchEvent overriden to avoid the ViewPager to handle further touch events when I detect a click. But the onItemClick callback is still not being called. And the list selector doesn't show either on click. I want this two features to work.

This is how the onInterceptTouchEvent from RowView looks like:

@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);
}

Any suggestions to solve this?

EDIT: Not working example about how the onItemClick in MainActivity is not called when the ViewPager is active (Lollipop list selector doesn't appear either)

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);
    }
}

解决方案

This is what I've done finally to manage this although the list selector doesn't work. This could be improved, but, for now, it is the only workaround that I like how it works.

public class CustomListView extends ListView implements AbsListView.OnScrollListener {
    /*
     *  Used for detect taps
     */
    private GestureDetector tapDetector;
    /*
     *  As we need to set our own OnScrollListener, this stores the one 
     *  used outside, if any
     */
    private OnScrollListener onScrollListener;

    private boolean isScrolling = false;

    public CustomListView(Context context) {
        super(context);
        initView(context);
    }

    public CustomListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    public CustomListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public CustomListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initView(context);
    }

    private void initView(Context context) {
        tapDetector = new GestureDetector(context, new TapListener());
        super.setOnScrollListener(this);
    }

    @Override
    public void setOnScrollListener(OnScrollListener onScrollListener) {
        this.onScrollListener = onScrollListener;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        boolean isTap = tapDetector.onTouchEvent(ev);

        if(ev.getActionMasked() == MotionEvent.ACTION_UP) {
            // Don't perform the click if the ListView is scrolling
            // so it is able to stop the scroll
            if(isTap && !isScrolling && hasOnItemClickListener()) {
                int itemPosition = pointToPosition((int)ev.getX(), (int)ev.getY());
                performItemClick(this, itemPosition, getItemIdAtPosition(itemPosition));
            }
        }

        return super.dispatchTouchEvent(ev);
    }

    public boolean hasOnItemClickListener() {
        return getOnItemClickListener() != null;
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        isScrolling = scrollState != OnScrollListener.SCROLL_STATE_IDLE;

        if(this.onScrollListener != null) {
            onScrollListener.onScrollStateChanged(view, scrollState);
        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        if(this.onScrollListener != null) {
            onScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
        }
    }

这篇关于ViewPager里面的ListView行prevents onItemClick被解雇的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆