用于滚动滚动的自定义视图

时间:2013-10-07 07:45:48

标签: android

我想创建一个自定义视图,它应该水平滚动,它可以用作标题工具栏(作为操作栏)和页脚工具栏。

 protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
        {
            try
            {
                DisplayMetrics met = new DisplayMetrics();
                display.GetMetrics(met);
                m_fToolSize = (met.Xdpi * c_fToolIconSize) / c_fmmPerInch;
                SetMeasuredDimension(met.WidthPixels, (int)(m_fToolSize + 2 * c_nToolIndent));
            }
            catch { }
        }

        protected override void OnLayout(bool changed, int l, int t, int r, int b)
        {
            try
            {
                int[] loc = new int[2];
                GetLocationOnScreen(loc);
                loc[1] -= SysUtil.GetStatusBarHeight(Resources);
                Display dsp = ((Activity)Context).WindowManager.DefaultDisplay;
                if (loc[1] < dsp.Height / 2)
                {
                    m_bIsUpperToolBar = true;
                }
                int nToolSize = (int)m_fToolSize;
                int nNumTools = (int)(((r - l) - (2 * c_nToolIndent)) / m_fToolSize);
                m_fToolSpace = ((r - l) - 2 * c_nToolIndent - nNumTools * nToolSize) / (nNumTools - 1);
                float x = c_nToolIndent, y = c_nToolIndent;
                for (int i = 0; i < ChildCount; i++)// Removed condition of nNumTools to allow scrolling
                {
                    GetChildAt(i).Layout((int)x, (int)y, (int)x + nToolSize, (int)y + nToolSize);
                    x += m_fToolSize + m_fToolSpace;
                }
            }
            catch (Exception ex)
            {
            }
        }

        //To Implement Scrolling
        //This allows a ViewGroup to watch events as they are dispatched to child Views
        public override bool OnInterceptTouchEvent(MotionEvent e)
        {
            Console.WriteLine("OnInterceptTouchEvent");
            Boolean intercept = false;

            try
            {
                switch (e.Action)
                {
                    case MotionEventActions.Move:
                        {
                            int xDiff = (int)Math.Abs(e.GetX() - m_fLastX);
                            if (xDiff > mTouchSlop)
                            {
                                m_nTouchState = c_nTouchStateHorizontalScrolling;
                                m_fLastX = e.GetX();
                            }
                            int yDiff = (int)Math.Abs(e.GetY() - m_fLastY);
                            if (yDiff > mTouchSlop)
                            {
                                m_nTouchState = -1;
                            }
                            if (Math.Abs(xDiff * 2) > Math.Abs(yDiff) && xDiff > mTouchSlop)
                            {
                                intercept = true;
                            }

                            break;
                        }

                    case MotionEventActions.Cancel:
                    case MotionEventActions.Up:
                        // Release the drag.
                        m_nTouchState = c_nTouchStateRest;
                        break;
                    case MotionEventActions.Down:
                        m_fLastY = e.GetY();
                        m_fLastX = e.GetX();
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
            }
            return intercept;
        }

        public override bool OnTouchEvent(MotionEvent e)
        {
            Console.WriteLine("TB OnTouchEvent");
            try
            {
                if (mVelocityTracker == null)
                {
                    mVelocityTracker = VelocityTracker.Obtain();
                }
                mVelocityTracker.AddMovement(e);
                float x = e.GetX();
                float y = e.GetY();
                switch (e.Action)
                {
                    case MotionEventActions.Down:
                        if (!m_scroller.IsFinished)
                        {
                            m_scroller.AbortAnimation();
                        }
                        m_fLastX = x;
                        if (m_scroller.IsFinished)
                        {
                            m_nTouchState = c_nTouchStateRest;
                        }
                        else
                        {
                            m_nTouchState = c_nTouchStateHorizontalScrolling;
                        }
                        break;

                    case MotionEventActions.Move:
                        int deltaX = (int)(m_fLastX - x);
                        m_fLastX = x;
                        int scrollX = ScrollX;
                        // Scroll to right
                        if (deltaX < 0)
                        {
                            if (scrollX > 0)
                            {
                                ScrollBy(Math.Max(-scrollX, deltaX), 0);
                            }
                        }
                        // Scroll to left
                        else if (deltaX > 0)
                        {
                            // Visible full icons always without empty spaces 
                            int availableToScroll =
                                    GetChildAt(ChildCount - 1).Right - scrollX - (display.Width - c_nToolIndent);

                            if (availableToScroll > 0)
                            {
                                ScrollBy(Math.Min(availableToScroll, deltaX), 0);
                            }
                        }
                        break;

                    case MotionEventActions.Up:

                        //for (int index = 0; index < ChildCount; index++)
                        //{
                        //    View v = GetChildAt(index);
                        //    Rect rect = new Rect(v.Left, v.Top, v.Right, v.Bottom);

                        //    if (v.GetLocalVisibleRect(rect))
                        //    {
                        //        // we are here because we are either clipped or fully visible
                        //        int[] loc = new int[2];
                        //        v.GetLocationOnScreen(loc);
                        //        int n = v.Width;

                        //        if (loc[0] < c_nToolIndent)
                        //        {
                        //            // identify clipped view
                        //            if (Math.Abs(loc[0]) >= v.Width / 2)
                        //            {
                        //                // scroll the view outside the screen
                        //                ScrollBy(v.Width + loc[0] + (int)m_fToolSpace - c_nToolIndent, 0);
                        //                break;
                        //            }
                        //            else
                        //            {
                        //                ScrollBy(loc[0] - c_nToolIndent, 0);
                        //                break;
                        //            }
                        //        }
                        //    }
                        //}
                        VelocityTracker velocityTracker = mVelocityTracker;
                    velocityTracker.ComputeCurrentVelocity(1000, mMaximumVelocity);
                    int initialXVelocity = (int)velocityTracker.XVelocity;
                    int initialYVelocity = (int)velocityTracker.YVelocity;
                    if ((System.Math.Abs(initialXVelocity) + System.Math.Abs(initialYVelocity) > mMinimumVelocity) && ChildCount > 0)
                    {
                        Fling(-initialXVelocity, 0);
                    }
                    if (mVelocityTracker != null)
                    {
                        mVelocityTracker.Recycle();
                        mVelocityTracker = null;
                    }
                    break;

                        m_nTouchState = c_nTouchStateRest;
                        break;
                    case MotionEventActions.Cancel:
                        m_nTouchState = c_nTouchStateRest;
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
            }
            return true;
        }
        public void Fling(int velocityX, int velocityY)
        {
            Console.WriteLine("TB Fling");
            if (ChildCount > 0)
            {
                int height = Height - PaddingBottom - PaddingTop;
                int bottom = GetChildAt(0).Height;
                int width = Width - PaddingRight - PaddingLeft;
                int right = GetChildAt(0).Width;

                m_scroller.Fling(ScrollX, 0, velocityX, 0, 0, 1300, 0, 0);

                bool movingDown = velocityY > 0;
                bool movingRight = velocityX > 0;

              //  View newFocused = findFocusableViewInMyBounds(movingRight, mScroller.FinalX, movingDown, mScroller.FinalY, FindFocus());


                AwakenScrollBars(m_scroller.Duration);
                Invalidate();
            }
        }

0 个答案:

没有答案