仿京东上拉详情展示Webview


compile 'com.android.support:design:22.2.1'
    
 
 
<?xml version="1.0" encoding="utf-8"?>
<com.example.administrator.jingdong.myview.PageContainer
    android:id="@+id/container"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    xmlns:app="http://schemas.android.com/apk/res-auto">
   <com.example.administrator.jingdong.myview.Page
       android:id="@+id/pageOne"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       >
   <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:orientation="vertical">
   <com.stx.xhb.xbanner.XBanner
       android:id="@+id/xbnr"
       app:AutoPlayTime="1000"
       android:layout_width="match_parent"
       android:layout_height="500px"></com.stx.xhb.xbanner.XBanner>
      <TextView
          android:textSize="50px"
          android:text="你猜"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:id="@+id/feilei_xiangqing_fragment_title"/>

   <TextView
       android:textSize="50px"
       android:layout_marginTop="30px"
       android:text="85"
       android:layout_width="match_parent"
       android:layout_height="0px"
       android:layout_weight="1"
       android:id="@+id/feilei_xiangqing_fragment_price"/>
   </LinearLayout>
   </com.example.administrator.jingdong.myview.Page>


   <com.example.administrator.jingdong.myview.Page
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       app:layout_behavior="@string/pageBehavior">
      <WebView
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:id="@+id/web"></WebView>

   </com.example.administrator.jingdong.myview.Page>

   

</com.example.administrator.jingdong.myview.PageContainer>

 
 
 
 
 
 
public class Page extends NestedScrollView {
    private boolean scrollAble = true;
    private float y;
    private float oldy = 0;
    private OnScrollListener onScrollListener;

    public Page(Context context) {
        this(context, null);
    }

    public Page(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public Page(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        ViewConfiguration.getTouchSlop();
    }

    public void setScrollAble(boolean scrollAble) {
        this.scrollAble = scrollAble;
    }

    public void setScrollAble(boolean scrollAble, float y) {
        this.scrollAble = scrollAble;
        this.y = y;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (scrollAble) {
            return super.onTouchEvent(ev);
        } else {
            switch (ev.getAction()) {
                case MotionEvent.ACTION_MOVE:
                    float distanceY = 0;
                    float newY = 0;
                    if (oldy == 0) {
                        distanceY = 1;
                        newY = ev.getRawY();
                    } else {
                        newY = ev.getRawY();
                        distanceY = newY - oldy;
                    }
                    oldy = newY;

                    if (onScrollListener != null) {
                        onScrollListener.onScroll(distanceY, y);
                    }

                    return true;
                case MotionEvent.ACTION_UP:

                    if (onScrollListener != null) {
                        onScrollListener.onScroll(-10000, y);
                    }
                    scrollAble = true;
                    oldy = 0;
                    return true;
                default:
                    return true;
            }

        }
    }

    public void setScrollListener(OnScrollListener onScrollListener) {
        this.onScrollListener = onScrollListener;
    }


    public interface OnScrollListener {
        void onScroll(float scrollY, float y);
    }

}

 
 
 
public class PageContainer extends CoordinatorLayout implements Page.OnScrollListener {
    private Page child;
    private PageBehavior behavior;

    public PageContainer(Context context) {
        this(context, null);
    }

    public PageContainer(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PageContainer(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    public void setOnPageChanged(
            PageBehavior.OnPageChanged onPageChanged) {
        if (behavior != null) {
            behavior.setOnPageChanged(onPageChanged);

        }
    }

    @Override
    public void onScroll(float scrollY, float distance) {
        if (scrollY == -10000) {
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    scrollTo(0, 0);
                }
            }, -10);
        } else {
            int y = (int) (getScrollY() - scrollY);
            if (y < distance) {
                return;
            }
            scrollTo(0, y);
            if (behavior != null) {
                behavior.setScrollY((int) (distance - y));
            }
        }
    }

    @Override
    public void onViewAdded(View child) {
        super.onViewAdded(child);
        if (child instanceof Page) {
            this.child = ((Page) child);
            this.child.setScrollListener(this);
        }

        LayoutParams layoutParams = (LayoutParams) child.getLayoutParams();
        if (layoutParams.getBehavior() != null && layoutParams.getBehavior() instanceof PageBehavior) {
            behavior = (PageBehavior) layoutParams.getBehavior();
        }

    }

    public void backToTop(){
        if (behavior!=null){
            behavior.backToTop();
        }
    }

    public void scrollToBottom(){
        if (behavior!=null){
            behavior.scrollToBottom();
        }
    }
}


 
 
public class PageBehavior extends CoordinatorLayout.Behavior {
    private static final int PAGE_ONE = 1;
    private static final int PAGE_TWO = 2;
    private WeakReference<View> dependentView,childView;
    private Scroller scroller;
    private Handler handler;
    private int status = PAGE_ONE;//记录状态
    private float gap;
    private int totalOne = 0;
    private int scrollY = 0;
    private int mode = 0;

    public OnPageChanged mOnPageChanged;

    public void setOnPageChanged(
            OnPageChanged onPageChanged) {
        mOnPageChanged = onPageChanged;
    }


    public PageBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
        scroller = new Scroller(context);
        handler = new Handler();
        gap = 100;
    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
        //设定依赖视图为id是R.id.pageOne的View
        if (dependency.getId() == R.id.pageOne) {
            dependentView = new WeakReference<>(dependency);
            childView=new WeakReference<>(child);
            return true;
        }
        return false;
    }

    @Override
    public boolean onLayoutChild(CoordinatorLayout parent, View child, int layoutDirection) {
        //child的布局
        child.layout(0, 0, parent.getWidth(), child.getMeasuredHeight());
        return true;
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
        //让child随着依赖视图的属性变动而变动
        child.setTranslationY(dependency.getMeasuredHeight() + dependency.getTranslationY());
        return true;
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, View child, View directTargetChild, View target, int nestedScrollAxes) {
        //只监测Vertical方向的动作
        scroller.abortAnimation();//停止动画
        return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0;
    }

    @Override
    public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);

        if (status == PAGE_ONE) {
            if (dyUnconsumed > 0) {
                View dependentView = getDependentView();
                totalOne = (totalOne - dyUnconsumed);
                dependentView.setTranslationY(totalOne * 0.5f);
            }

            if (dependentView.get().getTranslationY() < 0 && dyConsumed < 0) {
                mode = 1;
                ((Page) dependentView.get()).setScrollAble(false, dependentView.get().getTranslationY());
            }

        } else if (status == PAGE_TWO) {
            if (dyUnconsumed < 0) {
                View dependentView = getDependentView();
                totalOne = (totalOne + dyUnconsumed);
                int newTranslate = (int) (-dependentView.getMeasuredHeight() - (totalOne * 0.5));
                dependentView.setTranslationY(newTranslate);
            }

            if (dependentView.get().getTranslationY() > -dependentView.get().getHeight() && dyConsumed > 0) {
                mode = 1;
                ((Page) child).setScrollAble(false, dependentView.get().getTranslationY());
            }
        }
    }

    @Override
    public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target) {
        super.onStopNestedScroll(coordinatorLayout, child, target);
        totalOne = 0;
        View dependentView = getDependentView();
        float translationY = dependentView.getTranslationY();
        if (status == PAGE_ONE) {
            if (mode == 0) {
                if (translationY < -gap) {
                    scroller.startScroll(0, (int) translationY, 0, (int) (-dependentView.getMeasuredHeight() - translationY));
                    status = PAGE_TWO;
                    if (mOnPageChanged!=null){
                        mOnPageChanged.toBottom();
                    }
                } else {
                    scroller.startScroll(0, (int) translationY, 0, (int) (-translationY));
                }
            } else {
                mode = 0;
                if (scrollY < -gap) {
                    scroller.startScroll(0, scrollY, 0, -dependentView.getMeasuredHeight() - scrollY);
                    status = PAGE_TWO;
                    if (mOnPageChanged!=null){
                        mOnPageChanged.toBottom();
                    }
                } else {
                    scroller.startScroll(0, scrollY, 0, -scrollY);
                }
            }
        } else if (status == PAGE_TWO) {
            if (mode == 0) {
                if (translationY < -dependentView.getMeasuredHeight() + gap) {
                    scroller.startScroll(0, (int) translationY, 0, (int) (-dependentView.getMeasuredHeight() - translationY));

                } else {
                    scroller.startScroll(0, (int) translationY, 0, (int) (-translationY));
                    status = PAGE_ONE;
                    if (mOnPageChanged!=null){
                        mOnPageChanged.toTop();
                    }
                }
            } else {
                mode = 0;
                if (scrollY < -dependentView.getMeasuredHeight() + gap) {
                    scroller.startScroll(0, scrollY, 0, -dependentView.getMeasuredHeight() - scrollY);
                } else {
                    scroller.startScroll(0, scrollY, 0, -scrollY);
                    status = PAGE_ONE;
                    if (mOnPageChanged!=null){
                        mOnPageChanged.toTop();
                    }
                }
            }
        }

        handler.post(new Running());
    }

    private View getDependentView() {
        return dependentView.get();
    }

    private class Running implements Runnable {
        @Override
        public void run() {
            if (scroller.computeScrollOffset()) {
                View dependentView = getDependentView();
                dependentView.setTranslationY(scroller.getCurrY());
                handler.post(this);
            } else {


            }
        }
    }

    public void setScrollY(int scrollY) {
        this.scrollY = scrollY;
    }

    public void backToTop(){
        
        View dependentView = getDependentView();
        float translationY = dependentView.getTranslationY();
        if (status == PAGE_TWO) {
            if (mode == 0) {
                childView.get().setScrollY(0);
                dependentView.setScrollY(0);
                scroller.startScroll(0, (int) translationY, 0, (int) (-translationY));
                status = PAGE_ONE;
                if (mOnPageChanged!=null){
                    mOnPageChanged.toTop();
                }
            }
        }

        handler.post(new Running());
    }


    public void scrollToBottom(){
        View dependentView = getDependentView();
        float translationY = dependentView.getTranslationY();
        dependentView.setScrollY(dependentView.getMeasuredHeight());
        if (status == PAGE_ONE) {
            if (mode == 0) {
                    scroller.startScroll(0, (int) translationY, 0, (int) (-dependentView.getMeasuredHeight() - translationY));
                    status = PAGE_TWO;
                    if (mOnPageChanged!=null){
                        mOnPageChanged.toBottom();
                    }
                }
            }

        handler.post(new Running());
    }

    public interface OnPageChanged{
        
        void  toTop();
        
        void  toBottom();
    }
}


R.id.pageOne 为ids   ids为values下的xml文件

 
ids代码如下
 
<?xml version="1.0" encoding="utf-8"?>
<resources >
    <item name="pageOne" type="id" />
</resources >
 
 
strings代码如下
//
 app:layout_behavior="@string/pageBehavior">为values下的string文件
com.example.administrator.jingdong.myview  为PageBehavior的包名
 
<resources>
    <string name="app_name">webxiangqing</string>
    <string name="pageBehavior" translatable="false" >
com.example.administrator.jingdong.myview.PageBehavior</string >
 </ 
resources> 
public class MainActivity extends AppCompatActivity {

    private PageContainer container;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        WebView web = findViewById(R.id.web);
        web.loadUrl("https://github.com/ysnows");
        container = (PageContainer) findViewById(R.id.container);
        container.setOnPageChanged(new PageBehavior.OnPageChanged(){

            @Override
            public void toTop() {
                //位于第一页
                Toast.makeText(MainActivity.this, "我是第一页", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void toBottom() {
                Toast.makeText(MainActivity.this, "你好啊", Toast.LENGTH_SHORT).show();
            }
        });
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值