android 自定义Scrollview实现淘宝二层楼效果新版微信小程序下拉效果

由于最近一段时间真的是太忙了,没有顾上即使更新博客,还请粉丝们见谅,最近要实现这样一个效果,这个效果跟淘宝二层楼和新版微信7.0的下拉小程序效果差不多,百般查找真心没有找到自己合适的,没办法只能自撸了,来看效果。

来,二话不说了,直接上代码吧。

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;
import android.widget.Scroller;/*** Created by zhaoshaohe on 2019.4.1*/
public class StickyScrollView extends ScrollView {public static final String TAG = StickyScrollView.class.getSimpleName();public static final int PAGE_TOP = 0;public static final int PAGE_BOTTOM = 1;public static final double PERCENT = 0.4;public static final int ANIMATION_DURATION = 180;public static final int TOUCH_DURATION = 150;private ViewGroup mChildLayout;private View mTopChildView;private Context mContext;private OnPageChangeListener onPageChangeListener;private boolean isScrollAuto;           //判断是否自由滚动private Scroller mScroller;             //滑动类private int screenHeight;               //屏幕高度private int offsetDistance;             //topview的高度与屏幕的高度差private int topChildHeight;             //topview的高度private boolean isTouch;                //用户是否在触控屏幕private int currentPage;                //值为0时屏幕显示topview,值为1时屏幕显示bottomviewprivate long downTime;                  //用户按下屏幕的时间戳private long upTime;                    //用户抬起时的时间戳private int downY;                      //用户按下屏幕的y坐标private int upY;                        //用户抬起的y坐标private boolean isPageChange;           //页面是否切换public StickyScrollView(Context context) {super(context);this.mContext = context;}public StickyScrollView(Context context, AttributeSet attrs) {super(context, attrs);this.mContext = context;}public StickyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);this.mContext = context;}public void setOnPageChangeListener(OnPageChangeListener onPageChangeListener) {this.onPageChangeListener = onPageChangeListener;}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {super.onLayout(changed, l, t, r, b);mChildLayout = (ViewGroup) getChildAt(0);mTopChildView = mChildLayout.getChildAt(0);topChildHeight = mTopChildView.getMeasuredHeight();screenHeight = getMeasuredHeight();offsetDistance = topChildHeight - screenHeight;}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:isTouch = true;downY = (int) ev.getY();downTime = System.currentTimeMillis();if (mScroller != null) {mScroller.forceFinished(true);mScroller = null;}break;case MotionEvent.ACTION_MOVE:break;case MotionEvent.ACTION_UP:isTouch = false;upY = (int) ev.getY();upTime = System.currentTimeMillis();//用户手指在屏幕上的时间long duration = upTime - downTime;//这里要确保点击事件不失效if (Math.abs(upY - downY) > 50) {Log.e(TAG, ">>>ISN_T CLICK:" + Math.abs(upY - downY));if (currentPage == PAGE_TOP) {//下面的判断已经能确定用户是否往上滑if (getScrollY() > offsetDistance) {mScroller = new Scroller(mContext);if (getScrollY() < (screenHeight * PERCENT + offsetDistance) && duration > TOUCH_DURATION) {isPageChange = false;scrollToTarget(PAGE_TOP);} else {//切换到下界面isPageChange = true;isScrollAuto = duration < TOUCH_DURATION ? true : false;scrollToTarget(PAGE_BOTTOM);currentPage = PAGE_BOTTOM;}return false;}} else {if (getScrollY() < topChildHeight) {mScroller = new Scroller(mContext);if (getScrollY() < (topChildHeight - screenHeight * PERCENT) || duration < TOUCH_DURATION) {//切换到上界面isPageChange = true;isScrollAuto = duration < TOUCH_DURATION ? true : false;scrollToTarget(PAGE_TOP);currentPage = PAGE_TOP;} else {isPageChange = false;scrollToTarget(PAGE_BOTTOM);}return false;}}}break;}return super.dispatchTouchEvent(ev);}/*** 滚动到指定位置*/private void scrollToTarget(int currentPage) {int delta;if (currentPage == PAGE_TOP) {delta = getScrollY() - offsetDistance;mScroller.startScroll(0, getScrollY(), 0, -delta, isScrollAuto == true ? ANIMATION_DURATION : (int) (Math.abs(delta) * 0.4));} else if (currentPage == PAGE_BOTTOM) {delta = getScrollY() - topChildHeight;mScroller.startScroll(0, getScrollY(), 0, -delta, isScrollAuto == true ? ANIMATION_DURATION : (int) (Math.abs(delta) * 0.4));}postInvalidate();}@Overridepublic void computeScroll() {// 调用startScroll的时候scroller.computeScrollOffset()返回truesuper.computeScroll();if (mScroller == null) {return;}if (mScroller.computeScrollOffset()) {this.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());postInvalidate();if (mScroller.isFinished()) {mScroller = null;if (onPageChangeListener != null && isPageChange) onPageChangeListener.OnPageChange(currentPage);}}}@Overrideprotected void onScrollChanged(int l, int t, int oldl, int oldt) {super.onScrollChanged(l, t, oldl, oldt);//滚动时的监听,当用户触屏滑动时不监听,t == getScrollYif (currentPage == PAGE_TOP) {if (getScrollY() > offsetDistance && !isTouch) {if (mScroller == null) {//用于控制当滑动到分界线时停止滚动scrollTo(0, offsetDistance);} else {scrollToTarget(PAGE_TOP);}}} else if (currentPage == PAGE_BOTTOM) {if (getScrollY() < topChildHeight && !isTouch) {if (mScroller == null) {scrollTo(0, topChildHeight);} else {scrollToTarget(PAGE_BOTTOM);}}}}/*** 切换页面完成后的回调*/public interface OnPageChangeListener {void OnPageChange(int currentPage);}}

这是自定义的粘性StickyScrollview,主要逻辑都在这儿了。

来看如何使用:

<com.example.zsh.scrollview_demo.StickyScrollView xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/sticky_scroll"android:layout_width="match_parent"android:layout_height="match_parent"android:scrollbars="none"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><!-- child_0 --><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:orientation="vertical"><ImageViewandroid:id="@+id/item_1"android:clickable="true"android:layout_width="match_parent"android:layout_height="200dp"android:layout_marginTop="2dp"android:scaleType="centerCrop"android:src="@mipmap/ic_launcher" /><ImageViewandroid:id="@+id/item_2"android:clickable="true"android:layout_width="match_parent"android:layout_height="200dp"android:layout_marginTop="2dp"android:scaleType="centerCrop"android:background="@mipmap/ic_launcher" /><ImageViewandroid:id="@+id/item_3"android:clickable="true"android:layout_width="match_parent"android:layout_height="200dp"android:layout_marginTop="2dp"android:scaleType="centerCrop"android:background="@mipmap/ic_launcher" /><ImageViewandroid:id="@+id/item_4"android:clickable="true"android:layout_width="match_parent"android:layout_height="200dp"android:layout_marginTop="2dp"android:scaleType="centerCrop"android:background="@mipmap/ic_launcher" /><ImageViewandroid:id="@+id/item_5"android:clickable="true"android:layout_width="match_parent"android:layout_height="200dp"android:layout_marginTop="2dp"android:layout_marginBottom="2dp"android:scaleType="centerCrop"android:background="@mipmap/ic_launcher"  /></LinearLayout><!-- child_1 --><ScrollViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:scrollbars="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"><!-- divider --><TextViewandroid:layout_width="match_parent"android:layout_height="30dp"android:gravity="center"android:textColor="@android:color/white"android:textSize="16sp"android:text="Divider"android:background="#00AA50"/><ImageViewandroid:id="@+id/item_6"android:clickable="true"android:layout_width="match_parent"android:layout_height="200dp"android:layout_marginTop="2dp"android:scaleType="centerCrop"android:background="@color/colorAccent" /><ImageViewandroid:id="@+id/item_7"android:clickable="true"android:layout_width="match_parent"android:layout_height="200dp"android:layout_marginTop="2dp"android:scaleType="centerCrop"android:background="@color/colorAccent"/><ImageViewandroid:id="@+id/item_8"android:clickable="true"android:layout_width="match_parent"android:layout_height="200dp"android:layout_marginTop="2dp"android:scaleType="centerCrop"android:background="@color/colorAccent" /><ImageViewandroid:id="@+id/item_9"android:clickable="true"android:layout_width="match_parent"android:layout_height="200dp"android:layout_marginTop="2dp"android:scaleType="centerCrop"android:background="@color/colorAccent" /><ImageViewandroid:id="@+id/item_10"android:clickable="true"android:layout_width="match_parent"android:layout_height="200dp"android:layout_marginTop="2dp"android:scaleType="centerCrop"android:background="@color/colorAccent" /></LinearLayout></ScrollView></LinearLayout></com.example.zsh.scrollview_demo.StickyScrollView>

再来看MainActivity,

package com.example.zsh.scrollview_demo;import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;public class MainActivity extends AppCompatActivity implements View.OnClickListener, StickyScrollView.OnPageChangeListener {public static final String TAG = MainActivity.class.getSimpleName();private ImageView ImageItem1;private ImageView ImageItem2;private ImageView ImageItem3;private ImageView ImageItem4;private ImageView ImageItem5;private ImageView ImageItem6;private ImageView ImageItem7;private ImageView ImageItem8;private ImageView ImageItem9;private ImageView ImageItem10;private StickyScrollView stickyScrollView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);stickyScrollView = (StickyScrollView) findViewById(R.id.sticky_scroll);stickyScrollView.setOnPageChangeListener(this);ImageItem1 = (ImageView) findViewById(R.id.item_1);ImageItem2 = (ImageView) findViewById(R.id.item_2);ImageItem3 = (ImageView) findViewById(R.id.item_3);ImageItem4 = (ImageView) findViewById(R.id.item_4);ImageItem5 = (ImageView) findViewById(R.id.item_5);ImageItem6 = (ImageView) findViewById(R.id.item_6);ImageItem7 = (ImageView) findViewById(R.id.item_7);ImageItem8 = (ImageView) findViewById(R.id.item_8);ImageItem9 = (ImageView) findViewById(R.id.item_9);ImageItem10 = (ImageView) findViewById(R.id.item_10);ImageItem1.setOnClickListener(this);ImageItem2.setOnClickListener(this);ImageItem3.setOnClickListener(this);ImageItem4.setOnClickListener(this);ImageItem5.setOnClickListener(this);ImageItem6.setOnClickListener(this);ImageItem7.setOnClickListener(this);ImageItem8.setOnClickListener(this);ImageItem9.setOnClickListener(this);ImageItem10.setOnClickListener(this);}@Overridepublic void onClick(View v) {Log.e(TAG, ">>>onClick");switch (v.getId()) {case R.id.item_1:Log.e(TAG, ">>>item_1");Toast.makeText(this, "IMAGE_1", Toast.LENGTH_SHORT).show();break;case R.id.item_2:Log.e(TAG, ">>>item_2");Toast.makeText(this, "IMAGE_2", Toast.LENGTH_SHORT).show();break;case R.id.item_3:Log.e(TAG, ">>>item_3");Toast.makeText(this, "IMAGE_3", Toast.LENGTH_SHORT).show();break;case R.id.item_4:Log.e(TAG, ">>>item_4");Toast.makeText(this, "IMAGE_4", Toast.LENGTH_SHORT).show();break;case R.id.item_5:Log.e(TAG, ">>>item_5");Toast.makeText(this, "IMAGE_5", Toast.LENGTH_SHORT).show();break;case R.id.item_6:Log.e(TAG, ">>>item_6");Toast.makeText(this, "IMAGE_6", Toast.LENGTH_SHORT).show();break;case R.id.item_7:Log.e(TAG, ">>>item_7");Toast.makeText(this, "IMAGE_7", Toast.LENGTH_SHORT).show();break;case R.id.item_8:Log.e(TAG, ">>>item_8");Toast.makeText(this, "IMAGE_8", Toast.LENGTH_SHORT).show();break;case R.id.item_9:Log.e(TAG, ">>>item_9");Toast.makeText(this, "IMAGE_9", Toast.LENGTH_SHORT).show();break;case R.id.item_10:Log.e(TAG, ">>>item_10");Toast.makeText(this, "IMAGE_10", Toast.LENGTH_SHORT).show();break;}}@Overridepublic void OnPageChange(int currentPage) {Log.e(TAG, ">>>OnPageChange");switch (currentPage) {case StickyScrollView.PAGE_TOP:Toast.makeText(this, "CHANGE_TO_TOP", Toast.LENGTH_SHORT).show();break;case StickyScrollView.PAGE_BOTTOM:Toast.makeText(this, "CHANGE_TO_BOTTOM", Toast.LENGTH_SHORT).show();break;}}
}

好了,这样一个效果就做出来了。可能还会有小瑕疵,后续再慢慢调。欢迎大家使用,哈哈,我要去忙了。。

android 自定义Scrollview实现淘宝二层楼效果新版微信小程序下拉效果相关推荐

  1. 京东程序员回应“被猝死”;淘宝特价版已提交微信小程序;苹果 M1 单核性能勇超 Intel 11 代 i7|极客头条...

    「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧. 整理 | 丁恩华 出品 | CSDN(ID:CSDNnews ...

  2. 微信小程序下拉框插件_微信小程序自定义select下拉选项框组件的实现代码_清玖_前端开发者...

    知识点:组件,animation,获取当前点击元素的索引与内容 微信小程序中没有select下拉选项框,所以只有自定义.自定义的话,可以选择模板的方式,也可以选择组件的方式来创建. 这次我选择了组件, ...

  3. ios微信小程序下拉刷新怎么配_[wx]微信小程序自定义下拉刷新

    需求: 在小程序内存在列表等形式的页面内增加下拉刷新功能,提高用户体验感,加强界面操作与交互性: 实现方法: 1.小程序提供的下拉刷新(无法自定义刷新动画) 在页面设置内开启下拉(单独页面设置): { ...

  4. 微信小程序下拉框选项框组件—点击自定义输入,弹出输入框获取值实例

    功能说明 ① 选择自定义输入 ② 弹出输入框进行输入 ③ 输入完后自动selected ④ 再点击下拉框值还在,也还可以自定义输入 上代码 wxml代码 <view class="da ...

  5. 微信小程序下拉框之二维数组或对象

    js文件 Page({data:{//户型 这是一个本地的对象,然后绑定到页面上 pic_array: [{ id: 13, name: '1室1厅1卫' },{ id: 14, name: '1室2 ...

  6. 双十一淘宝查历史最低价流量主小程序源码

    [链接在文末] 双十一淘宝查历史最低价流量主小程序源码,这是一个商品历史价格查询的一个小工具. 用户输入淘宝京东天猫等等平台商品链接查询优惠卷和历史价格,这样在618.双十一等各大电商活动的时候了解商 ...

  7. android微信下拉出现小程序,仿新版微信的小程序下拉栏

    原标题:仿新版微信的小程序下拉栏 本项目会对金融交易软件中存在的各种View进行模仿绘制,提供详细的实现思路,收集整理相关算法.文档以及专业资料. https://github.com/scsfwgy ...

  8. android微信下拉出现小程序,Android 仿新版微信的小程序下拉栏

    Android 仿新版微信的小程序下拉栏 上周微信更新到了 6.6.1 版本,加入了微信小游戏.朋友圈都在玩跳一跳.而且现在微信把最近用过的小程序放到了首页顶部,轻轻下拉就可以快速访问了.可以看下效果 ...

  9. WordPress独立后台高端二开黑金壁纸微信小程序源码

    WordPress独立后台壁纸小程序是一款高端二开黑金壁纸微信小程序源码,拥有WP独立后台运行,可以自定义后台添加流量AD ID.这款源码,是修复版的,支持看AD后保存壁纸到本地. 内附安装教程. W ...

最新文章

  1. 认认真真推荐几个机器学习类的公众号
  2. Struts2的类型转换(下)
  3. Knockoutjs Component问题汇总
  4. 机器学习基石第三讲:types of learning
  5. 【渝粤教育】国家开放大学2019年春季 8042-22T养殖业基础 参考试题
  6. Truncated SVD for faster dection
  7. 面试官:Spring事务失效的场景有哪些?如何解决?
  8. ras私钥c#转java_RSA密钥,JAVA与.NET之间转换
  9. iOS开发网络篇—大文件的多线程断点下载
  10. 微信小程序教程笔记4
  11. C51系列单片最小机原理图及L298N接线图
  12. 中国能源互联网行业十四五前景规划与发展战略格局分析报告2022-2028年版
  13. linux系统usb口死机,在Linux上修复故障的USB设备或端口的5种方法 | MOS86
  14. java 夏令时jvm设置问题
  15. 微信html下拉刷新页面,微信公众号内的页面的下拉刷新,兼容手机端和PC端
  16. 若依框架不分离版本创建新模块(多模块版)
  17. Linux虚拟机添加新硬盘
  18. 政考网:公务员考试备考攻略!
  19. kubesphere多节点在线安装
  20. Get 和 Post 请求

热门文章

  1. ROS(indigo)使用Qt Creator Plug in即ros_qtc_plugin
  2. [C语言]-指针详解
  3. iOS用户隐私政策(中英文)
  4. 5G 移动性管理状态
  5. 知识图谱数据库将人类的思维路径转化为机器的路径思维
  6. 成绩单(1000米跑成绩)
  7. 2|电子技术|数字电子技术基础|雨课堂习题|考前回顾
  8. These critical programs are missing or too old: make compiler
  9. 3. 通用计算机 (计算机发明的逻辑与细节)
  10. 实证研究的步骤_环环相扣!牢记这些步骤,论文变轻松