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
- android 带漂浮tab菜单 StickyNavLayout
- (Android特效)-Android-StickyNavLayout
- Android实现底部菜单Tab
- Android中实现StickyNavLayout自己的小demo
- android TAb分页菜单实现总结
- 【Android】FragmentTabHost实现底部Tab菜单选项
- Android TAb分页菜单实现总结
- android 主页底部菜单tab切换标签
- 漂浮图片带关闭按钮
- tab菜单
- Tab菜单
- 关于带Tab的Android应用
- Android 漂浮的Activity
- Android漂浮窗口
- Android 漂浮的Activity
- ANDROID-漂浮背景效果
- 漂浮广告代码2 带分析
- Android 设置界面修改为Iphone的tab菜单风格
- 一个实际项目Java架构设计之总体设计
- zookeeper简单使用
- C到C++完美过度(三)
- linux-防火墙
- SVN配置及操作
- android 带漂浮tab菜单 StickyNavLayout
- C语言基本数据结构之四(线性,对分,二叉树查找及二叉树删除)
- TFTP服务器搭建
- /lib64/libc.so.6: version `GLIBC_2.14' not found问题
- mysql实现hash分表
- Hibernate
- 学习UML后的一点总结
- 如何编写一个简单群聊
- 单例设计模式