android 带漂浮tab菜单 StickyNavLayout

来源:互联网 发布:移动宽带网络客服电话 编辑:程序博客网 时间:2024/05/21 06:31
主要控制滑动事件的分配(仅支持listview,pulltorefreshlist和ScrollView)
public class StickyNavLayout extends LinearLayout implements NestedScrollingParent{    private static final String TAG = "StickyNavLayout";    @Override    public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes)    {        Log.e(TAG, "onStartNestedScroll");        return true;    }    @Override    public void onNestedScrollAccepted(View child, View target, int nestedScrollAxes)    {        Log.e(TAG, "onNestedScrollAccepted");    }    @Override    public void onStopNestedScroll(View target)    {        Log.e(TAG, "onStopNestedScroll");    }    @Override    public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed)    {        Log.e(TAG, "onNestedScroll");    }    @Override    public void onNestedPreScroll(View target, int dx, int dy, int[] consumed)    {        Log.e(TAG, "onNestedPreScroll");        boolean hiddenTop = dy > 0 && getScrollY() < mTopViewHeight;        boolean showTop = dy < 0 && getScrollY() >= 0 && !ViewCompat.canScrollVertically(target, -1);        if (hiddenTop || showTop)        {            scrollBy(0, dy);            consumed[1] = dy;        }    }    @Override    public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed)    {        Log.e(TAG, "onNestedFling");        return false;    }    @Override    public boolean onNestedPreFling(View target, float velocityX, float velocityY)    {        Log.e(TAG, "onNestedPreFling");        //down - //up+        if (getScrollY() >= mTopViewHeight) return false;        fling((int) velocityY);        return true;    }    @Override    public int getNestedScrollAxes()    {        Log.e(TAG, "getNestedScrollAxes");        return 0;    }    private View mTop;    private View mNav;    private ViewPager mViewPager;    private int mTopViewHeight;    private OverScroller mScroller;    private VelocityTracker mVelocityTracker;    private int mTouchSlop;    private int mMaximumVelocity, mMinimumVelocity;    private float mLastY;    private boolean mDragging;    public StickyNavLayout(Context context, AttributeSet attrs)    {        super(context, attrs);        setOrientation(LinearLayout.VERTICAL);        mScroller = new OverScroller(context);        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();        mMaximumVelocity = ViewConfiguration.get(context)                .getScaledMaximumFlingVelocity();        mMinimumVelocity = ViewConfiguration.get(context)                .getScaledMinimumFlingVelocity();    }    private void initVelocityTrackerIfNotExists()    {        if (mVelocityTracker == null)        {            mVelocityTracker = VelocityTracker.obtain();        }    }    private void recycleVelocityTracker()    {        if (mVelocityTracker != null)        {            mVelocityTracker.recycle();            mVelocityTracker = null;        }    }    @Override    public boolean onTouchEvent(MotionEvent event)    {        initVelocityTrackerIfNotExists();        mVelocityTracker.addMovement(event);        int action = event.getAction();        float y = event.getY();        switch (action)        {            case MotionEvent.ACTION_DOWN:                if (!mScroller.isFinished())                    mScroller.abortAnimation();                mLastY = y;                return true;            case MotionEvent.ACTION_MOVE:                float dy = y - mLastY;                if (!mDragging && Math.abs(dy) > mTouchSlop)                {                    mDragging = true;                }                if (mDragging)                {                    scrollBy(0, (int) -dy);                }                mLastY = y;                break;            case MotionEvent.ACTION_CANCEL:                mDragging = false;                recycleVelocityTracker();                if (!mScroller.isFinished())                {                    mScroller.abortAnimation();                }                break;            case MotionEvent.ACTION_UP:                mDragging = false;                mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);                int velocityY = (int) mVelocityTracker.getYVelocity();                if (Math.abs(velocityY) > mMinimumVelocity)                {                    fling(-velocityY);                }                recycleVelocityTracker();                break;        }        return super.onTouchEvent(event);    }    @Override    protected void onFinishInflate()    {        super.onFinishInflate();        mTop = findViewById(R.id.id_stickynavlayout_topview);        mNav = findViewById(R.id.id_stickynavlayout_indicator);        View view = findViewById(R.id.id_stickynavlayout_viewpager);        if (!(view instanceof ViewPager))        {            throw new RuntimeException(                    "id_stickynavlayout_viewpager show used by ViewPager !");        }        mViewPager = (ViewPager) view;    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)    {        //不限制顶部的高度        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        getChildAt(0).measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));        ViewGroup.LayoutParams params = mViewPager.getLayoutParams();        params.height = getMeasuredHeight() - mNav.getMeasuredHeight();        setMeasuredDimension(getMeasuredWidth(), mTop.getMeasuredHeight() + mNav.getMeasuredHeight() + mViewPager.getMeasuredHeight());    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh)    {        super.onSizeChanged(w, h, oldw, oldh);        mTopViewHeight = mTop.getMeasuredHeight();    }    public void fling(int velocityY)    {        mScroller.fling(0, getScrollY(), 0, velocityY, 0, 0, 0, mTopViewHeight);        invalidate();    }    @Override    public void scrollTo(int x, int y)    {        if (y < 0)        {            y = 0;        }        if (y > mTopViewHeight)        {            y = mTopViewHeight;        }        if (y != getScrollY())        {            super.scrollTo(x, y);        }        isTopHidden = getScrollY() == mTopViewHeight;    }    @Override    public void computeScroll()    {        if (mScroller.computeScrollOffset())        {            scrollTo(0, mScroller.getCurrY());            invalidate();        }    }    @Override    public boolean dispatchTouchEvent(MotionEvent ev) {        int action = ev.getAction();        float y = ev.getY();        switch (action) {            case MotionEvent.ACTION_DOWN:                mLastY = y;                break;            case MotionEvent.ACTION_MOVE:                float dy = y - mLastY;                getCurrentScrollView();                if (mInnerScrollView instanceof ScrollView) {                    if (mInnerScrollView.getScrollY() == 0 && isTopHidden && dy > 0                            && !isInControl) {                        isInControl = true;                        ev.setAction(MotionEvent.ACTION_CANCEL);                        MotionEvent ev2 = MotionEvent.obtain(ev);                        dispatchTouchEvent(ev);                        ev2.setAction(MotionEvent.ACTION_DOWN);                        return dispatchTouchEvent(ev2);                    }                } else if (mInnerScrollView instanceof ListView) {                    ListView lv = (ListView) mInnerScrollView;                    View c = lv.getChildAt(lv.getFirstVisiblePosition());                    if (!isInControl && c != null && c.getTop() == 0 && isTopHidden                            && dy > 0) {                        isInControl = true;                        ev.setAction(MotionEvent.ACTION_CANCEL);                        MotionEvent ev2 = MotionEvent.obtain(ev);                        dispatchTouchEvent(ev);                        ev2.setAction(MotionEvent.ACTION_DOWN);                        return dispatchTouchEvent(ev2);                    }                }else if (mInnerScrollView instanceof PullToRefreshListView) {                    ListView lv =  ((PullToRefreshListView) mInnerScrollView).getRefreshableView();                    View c = lv.getChildAt(lv.getFirstVisiblePosition());                    if (!isInControl && c != null && c.getTop() == 0 && isTopHidden                            && dy > 0) {                        isInControl = true;                        ev.setAction(MotionEvent.ACTION_CANCEL);                        MotionEvent ev2 = MotionEvent.obtain(ev);                        dispatchTouchEvent(ev);                        ev2.setAction(MotionEvent.ACTION_DOWN);                        return dispatchTouchEvent(ev2);                    }                }                break;        }        return super.dispatchTouchEvent(ev);    }    /**     *     */    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        final int action = ev.getAction();        float y = ev.getY();        switch (action) {            case MotionEvent.ACTION_DOWN:                mLastY = y;                break;            case MotionEvent.ACTION_MOVE:                float dy = y - mLastY;                getCurrentScrollView();                if (Math.abs(dy) > mTouchSlop) {                    mDragging = true;                    if (mInnerScrollView instanceof ScrollView) {                        // 如果topView没有隐藏                        // 或sc的scrollY = 0 && topView隐藏 && 下拉,则拦截                        if (!isTopHidden                                || (mInnerScrollView.getScrollY() == 0                                && isTopHidden && dy > 0)) {                            initVelocityTrackerIfNotExists();                            mVelocityTracker.addMovement(ev);                            mLastY = y;                            return true;                        }                    } else if (mInnerScrollView instanceof ListView) {                        ListView lv = (ListView) mInnerScrollView;                        View c = lv.getChildAt(lv.getFirstVisiblePosition());                        // 如果topView没有隐藏                        // 或sc的listView在顶部 && topView隐藏 && 下拉,则拦截                        if (!isTopHidden || c==null||//                                (c != null //                                        && c.getTop() == 0//                                        && isTopHidden && dy > 0)) {                            initVelocityTrackerIfNotExists();                            mVelocityTracker.addMovement(ev);                            mLastY = y;                            Log.d(TAG,"onInterceptTouchEvent: true");                            return true;                        }                    }else if (mInnerScrollView instanceof PullToRefreshListView) {                        ListView lv = ((PullToRefreshListView) mInnerScrollView).getRefreshableView();                        View c = lv.getChildAt(lv.getFirstVisiblePosition());                        // 如果topView没有隐藏                        // 或sc的listView在顶部 && topView隐藏 && 下拉,则拦截                        if (!isTopHidden || c==null||//                                (c != null //                                        && c.getTop() == 0//                                        && isTopHidden && dy > 0)) {                            initVelocityTrackerIfNotExists();                            mVelocityTracker.addMovement(ev);                            mLastY = y;                            Log.d(TAG,"onInterceptTouchEvent: true");                            return true;                        }                    }                }                break;            case MotionEvent.ACTION_CANCEL:            case MotionEvent.ACTION_UP:                mDragging = false;                recycleVelocityTracker();                break;        }        Log.d(TAG,"onInterceptTouchEvent:"+super.onInterceptTouchEvent(ev)+"");        return super.onInterceptTouchEvent(ev);    }    private ViewGroup mInnerScrollView;    private boolean isTopHidden = false;    private boolean isInControl = false;    private void getCurrentScrollView() {        int currentItem = mViewPager.getCurrentItem();        PagerAdapter a = mViewPager.getAdapter();        if (a instanceof FragmentPagerAdapter) {            FragmentPagerAdapter fadapter = (FragmentPagerAdapter) a;            Fragment item = (Fragment) fadapter.instantiateItem(mViewPager,                    currentItem);            mInnerScrollView = (ViewGroup) (item.getView()                    .findViewById(R.id.id_stickynavlayout_innerscrollview));        } else if (a instanceof FragmentStatePagerAdapter) {            FragmentStatePagerAdapter fsAdapter = (FragmentStatePagerAdapter) a;            Fragment item = (Fragment) fsAdapter.instantiateItem(mViewPager,                    currentItem);            mInnerScrollView = (ViewGroup) (item.getView()                    .findViewById(R.id.id_stickynavlayout_innerscrollview));        }    }}
tab菜单栏
public class SimpleViewPagerIndicator extends LinearLayout{   private static final int COLOR_TEXT_NORMAL = 0xFF000000;   private static final int COLOR_INDICATOR_COLOR = Color.GREEN;   private String[] mTitles;   private int mTabCount;   private int mIndicatorColor = COLOR_INDICATOR_COLOR;   private float mTranslationX;   private Paint mPaint = new Paint();   private int mTabWidth;   public SimpleViewPagerIndicator(Context context)   {      this(context, null);   }   public SimpleViewPagerIndicator(Context context, AttributeSet attrs)   {      super(context, attrs);      mPaint.setColor(mIndicatorColor);      mPaint.setStrokeWidth(9.0F);   }   @Override   protected void onSizeChanged(int w, int h, int oldw, int oldh)   {      super.onSizeChanged(w, h, oldw, oldh);      mTabWidth = w / mTabCount;   }   public void setTitles(String[] titles)   {      mTitles = titles;      mTabCount = titles.length;      generateTitleView();   }   public void setIndicatorColor(int indicatorColor)   {      this.mIndicatorColor = indicatorColor;   }   private OnPagerSelected mOnPagerSelected;   public void setOnPagerSelected(OnPagerSelected listener){      mOnPagerSelected=listener;   }   public interface OnPagerSelected{      void onPagerSelected(int position);   }   @Override   protected void dispatchDraw(Canvas canvas)   {      super.dispatchDraw(canvas);      canvas.save();      canvas.translate(mTranslationX, getHeight() - 2);      canvas.drawLine(0, 0, mTabWidth, 0, mPaint);      canvas.restore();   }   public void scroll(int position, float offset)   {      /**       * <pre>       *  0-1:position=0 ;1-0:postion=0;       * </pre>       */      mTranslationX = getWidth() / mTabCount * (position + offset);      invalidate();   }   @Override   public boolean dispatchTouchEvent(MotionEvent ev)   {      return super.dispatchTouchEvent(ev);   }   private void generateTitleView()   {      if (getChildCount() > 0)         this.removeAllViews();      int count = mTitles.length;      setWeightSum(count);      for (int i = 0; i < count; i++)      {         TextView tv = new TextView(getContext());         LayoutParams lp = new LayoutParams(0,               LayoutParams.MATCH_PARENT);         lp.weight = 1;         tv.setGravity(Gravity.CENTER);         tv.setTextColor(COLOR_TEXT_NORMAL);         tv.setText(mTitles[i]);         tv.setTag(i);         tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);         tv.setLayoutParams(lp);         tv.setOnClickListener(new OnClickListener()         {            @Override            public void onClick(View v)            {               if(mOnPagerSelected!=null){                  mOnPagerSelected.onPagerSelected((int) v.getTag());               }            }         });         addView(tv);      }   }}

0 0
原创粉丝点击