Skip to content

服务器托管,北京服务器托管,服务器租用-价格及机房咨询

Menu
  • 首页
  • 关于我们
  • 新闻资讯
  • 数据中心
  • 服务器托管
  • 服务器租用
  • 机房租用
  • 支持中心
  • 解决方案
  • 联系我们
Menu

向上拖动时,可以惯性滑动显示到下一页的控件DragLayout

Posted on 2023年5月6日 by hackdl

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

只支持两页!

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; // 手指松开是否加载下一页的notifier

	public 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());
	}

	@Override
	protected void onFinishInflate() {
		// 跟findviewbyId一样,初始化上下两个view
		frameView1 = getChildAt(0);
		frameView2 = getChildAt(1);
	}

	class YScrollDetector extends SimpleOnGestureListener {

		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2, float dx,
				float dy) {
			// 垂直滑动时dy>dx,才被认定是上下拖动
			return Math.abs(dy) > Math.abs(dx);
		}
	}

	@Override
	public void computeScroll() {
		if (mDragHelper.continueSettling(true)) {
			ViewCompat.postInvalidateOnAnimation(this);
		}
	}

	/**
	 * 这是拖拽效果的主要逻辑
	 */
	private class DragHelperCallback extends ViewDragHelper.Callback {

		@Override
		public 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);
		}

		@Override
		public boolean tryCaptureView(View child, int pointerId) {
			// 两个子View都需要跟踪,返回true
			return true;
		}

		@Override
		public int getViewVerticalDragRange(View child) {
			// 这个用来控制拖拽过程中松手后,自动滑行的速度,暂时给一个随意的数值
			return 1;
		}

		@Override
		public void onViewReleased(View releasedChild, float xvel, float yvel) {
			// 滑动松开后,需要向上或者乡下粘到特定的位置
			animTopOrBottom(releasedChild, yvel);
		}

		@Override
		public int clampViewPositionVertical(View child, int top, int dy) {
			int finalTop = top;
			if (child == frameView1) {
				// 拖动的时第一个view
				if (top > 0) {
					// 不让第一个view往下拖,因为顶部会白板
					finalTop = 0;
				}
			} else if (child == frameView2) {
				// 拖动的时第二个view
				if (top  VEL_THRESHOLD
					|| (downTop1 == -viewHeight && releasedChild.getTop() > DISTANCE_THRESHOLD)) {
				// 保持原地不动
				finalTop = viewHeight;
			}
		}

		if (mDragHelper.smoothSlideViewTo(releasedChild, 0, finalTop)) {
			ViewCompat.postInvalidateOnAnimation(this);
		}
	}

	/* touch事件的拦截与处理都交给mDraghelper来处理 */
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {

		if (frameView1.getBottom() > 0 && frameView1.getTop() 

用法:

private void initView() {
		fragment1 = new VerticalFragment1();
		fragment2 = new VerticalFragment2();
//		fragment3 = new VerticalFragment3();

		getSupportFragmentManager().beginTransaction()
				.add(R.id.first, fragment1)
				.add(R.id.second, fragment2)
//				.add(R.id.second, fragment3)//只支持两页
				.commit();

		ShowNextPageNotifier nextIntf = new ShowNextPageNotifier() {
			@Override
			public void onDragNext() {
//				fragment3.initView();
			}
		};
		draglayout = (DragLayout) findViewById(R.id.draglayout);
		draglayout.setNextPageListener(nextIntf);
	}

布局:



        

        
    

仿淘宝商品浏览界面, 向上拉查看详情

这是一个多功能的扩展GridView 可展开,可拖动,可排序,可删除。 固定更多按钮。 展开合并支持动画。 支持箭头图标移动。 数据的处理和显示使用Bean。 来自于500彩票Andorid客户端首页功能。

http://www.jcodecraeer.com/a/opensource/2015/0827/3376.html

自定义商品详情页

  • 大小: 1.1 MB
  • android-vertical-slide-view-master.zip (2.6 MB)
  • 下载次数: 11
  • 查看图片附件

服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.e1idc.net

Related posts:

  1. 北京idc牌照申请
  2. 企业托管服务器:安全稳定的数据管理方案
  3. OpenPie 和 ChatGPT 聊聊云上数据计算的那些事儿
  4. 高效稳定的服务器托管100m服务
  5. 沭河路云服务器托管:高效稳定的云计算服务

服务器托管,北京服务器托管,服务器租用,机房机柜带宽租用

服务器托管

咨询:董先生

电话13051898268 QQ/微信93663045!

上一篇: DragLayout测试代码(ViewDragHelper)
下一篇: 带有增加与减少按钮的数量选择控件QuantityView

最新更新

  • 五月学习之keepalived 软件简介
  • Cibersort免疫浸润的在线分析及R语言代码实现
  • 阿里云的认证最有几个等级?考试费用是多少?
  • 京东APP百亿级商品与车关系数据检索实践 | 京东云技术团队
  • 【Hello Network】TCP协议 TCP协议 确认应答机制 (ACK) 超时重传机制 连接管理机制 流量控制 滑动窗口 拥塞控制 延时应答 捎带应答 面向字节流 粘包问题 TCP的异常情况 TCP小结 基于TCP的应用层协议

随机推荐

  • 辽宁阜新服务器托管服务:高效、安全的解决方案
  • 武汉服务器托管商:专业、安全的数据管理服务
  • 万亿京东的担当
  • 天津无需备案的云服务器托管服务
  • idc机房托管需要租服务器吗

客服咨询

  • 董先生
  • 微信/QQ:93663045
  • 电话:13051898268
  • 邮箱:dongli@hhisp.com
  • 地址:北京市石景山区重聚园甲18号2层

友情链接

  • 服务器托管
  • 服务器租用
  • 机房租用托管
  • 服务器租用托管
©2023 服务器托管,北京服务器托管,服务器租用-价格及机房咨询 京ICP备13047091号-8