最近项目需求类似于淘宝中的继续拖动,显示详情页面,就是当activity滑动到底部时,会出来另一个webview,这其中可能会出现scrollview和webview冲突。

效果图如下:


下载地址: http://www.see-source.com/androidwidget/detail.html?wid=519
<span style="font-size:18px;">在网上查的demo,与大家共享,代码如下:
MainActivity代码:
package com.stone.verticalslide;import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Window;import com.stone.verticalslide.DragLayout.ShowNextPageNotifier;public class MainActivity extends FragmentActivity {private VerticalFragment1 fragment1;private VerticalFragment3 fragment3;private DragLayout draglayout;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_main);initView();}/*** 初始化View*/private void initView() {fragment1 = new VerticalFragment1();fragment3 = new VerticalFragment3();getSupportFragmentManager().beginTransaction().add(R.id.first, fragment1).add(R.id.second, fragment3).commit();ShowNextPageNotifier nextIntf = new ShowNextPageNotifier() {@Overridepublic void onDragNext() {fragment3.initView();}};draglayout = (DragLayout) findViewById(R.id.draglayout);draglayout.setNextPageListener(nextIntf);}}MainActivity的xml文件代码:
<LinearLayout 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:orientation="vertical" ><TextViewandroid:layout_width="fill_parent"android:layout_height="50dp"android:background="#1fa9a6"android:gravity="center"android:text="商品详情"android:textColor="#fff"android:textSize="18sp"android:textStyle="bold" /><Viewandroid:layout_width="fill_parent"android:layout_height="1px"android:background="#aaaaaa" /><com.stone.verticalslide.DragLayoutandroid:id="@+id/draglayout"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1" ><FrameLayoutandroid:id="@+id/first"android:layout_width="fill_parent"android:layout_height="fill_parent" /><FrameLayoutandroid:id="@+id/second"android:layout_width="fill_parent"android:layout_height="fill_parent" /></com.stone.verticalslide.DragLayout><Viewandroid:layout_width="fill_parent"android:layout_height="1px"android:background="#aaa" /><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="60dp"android:background="#fff"android:gravity="center_vertical"android:orientation="horizontal" ><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:layout_weight="1"android:gravity="left"android:text="¥28.00"android:textColor="#f00" /><TextViewandroid:layout_width="110dp"android:layout_height="35dp"android:layout_marginLeft="10dp"android:background="#ff0000"android:gravity="center"android:text="加入购物车"android:textColor="#fff"android:textSize="18sp" /><TextViewandroid:layout_width="90dp"android:layout_height="35dp"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:background="#454545"android:drawableLeft="@drawable/qq"android:gravity="center"android:paddingLeft="10dp"android:paddingRight="10dp"android:text="客服"android:textColor="#fff"android:textSize="18sp" /></LinearLayout></LinearLayout>
两个碎片代码:
第一个碎片:
package com.stone.verticalslide;import android.graphics.Paint;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;public class VerticalFragment1 extends Fragment {@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View rootView = inflater.inflate(R.layout.vertical_fragment1, null);TextView oldTextView = (TextView) rootView.findViewById(R.id.old_textview);oldTextView.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG);return rootView;}
}
碎片的xml文件代码:
<?xml version="1.0" encoding="utf-8"?>
<com.stone.verticalslide.CustScrollView xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/custScrollView"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#fff"android:orientation="vertical" ><LinearLayoutandroid:layout_width="match_parent"android:layout_height="fill_parent"android:orientation="vertical" ><RelativeLayoutandroid:layout_width="fill_parent"android:layout_height="220dp"android:background="@drawable/img001" ><TextViewandroid:layout_width="33dp"android:layout_height="28dp"android:layout_marginLeft="10dp"android:layout_marginTop="10dp"android:background="@drawable/alpha_circle"android:gravity="center"android:text="1/4"android:textColor="#fff" /><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="60dp"android:layout_alignParentBottom="true"android:background="#3f000000"android:gravity="center_vertical"android:orientation="horizontal" ><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:layout_weight="1"android:text="THE FACE SHOP菲诗小铺深层清洁洁面乳170ml"android:textColor="#fff"android:textSize="16sp" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="8dp"android:drawablePadding="5dp"android:drawableTop="@drawable/share_button"android:text="分享"android:textColor="#fff" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:drawablePadding="5dp"android:drawableTop="@drawable/love"android:text="收藏"android:textColor="#fff" /></LinearLayout></RelativeLayout><RelativeLayoutandroid:layout_width="fill_parent"android:layout_height="60dp" ><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerVertical="true"android:gravity="center_horizontal"android:orientation="vertical" ><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal" ><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:text="¥28.00"android:textColor="#f00"android:textSize="16sp" /><TextViewandroid:id="@+id/old_textview"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="5dp"android:text="¥28.00 "android:textColor="#888"android:textSize="16sp" /></LinearLayout><TextViewandroid:layout_width="50dp"android:layout_height="22dp"android:layout_marginTop="5dp"android:background="#ec616c"android:gravity="center"android:text="包邮"android:textColor="#fff" /></LinearLayout><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_centerVertical="true"android:layout_marginRight="20dp"android:gravity="center_horizontal"android:orientation="vertical" ><TextViewandroid:layout_width="wrap_content"android:layout_height="22dp"android:gravity="center"android:text="已售出 28303 件"android:textColor="#999" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:gravity="center"android:text="库存:1354件"android:textColor="#999" /></LinearLayout></RelativeLayout><Viewandroid:layout_width="fill_parent"android:layout_height="1px"android:background="#ddd" /><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="44dp"android:gravity="center_vertical"android:orientation="horizontal" ><Viewandroid:layout_width="24dp"android:layout_height="24dp"android:layout_marginLeft="10dp"android:background="@drawable/goods_introduction" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:text="商品简介"android:textColor="#444" /></LinearLayout><Viewandroid:layout_width="fill_parent"android:layout_height="1px"android:background="#ddd" /><TextViewandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_marginBottom="10dp"android:layout_marginLeft="10dp"android:layout_marginTop="10dp"android:lineSpacingExtra="5dp"android:text="商品名称:THE FACE SHOP菲诗小铺深层清洁洁面乳170ml\n品牌:菲诗小铺\n适用肤质:油性肌肤、混合肌肤\n产地:中国\n生产日期:详见商品包装\n保质期:三年\n包装方式:无盒塑封"android:textColor="#888" /><Viewandroid:layout_width="fill_parent"android:layout_height="1px"android:background="#ddd" /><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="44dp"android:gravity="center_vertical"android:orientation="horizontal" ><Viewandroid:layout_width="24dp"android:layout_height="24dp"android:layout_marginLeft="10dp"android:background="@drawable/comment" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:text="商品评价  (6314)"android:textColor="#444" /></LinearLayout><Viewandroid:layout_width="fill_parent"android:layout_height="1px"android:background="#ddd" /><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:gravity="center_vertical"android:orientation="horizontal"android:paddingBottom="5dp"android:paddingTop="5dp" ><Viewandroid:layout_width="30dp"android:layout_height="30dp"android:layout_marginLeft="14dp"android:background="@drawable/head" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:text="182***@qq.com"android:textColor="#999" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:text="油性发质"android:textColor="#999" /><RatingBarstyle="?android:attr/ratingBarStyleSmall"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:numStars="5" /></LinearLayout><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="14dp"android:layout_marginTop="5dp"android:lineSpacingExtra="5dp"android:text="这个真的是全五星级的宝贝啊,白菜价格,超级大的一瓶,真的是超乎你的想象,我买的樱桃的,非常喜欢,膏体是淡淡的粉色,泡沫很细腻,配上丽子送的..."android:textColor="#555" /><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:gravity="center_vertical"android:orientation="horizontal"android:paddingBottom="8dp"android:paddingTop="5dp" ><Viewandroid:layout_width="60dp"android:layout_height="60dp"android:layout_marginLeft="14dp"android:background="@drawable/capture01" /><Viewandroid:layout_width="60dp"android:layout_height="60dp"android:layout_marginLeft="14dp"android:background="@drawable/capture02" /><Viewandroid:layout_width="60dp"android:layout_height="60dp"android:layout_marginLeft="14dp"android:background="@drawable/capture03" /><Viewandroid:layout_width="60dp"android:layout_height="60dp"android:layout_marginLeft="14dp"android:background="@drawable/capture04" /></LinearLayout><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:paddingBottom="10dp"android:paddingTop="5dp" ><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginLeft="14dp"android:layout_weight="1"android:text="樱桃"android:textColor="#888" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:layout_marginRight="10dp"android:text="2015-01-15 10:12:50"android:textColor="#888" /></LinearLayout><Viewandroid:layout_width="fill_parent"android:layout_height="1px"android:background="#ddd" /><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:gravity="center_vertical"android:orientation="horizontal"android:paddingBottom="10dp"android:paddingTop="10dp" ><Viewandroid:layout_width="70dp"android:layout_height="70dp"android:layout_marginLeft="14dp"android:background="@drawable/official" /><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:orientation="vertical" ><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="官方直营"android:textColor="#444" /><RatingBarstyle="?android:attr/ratingBarStyleSmall"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:numStars="5"android:rating="5" /><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:orientation="horizontal" ><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:background="#f57c86"android:paddingLeft="4dp"android:paddingRight="4dp"android:text="全场包邮"android:textColor="#fff" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="5dp"android:background="#f57c86"android:paddingLeft="4dp"android:paddingRight="4dp"android:text="48小时发货"android:textColor="#fff" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="5dp"android:background="#f57c86"android:paddingLeft="4dp"android:paddingRight="4dp"android:text="30天退换货"android:textColor="#fff" /></LinearLayout></LinearLayout><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:text="进店\n看看"android:textColor="#888" /></LinearLayout><Viewandroid:layout_width="fill_parent"android:layout_height="1px"android:background="#ddd" /><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="60dp"android:background="#fafafa"android:gravity="center_vertical"android:orientation="horizontal" ><Viewandroid:layout_width="0dp"android:layout_height="1px"android:layout_weight="1"android:background="#ddd" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:paddingLeft="5dp"android:paddingRight="5dp"android:text="继续拖动,查看图文详情"android:textColor="#777"android:textSize="13sp" /><Viewandroid:layout_width="0dp"android:layout_height="1px"android:layout_weight="1"android:background="#ddd" /></LinearLayout></LinearLayout></com.stone.verticalslide.CustScrollView>第二个碎片代码:
package com.stone.verticalslide;import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;public class VerticalFragment3 extends Fragment {private View progressBar;private CustWebView webview;private boolean hasInited = false;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View rootView = inflater.inflate(R.layout.vertical_fragment3, null);webview = (CustWebView) rootView.findViewById(R.id.fragment3_webview);progressBar = rootView.findViewById(R.id.progressbar);return rootView;}public void initView() {if (null != webview && !hasInited) {hasInited = true;progressBar.setVisibility(View.GONE);webview.loadUrl("http://m.zol.com/tuan/");}}
}碎片的xml文件代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent" ><com.stone.verticalslide.CustWebViewandroid:id="@+id/fragment3_webview"android:layout_width="fill_parent"android:layout_height="fill_parent" /><ProgressBarandroid:id="@+id/progressbar"style="@android:style/Widget.ProgressBar.Inverse"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:layout_centerHorizontal="true" /></RelativeLayout>核心类DragLayout 可以装载两个碎片,实现我们要的效果:
package com.stone.verticalslide;import android.annotation.SuppressLint;
import android.content.Context;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;/*** 这是一个viewGroup容器,实现上下两个frameLayout拖动切换* * @author sistone.Zhang*/
@SuppressLint("NewApi")
public class DragLayout extends ViewGroup {/* 拖拽工具类 */private final ViewDragHelper mDragHelper;private GestureDetectorCompat gestureDetector;/* 上下两个frameLayout,在Activity中注入fragment */private View frameView1, frameView2;private int viewHeight;private static final int VEL_THRESHOLD = 100; // 滑动速度的阈值,超过这个绝对值认为是上下private static final int DISTANCE_THRESHOLD = 100; // 单位是像素,当上下滑动速度不够时,通过这个阈值来判定是应该粘到顶部还是底部private int downTop1; // 手指按下的时候,frameView1的getTop值private ShowNextPageNotifier nextPageListener; // 手指松开是否加载下一页的notifierpublic DragLayout(Context context) {this(context, null);}public DragLayout(Context context, AttributeSet attrs) {this(context, attrs, 0);}public DragLayout(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);mDragHelper = ViewDragHelper.create(this, 10f, new DragHelperCallback());mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_BOTTOM);gestureDetector = new GestureDetectorCompat(context,new YScrollDetector());}@Overrideprotected void onFinishInflate() {// 跟findviewbyId一样,初始化上下两个viewframeView1 = getChildAt(0);frameView2 = getChildAt(1);}class YScrollDetector extends SimpleOnGestureListener {@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float dx,float dy) {// 垂直滑动时dy>dx,才被认定是上下拖动return Math.abs(dy) > Math.abs(dx);}}@Overridepublic void computeScroll() {if (mDragHelper.continueSettling(true)) {ViewCompat.postInvalidateOnAnimation(this);}}/*** 这是拖拽效果的主要逻辑*/private class DragHelperCallback extends ViewDragHelper.Callback {@Overridepublic void onViewPositionChanged(View changedView, int left, int top,int dx, int dy) {int childIndex = 1;if (changedView == frameView2) {childIndex = 2;}// 一个view位置改变,另一个view的位置要跟进onViewPosChanged(childIndex, top);}@Overridepublic boolean tryCaptureView(View child, int pointerId) {// 两个子View都需要跟踪,返回truereturn true;}@Overridepublic int getViewVerticalDragRange(View child) {// 这个用来控制拖拽过程中松手后,自动滑行的速度,暂时给一个随意的数值return 1;}@Overridepublic void onViewReleased(View releasedChild, float xvel, float yvel) {// 滑动松开后,需要向上或者乡下粘到特定的位置animTopOrBottom(releasedChild, yvel);}@Overridepublic int clampViewPositionVertical(View child, int top, int dy) {int finalTop = top;if (child == frameView1) {// 拖动的时第一个viewif (top > 0) {// 不让第一个view往下拖,因为顶部会白板finalTop = 0;}} else if (child == frameView2) {// 拖动的时第二个viewif (top < 0) {// 不让第二个view网上拖,因为底部会白板finalTop = 0;}}// finalTop代表的是理论上应该拖动到的位置。此处计算拖动的距离除以一个参数(3),是让滑动的速度变慢。数值越大,滑动的越慢return child.getTop() + (finalTop - child.getTop()) / 3;}}/*** 滑动时view位置改变协调处理* * @param viewIndex*            滑动view的index(1或2)* @param posTop*            滑动View的top位置*/private void onViewPosChanged(int viewIndex, int posTop) {if (viewIndex == 1) {int offsetTopBottom = viewHeight + frameView1.getTop()- frameView2.getTop();frameView2.offsetTopAndBottom(offsetTopBottom);} else if (viewIndex == 2) {int offsetTopBottom = frameView2.getTop() - viewHeight- frameView1.getTop();frameView1.offsetTopAndBottom(offsetTopBottom);}// 有的时候会默认白板,这个很恶心。后面有时间再优化invalidate();}private void animTopOrBottom(View releasedChild, float yvel) {int finalTop = 0; // 默认是粘到最顶端if (releasedChild == frameView1) {// 拖动第一个view松手if (yvel < -VEL_THRESHOLD|| (downTop1 == 0 && frameView1.getTop() < -DISTANCE_THRESHOLD)) {// 向上的速度足够大,就滑动到顶端// 向上滑动的距离超过某个阈值,就滑动到顶端finalTop = -viewHeight;// 下一页可以初始化了if (null != nextPageListener) {nextPageListener.onDragNext();}}} else {// 拖动第二个view松手if (yvel > VEL_THRESHOLD|| (downTop1 == -viewHeight && releasedChild.getTop() > DISTANCE_THRESHOLD)) {// 保持原地不动finalTop = viewHeight;}}if (mDragHelper.smoothSlideViewTo(releasedChild, 0, finalTop)) {ViewCompat.postInvalidateOnAnimation(this);}}/* touch事件的拦截与处理都交给mDraghelper来处理 */@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {if (frameView1.getBottom() > 0 && frameView1.getTop() < 0) {// view粘到顶部或底部,正在动画中的时候,不处理touch事件return false;}boolean yScroll = gestureDetector.onTouchEvent(ev);boolean shouldIntercept = mDragHelper.shouldInterceptTouchEvent(ev);int action = ev.getActionMasked();if (action == MotionEvent.ACTION_DOWN) {// action_down时就让mDragHelper开始工作,否则有时候导致异常 他大爷的mDragHelper.processTouchEvent(ev);downTop1 = frameView1.getTop();}return shouldIntercept && yScroll;}@Overridepublic boolean onTouchEvent(MotionEvent e) {// 统一交给mDragHelper处理,由DragHelperCallback实现拖动效果mDragHelper.processTouchEvent(e); // 该行代码可能会抛异常,正式发布时请将这行代码加上try catchreturn true;}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {// 只在初始化的时候调用// 一些参数作为全局变量保存起来if (frameView1.getTop() == 0) {// 只在初始化的时候调用// 一些参数作为全局变量保存起来frameView1.layout(l, 0, r, b - t);frameView2.layout(l, 0, r, b - t);viewHeight = frameView1.getMeasuredHeight();frameView2.offsetTopAndBottom(viewHeight);} else {// 如果已被初始化,这次onLayout只需要将之前的状态存入即可frameView1.layout(l, frameView1.getTop(), r, frameView1.getBottom());frameView2.layout(l, frameView2.getTop(), r, frameView2.getBottom());}}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {measureChildren(widthMeasureSpec, heightMeasureSpec);int maxWidth = MeasureSpec.getSize(widthMeasureSpec);int maxHeight = MeasureSpec.getSize(heightMeasureSpec);setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, 0),resolveSizeAndState(maxHeight, heightMeasureSpec, 0));}/*** 这是View的方法,该方法不支持android低版本(2.2、2.3)的操作系统,所以手动复制过来以免强制退出*/public static int resolveSizeAndState(int size, int measureSpec,int childMeasuredState) {int result = size;int specMode = MeasureSpec.getMode(measureSpec);int specSize = MeasureSpec.getSize(measureSpec);switch (specMode) {case MeasureSpec.UNSPECIFIED:result = size;break;case MeasureSpec.AT_MOST:if (specSize < size) {result = specSize | MEASURED_STATE_TOO_SMALL;} else {result = size;}break;case MeasureSpec.EXACTLY:result = specSize;break;}return result | (childMeasuredState & MEASURED_STATE_MASK);}public void setNextPageListener(ShowNextPageNotifier nextPageListener) {this.nextPageListener = nextPageListener;}public interface ShowNextPageNotifier {public void onDragNext();}
}自定义的ScrollView:
package com.stone.verticalslide;import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ScrollView;public class CustScrollView extends ScrollView {boolean allowDragBottom = true; // 如果是true,则允许拖动至底部的下一页float downY = 0;boolean needConsumeTouch = true; // 是否需要承包touch事件,needConsumeTouch一旦被定性,则不会更改int maxScroll = -1; // 最大滑动距离public CustScrollView(Context arg0) {this(arg0, null);}public CustScrollView(Context arg0, AttributeSet arg1) {this(arg0, arg1, 0);}public CustScrollView(Context arg0, AttributeSet arg1, int arg2) {super(arg0, arg1, arg2);}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {if (ev.getAction() == MotionEvent.ACTION_DOWN) {downY = ev.getRawY();needConsumeTouch = true; // 默认情况下,scrollView内部的滚动优先,默认情况下由该ScrollView去消费touch事件if (maxScroll > 0&& getScrollY() + getMeasuredHeight() >= maxScroll - 2) {// 允许向上拖动底部的下一页allowDragBottom = true;} else {// 不允许向上拖动底部的下一页allowDragBottom = false;}} else if (ev.getAction() == MotionEvent.ACTION_MOVE) {if (!needConsumeTouch) {// 在最顶端且向上拉了,则这个touch事件交给父类去处理getParent().requestDisallowInterceptTouchEvent(false);return false;} else if (allowDragBottom) {// needConsumeTouch尚未被定性,此处给其定性// 允许拖动到底部的下一页,而且又向上拖动了,就将touch事件交给父viewif (downY - ev.getRawY() > 2) {// flag设置,由父类去消费needConsumeTouch = false;getParent().requestDisallowInterceptTouchEvent(false);return false;}}}// 通知父view是否要处理touch事件getParent().requestDisallowInterceptTouchEvent(needConsumeTouch);return super.dispatchTouchEvent(ev);}@Overrideprotected void onScrollChanged(int l, int t, int oldl, int oldt) {if (maxScroll < 0) {maxScroll = computeVerticalScrollRange();}super.onScrollChanged(l, t, oldl, oldt);}
}自定义的WebView
package com.stone.verticalslide;import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.webkit.WebView;public class CustWebView extends WebView {boolean allowDragTop = true; // 如果是true,则允许拖动至底部的下一页float downY = 0;boolean needConsumeTouch = true; // 是否需要承包touch事件,needConsumeTouch一旦被定性,则不会更改public CustWebView(Context arg0) {this(arg0, null);}public CustWebView(Context arg0, AttributeSet arg1) {this(arg0, arg1, 0);}public CustWebView(Context arg0, AttributeSet arg1, int arg2) {super(arg0, arg1, arg2);}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {if (ev.getAction() == MotionEvent.ACTION_DOWN) {downY = ev.getRawY();needConsumeTouch = true; // 默认情况下,listView内部的滚动优先,默认情况下由该listView去消费touch事件allowDragTop = isAtTop();} else if (ev.getAction() == MotionEvent.ACTION_MOVE) {if (!needConsumeTouch) {// 在最顶端且向上拉了,则这个touch事件交给父类去处理getParent().requestDisallowInterceptTouchEvent(false);return false;} else if (allowDragTop) {// needConsumeTouch尚未被定性,此处给其定性// 允许拖动到底部的下一页,而且又向上拖动了,就将touch事件交给父viewif (ev.getRawY() - downY > 2) {// flag设置,由父类去消费needConsumeTouch = false;getParent().requestDisallowInterceptTouchEvent(false);return false;}}}// 通知父view是否要处理touch事件getParent().requestDisallowInterceptTouchEvent(needConsumeTouch);return super.dispatchTouchEvent(ev);}/*** 判断listView是否在顶部* * @return 是否在顶部*/private boolean isAtTop() {return getScrollY() == 0;}
}</span>

仿淘宝的继续拖动显示详情页面相关推荐

  1. 仿淘宝电商官网静态页面(HTML+CSS+JS)+ 常见布局解析,学会如果做是关键!

    仿淘宝电商官网静态页面 作为一个前端开发,布局+样式已经成为了必备的技能,你做得好是应该的,做的不好可以原谅,但当你意识到不足时,补足它 这是我刚"入坑"的时候写的Demo,因为当 ...

  2. Android自定义控件-仿淘宝ios客户端天猫商品详情界面

    仿照淘宝和聚美优品,在商品详情页,向上拖动时,可以加载下一页.使用ViewDragHelper,滑动比较流畅. scrollView滑动到底部的时候,再行向上拖动时,添加了一些阻力. 项目地址:htt ...

  3. 仿淘宝购物车实现功能:滚动页面到【结算操作】不可视时,浏览器底部出现固定栏

    最近在做一个电商平台,做到购物车的时候,就脑洞大开要模仿淘宝实现一个非常人性化的用户体验性效果.觉得很不错,非常好玩就很大家分享了. 先附上效果图 实现的效果就是这个小东西,哈哈 1.整个页面结算操作 ...

  4. Android自定义控件-仿淘宝ios客户端天猫商品详情界面动效

    效果图 源码和例子 github:https://github.com/teisun/Android-PullPushScrollView  csdn:http://download.csdn.net ...

  5. 仿淘宝商品详情页面Android

    [致谢]:qifengdeqingchen [博客地址]:http://blog.csdn.net/qifengdeqingchen/article/details/51659735 1.需求: 要实 ...

  6. 【jQuery】仿淘宝五星评价打分的实现

    我的上一篇博文写到了评价分数的五星显示,这篇博文将介绍如何实现打分的效果. 首先,我们还是先分析我们想要的效果. 1.当鼠标移到星星上面的时候,当前星星以及前面的星星要亮起来,然后星星的右侧出现提示语 ...

  7. 仿淘宝商品详情-点击显示大图,可滑动

    现在在做一个商城类的项目: 大家都用过淘宝,需求就是要求仿淘宝的效果做一个, 直接上图 用到了一个项目PhotoView 大家运行一下看最后一个项目,把单一的图片显示改成VIewpager就好.

  8. Android仿淘宝详情页面viewPager滑动到最后一张图片跳转的功能

    需要做一个仿淘宝客户端ViewPager滑动到最后一页,再拖动的时候跳到详情的功能,刚开始我也迷糊了,通过查阅相关资料发现有好多种实现方法,下面小编给大家分享实例代码,感兴趣的朋友一起看看吧 需要做一 ...

  9. Ecshop 商品页配送方式添加 实现仿淘宝按地区显示运费

    Ecshop实现仿淘宝按地区显示运费 淘宝网(Taobao)购物的宝贝详情页面,可以针对不同地区显示不同运费,运费由后台设定:结算时间,按重量.件数计算运费.Ecshop本身有配送方式插件,已有多家物 ...

最新文章

  1. 30行Python代码实现高分辨率图像导航
  2. Android中的context
  3. 截取指定内容/截取用逗号隔开的各个关键字
  4. win10: Coursera 视频无法观看问题解决。
  5. the Open Source Community
  6. oracle将字符串转化为blob,oracle String类型转换成blob类型插入
  7. 一场员工高管间的口水战,员工输了
  8. 基于社会资源的普通摄像机1400结构化AI算法改造方案
  9. win10下Miracast无线投屏使用教程及异常解决方案(超详细)
  10. 非线性系统 知识梳理
  11. 唐人笔+手写板连接到计算机usb端口+错误,汉王唐人笔如意驱动
  12. 互联网日报 | 微信聊天时可直接“搜一搜”了;蚂蚁集团9月18日科创板首发上会;谷歌正式发布安卓11系统...
  13. c语言程序填空题库,c语言填空题题库
  14. unity3d FPS 枪的后座力
  15. 道高一尺,魔高一丈--加密与解密的此消彼长
  16. 木瓜移动每日资讯0601:速卖通5月底发布“G100出海计划”
  17. Deer计划(1)点云数据解析成图
  18. 复杂网络学习笔记:networkx实现网络的基本拓扑性质
  19. 如何有效开展小组教学_如何在小学数学教学中有效开展小组合作学习
  20. 隐形守护者服务器维护,隐形守护者更新公告一览 隐形守护者更新3.5有什么内容_游侠网...

热门文章

  1. 对待客户,除了服务要好以外,态度也一定要强硬
  2. Windows 10 重置电脑 重装系统 恢复出产设置 去除所有广告等
  3. bzoj 1917: [Ctsc2010]星际旅行 树形dp解决树上网络流
  4. python编写一个班级类 点名簿_2014年长春市高中毕业班第四次调研测试
  5. App开发用什么软件?零基础也可以制作App
  6. B树B+树的原理和操作
  7. 命里有时终须有与我命由我不由天
  8. Intellij IDEA——启动Tomcat控制台输出繁体乱码
  9. 4家外国支持支付宝支付的域名注册商
  10. 哪些地方可以打印试卷