android 嵌套滑动
来源:互联网 发布:淘宝介入卖家没有发票 编辑:程序博客网 时间:2024/05/16 17:19
转载自hongyang blog:http://blog.csdn.net/lmj623565791/article/details/52204039
稍微改动了源码,因为要做的效果有点差别:实际效果为米多财富app产品中心首页(目前线上的app虽然实现了效果,但是快速滑动,有时会有bug),所以想要换一种思路解决,就是接下来要讨论的内容。——嵌套滑动
android 5.0之后,引入了几个类:
NestedScrollingChild
NestedScrollingParent
NestedScrollingChildHelper
NestedScrollingParentHelper
——v4包已经向下兼容,详细用法可以谷歌。
源码:
主要改动了
StickyNavLayout类的内容,其他类没有修改
package com.zhy.stickynavlayout.view;import android.content.Context;import android.support.v4.view.NestedScrollingParent;import android.support.v4.view.ViewCompat;import android.support.v4.view.ViewPager;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup;import android.widget.LinearLayout;import android.widget.OverScroller;import com.zhy.stickynavlayout.R;public class StickyNavLayout extends LinearLayout implements NestedScrollingParent{ //每次事件会调用一次 @Override public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) { return true; } @Override public void onNestedScrollAccepted(View child, View target, int nestedScrollAxes) { } @Override public void onStopNestedScroll(View target) { //getScrollY()的范围在0和mTopViewHeight/2之间 if(getScrollY()<=mTopViewHeight/4)//自动滑下来 { mScroller.startScroll(0,getScrollY(),0,-getScrollY(),500); } else { mScroller.startScroll(0,getScrollY(),0,mTopViewHeight/2-getScrollY(),500); } postInvalidate(); } @Override public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) { } @Override public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) { //dy向上移动为正,向下移动为负 boolean hiddenTop = dy > 0 && getScrollY() < mTopViewHeight/2;//为true表示还没有被隐藏 boolean showTop = dy < 0 && getScrollY() >= 0 && !ViewCompat.canScrollVertically(target, -1);//为true表示不能再往下滑动了 //target滑动的时候为true, if (hiddenTop || showTop)//表示头部还没有完全隐藏 { scrollBy(0, dy); consumed[1] = dy; } } @Override public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) { return false; } @Override public boolean onNestedPreFling(View target, float velocityX, float velocityY) { //down - //up+ if (getScrollY() >= mTopViewHeight/2) return false; fling((int) velocityY);//没演示出什么作用 return true; } @Override public int getNestedScrollAxes() { return 0; } private View mTop; private View mNav; private ViewPager mViewPager; private int mTopViewHeight; private OverScroller mScroller; public StickyNavLayout(Context context, AttributeSet attrs) { super(context, attrs); setOrientation(LinearLayout.VERTICAL); mScroller = new OverScroller(context); } @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)); //重新设置viewpager的高度 ViewGroup.LayoutParams params = mViewPager.getLayoutParams(); params.height = getMeasuredHeight() - mNav.getMeasuredHeight()-mTop.getMeasuredHeight()/2; //重新设置高度,使不会出现底部空白 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/2) { y = mTopViewHeight/2; } if (y != getScrollY()) { super.scrollTo(x, y); } } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { scrollTo(0, mScroller.getCurrY()); invalidate(); } }}
SimpleViewPagerIndicator类
package com.zhy.stickynavlayout.view;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.util.AttributeSet;import android.util.TypedValue;import android.view.Gravity;import android.view.MotionEvent;import android.view.View;import android.widget.LinearLayout;import android.widget.TextView;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);}@Overrideprotected 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;}@Overrideprotected 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();}@Overridepublic 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.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);tv.setLayoutParams(lp);tv.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v){}});addView(tv);}}}
MainActivity类
package com.zhy.stickynavlayout;import android.os.Bundle;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentActivity;import android.support.v4.app.FragmentPagerAdapter;import android.support.v4.view.ViewPager;import android.support.v4.view.ViewPager.OnPageChangeListener;import com.zhy.stickynavlayout.view.SimpleViewPagerIndicator;public class MainActivity extends FragmentActivity{private String[] mTitles = new String[] { "简介", "评价", "相关" };private SimpleViewPagerIndicator mIndicator;private ViewPager mViewPager;private FragmentPagerAdapter mAdapter;private TabFragment[] mFragments = new TabFragment[mTitles.length];@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initViews();initDatas();initEvents();}private void initEvents(){mViewPager.setOnPageChangeListener(new OnPageChangeListener(){@Overridepublic void onPageSelected(int position){}@Overridepublic void onPageScrolled(int position, float positionOffset,int positionOffsetPixels){mIndicator.scroll(position, positionOffset);}@Overridepublic void onPageScrollStateChanged(int state){}});}private void initDatas(){mIndicator.setTitles(mTitles);for (int i = 0; i < mTitles.length; i++){mFragments[i] = (TabFragment) TabFragment.newInstance(mTitles[i]);}mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()){@Overridepublic int getCount(){return mTitles.length;}@Overridepublic Fragment getItem(int position){return mFragments[position];}};mViewPager.setAdapter(mAdapter);mViewPager.setCurrentItem(0);}private void initViews(){mIndicator = (SimpleViewPagerIndicator) findViewById(R.id.id_stickynavlayout_indicator);mViewPager = (ViewPager) findViewById(R.id.id_stickynavlayout_viewpager);}}
TabFragment类
package com.zhy.stickynavlayout;import android.os.Bundle;import android.support.v4.app.Fragment;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import com.zhy.base.adapter.ViewHolder;import com.zhy.base.adapter.recyclerview.CommonAdapter;import java.util.ArrayList;import java.util.List;public class TabFragment extends Fragment{ public static final String TITLE = "title"; private String mTitle = "Defaut Value"; private RecyclerView mRecyclerView; // private TextView mTextView; private List<String> mDatas = new ArrayList<String>(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() != null) { mTitle = getArguments().getString(TITLE); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_tab, container, false); mRecyclerView = (RecyclerView) view .findViewById(R.id.id_stickynavlayout_innerscrollview); mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); // mTextView = (TextView) view.findViewById(R.id.id_info); // mTextView.setText(mTitle); for (int i = 0; i < 50; i++) { mDatas.add(mTitle + " -> " + i); } mRecyclerView.setAdapter(new CommonAdapter<String>(getActivity(), R.layout.item, mDatas) { @Override public void convert(ViewHolder holder, String o) { holder.setText(R.id.id_info, o); } }); return view; } public static TabFragment newInstance(String title) { TabFragment tabFragment = new TabFragment(); Bundle bundle = new Bundle(); bundle.putString(TITLE, title); tabFragment.setArguments(bundle); return tabFragment; }}
activity_main.xml类
<com.zhy.stickynavlayout.view.StickyNavLayout xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RelativeLayout android:id="@id/id_stickynavlayout_topview" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#4400ff00" > <TextView android:layout_width="match_parent" android:layout_height="256dp" android:gravity="center" android:text="软件介绍" android:textSize="30sp" android:textStyle="bold" /> </RelativeLayout> <com.zhy.stickynavlayout.view.SimpleViewPagerIndicator android:id="@id/id_stickynavlayout_indicator" android:layout_width="match_parent" android:layout_height="50dp" android:background="#ffffffff" > </com.zhy.stickynavlayout.view.SimpleViewPagerIndicator> <android.support.v4.view.ViewPager android:id="@id/id_stickynavlayout_viewpager" android:layout_width="match_parent" android:layout_height="match_parent" > </android.support.v4.view.ViewPager></com.zhy.stickynavlayout.view.StickyNavLayout >
fragment_tab.xml
<android.support.v7.widget.RecyclerView android:id="@id/id_stickynavlayout_innerscrollview" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#44ff0000" android:scrollbars="none"></android.support.v7.widget.RecyclerView>
item.xml
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="50dp"> <TextView android:id="@+id/id_info" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffffff" android:gravity="center"> </TextView></FrameLayout>
0 0
- Android 嵌套滑动分析
- android 嵌套滑动
- android嵌套滑动NestedScrolling
- Android ScrollView 嵌套 ScrollView 滑动
- Android NestedScrolling嵌套滑动机制
- android嵌套滑动- Material Design
- 【Android】Scrollview嵌套EditText,使其滑动
- android viewpaper嵌套viewpaper,滑动问题解决
- 浅析:Android 嵌套滑动机制(NestedScrolling)
- Android 嵌套滑动机制(NestedScrolling)
- 详解:Android嵌套滑动机制 (NestedScrolling)
- 详解:Android嵌套滑动机制 (NestedScrolling)
- Android 嵌套ViewPager实现连贯双滑动
- Android listview嵌套viewpager滑动冲突问题
- Android 嵌套滑动机制(NestedScrolling)
- Android 嵌套滑动机制(NestedScrolling)
- Android Listview嵌套viewpager 滑动冲突解决
- Android 嵌套滑动机制(NestedScrolling)
- mycat安装及分片初体验
- SVN的入门用法
- es6新语法arrow function
- eclipse查看jar包源代码乱码问题解决
- apache storm的安装部署
- android 嵌套滑动
- 156.Median of Two Sorted Arrays
- jQuery中$.get、$.post、$.getJSON和$.ajax的用法
- 专业名词解析
- 高光谱图像选择波段的研究
- Linux Oracle删除归档日志
- 笔试选择题9
- 软考之我见——论文
- php中XML与数组的相互转换