美文网首页
关于ListView GridView 嵌套遇到的坑

关于ListView GridView 嵌套遇到的坑

作者: jacky123 | 来源:发表于2016-10-13 16:29 被阅读136次

    前言

    随着项目的需求及展示要求,一般ListView都会涉及到嵌套问题,本文就关于嵌套问题,集合平时开发遇到的坑,做一个介绍,祭奠我们遇到的坑!欢迎大家补充。


    1.获取一个 ListView 的当前点击的 ItemView 。

    public View getItemViewByPosition(int pos, AdapterView listView) {
        final int firstListItemPosition = listView.getFirstVisiblePosition();
        final int lastListItemPosition = firstListItemPosition + listView.getChildCount() - 1;
    
        if (pos < firstListItemPosition || pos > lastListItemPosition) {
            return listView.getAdapter().getView(pos, null, listView);
        } else {
            final int childIndex = pos - firstListItemPosition;
            return listView.getChildAt(childIndex);
        }
    }
    

    这个方法,如果有坑,欢迎大家留言讨论,尤其是ListView 有 HeaderView 的时候。比较稳妥的,我是采用嵌套方法,找到我要求的 view 的parentView,如下。

    2.根据当前点击的 view 获取他的 ParentView,可以代替1.

    比如我需要找到 v 的父控件,或者'爷爷'控件,我们只要知道父控件的 id,比如:R.id.ll_left,R.id.ll_right。

    @Override
    public boolean onLongClick(View v) {
        LogUtils.d("info", "View info:" + v.toString());
    
        View convertView = null;
    
        try {
            MessageView message = (MessageView) v.getTag();
            int position = messageList.indexOf(message);
    
            boolean isIncoming = message.getDirection() == Direction.INCOMING;
            convertView = findLinearLayoutViewByChild(v, isIncoming);
    
            if (convertView != null) {
                convertView.setTag(message);
                callBack.execute(position, convertView);
            }
        } catch (Exception e) {
            LogUtils.e("info", e.toString());
        }
    
        return true;
    }
    
    //方法
    private View findLinearLayoutViewByChild(View v, boolean inComing) {
            View viewGroup = null;
            View res = null;
            View parent = null;
            parent = (View) v.getParent();
            if (v instanceof ViewGroup) {
                viewGroup = (ViewGroup) v;
    
                if (inComing) {
                    res = viewGroup.findViewById(R.id.ll_left);
                } else {
                    res = viewGroup.findViewById(R.id.ll_right);
                }
    
                if (res != null) {
                    return res;
                } else {
                    if (parent != null) {
                        return findLinearLayoutViewByChild((View) v.getParent(), inComing);
                    } else {
                        return null;
                    }
    
                }
            } else {
                if (parent != null) {
                    return findLinearLayoutViewByChild((View) v.getParent(), inComing);
                } else {
                    return null;
                }
            }
        }
    

    3.ListView Item嵌套GridView ,GridView里面的空白处的长按事件不执行的解决方案。

    相信大家一看就知道怎么解决的。

    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.ViewConfiguration;
    import android.widget.AdapterView;
    import android.widget.GridView;
    
    public class MyGridView extends GridView {
        public MyGridView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public MyGridView(Context context) {
            super(context);
        }
    
        public MyGridView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
            int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
            super.onMeasure(widthMeasureSpec, expandSpec);
        }
    
        // 用来处理是否为长按的Runnable
        private Runnable mLongClickRunnable = new Runnable() {
            @Override
            public void run() {
                performLongClick();
            }
        };
    
        int downX;
        int downY;
    
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = (int) ev.getX();
                downY = (int) ev.getY();
    
                // 根据按下的X,Y坐标获取所点击item的position
                int position = pointToPosition(downX, downY);
    
                // 点击在 item 的位置
                if (position != AdapterView.INVALID_POSITION) {
                    return super.dispatchTouchEvent(ev);
                }
    
                // 不是itemview的位置的时候,mLongClickRunnable
                postDelayed(mLongClickRunnable, ViewConfiguration.getLongPressTimeout());
                break;
    
            case MotionEvent.ACTION_MOVE:
                int moveX = (int) ev.getX();
                int moveY = (int) ev.getY();
    
                int movePosition = pointToPosition(moveX, moveY);
                // 如果我们在按下的空白区域内移动,只要不进入有item的区域我们就不移除 mRunnable
                if (movePosition != AdapterView.INVALID_POSITION) {
                    removeCallbacks(mLongClickRunnable);
                }
                
                //如果在空白区域移动过多,我们移除空白区域的 mRunnable
                if (movePosition == AdapterView.INVALID_POSITION
                        && (Math.abs(moveX -downX)>ViewConfiguration.getTouchSlop()
                                || Math.abs(moveY -downY)>ViewConfiguration.getTouchSlop())) {
                    removeCallbacks(mLongClickRunnable);
                }
                break;
    
            case MotionEvent.ACTION_UP:
                removeCallbacks(mLongClickRunnable);
                break;
            }
            return super.dispatchTouchEvent(ev);
        }
    }
    
    

    相关文章

      网友评论

          本文标题:关于ListView GridView 嵌套遇到的坑

          本文链接:https://www.haomeiwen.com/subject/ypiwyttx.html