android rebound平移,Android 仿 IOS 拖拽回弹之进阶 ReboundFrameLayout

本文介绍了如何在Android中实现仿iOS的拖拽回弹效果,通过自定义ReboundFrameLayout控件,提供类似于iOS的弹性滚动体验。文章详细解析了关键代码实现,包括Scroller的使用和滑动逻辑处理,帮助开发者实现更流畅的滚动交互。
摘要由CSDN通过智能技术生成

Android 仿 IOS 拖拽回弹之进阶 ReboundFrameLayout

前言

IOS 拖拽回弹给用户的体验不得不赞然后 Android 原生的 API 各种不支持, 于是乎出现的很多仿 IOS 拖拽回弹的 Android 控件 ReboundScrollView, 比起原生的 ScrollView, 体验上好了很多, 但是还是不尽人意: RebounScrollView 里的内容超出屏幕时, 你想一次性在显示完 ScrollView 里的内容紧跟着拽出屏幕, 你发现你做不到, 臣妾也做不到! 于是乎, 我想我是不是可以试试? 下面分享一个让你也可以有 IOS 拖拽回弹般体验的 ReboundFrameLayout 既然 Android 原生的 ScrollView 做不到, 那我干脆舍弃不用, 我们自己做类似 ScrollView 的滑动, 这样方便我们在滑动到顶部 (或底部) 时可以继续向下(或向上滑动)

这里链接两个大神写的拖拽回弹控件:

1ReboundScrollView 仿 IOS 拖拽回弹

2 Android 上实现仿 IOS 弹性 ScrollView

我的思路

ab7653affab982b574eb7acc55df2e04.gif

思路图

效果展示

ab7653affab982b574eb7acc55df2e04.gifReboundFramLayout

实现

利用 Scroller 方式实现滚动

代码实现比较简单, 且有详细的注释ReboundFrameLayout.java

packagejsc.kit.org.rebound;

importandroid.content.Context;

importandroid.graphics.Rect;

importandroid.util.AttributeSet;

importandroid.view.MotionEvent;

importandroid.view.View;

importandroid.view.ViewConfiguration;

importandroid.widget.FrameLayout;

importandroid.widget.Scroller;

/**

* 布局上下反弹

*

* @author jsc

*/

publicclassReboundFrameLayoutextendsFrameLayout{

privatefinalStringTAG=getClass().getSimpleName();

privatefinalfloatRATIO=0.65f;

privatefinalintANIM_TIME=300;

privateViewmChildView;

privatefloatmCurY;

privatefloatmLastY;

privateScrollermScroller;

privateintmTouchSlop;

publicReboundFrameLayout(Contextcontext,AttributeSetattrs){

super(context,attrs);

mScroller=newScroller(context);

mTouchSlop=ViewConfiguration.get(context).getScaledPagingTouchSlop();

}

@Override

protectedvoidonFinishInflate(){

super.onFinishInflate();

mChildView=getChildAt(0);

}

@Override

publicbooleanonInterceptTouchEvent(MotionEventev){

switch(ev.getAction()){

caseMotionEvent.ACTION_DOWN:

mCurY=ev.getY();

mLastY=mCurY;

caseMotionEvent.ACTION_MOVE:

floatmCurY=ev.getY();

intmark=(int)(mCurY-mLastY);

intslop=Math.abs(mark);

mLastY=mCurY;

// 当滑动的距离小于 10px 的时候, 我们认为这次滑动是无效的, 销毁这次事件

if(slop>=10){

returntrue;

}

break;

caseMotionEvent.ACTION_UP:

break;

}

returnsuper.onInterceptTouchEvent(ev);

}

@Override

publicbooleanonTouchEvent(MotionEventev){

switch(ev.getAction()){

caseMotionEvent.ACTION_DOWN:

floatmCurY=ev.getY();

mLastY=mCurY;

caseMotionEvent.ACTION_MOVE:

mCurY=ev.getY();

intmYOffset=(int)((mCurY-mLastY)*RATIO);

scroll(mChildView,mYOffset);

mLastY=mCurY;

returntrue;

caseMotionEvent.ACTION_UP:

if(!mScroller.isFinished()){

mScroller.forceFinished(true);

}

mScroller.startScroll(0,getScrollY(),0,-getScrollY(),ANIM_TIME);

invalidate();

default:

break;

}

returntrue;

}

@Override

publicvoidcomputeScroll(){

if(mScroller.computeScrollOffset()){

scrollTo(mScroller.getCurrX(),mScroller.getCurrY());

postInvalidate();

}

}

privatevoidscroll(ViewmChildView,intmYOffset){

//child 内容下滑高度

intchildScrolledY=mChildView.getScrollY();

//child 在其 parent 中的可见部分

Rectrect=newRect();

mChildView.getLocalVisibleRect(rect);

//child 实际内容高度

mChildView.measure(0,0);

intrealHeight=mChildView.getMeasuredHeight();

//child 内容滑动到其 parent 底部时需要向上滑动的距离

intdistanceFromBottom=realHeight-rect.bottom;

if(mYOffset>0){// 向下滑动

// 如果向下滑动的距离小于 child 内容上滑到其 parent 顶部的距离, 则向下滑动 child 内容 mYOffset 距离

if(mYOffset

mChildView.scrollBy(0,-mYOffset);

}else{// 如果滑动的距离大于或等于 child 内容已经下滑的高度, 则向下滑动 child 的内容至其 parent 的顶部, 再向下滑动超出部分的距离

mChildView.scrollBy(0,-childScrolledY);

scrollBy(0,-(mYOffset-childScrolledY));

}

}elseif(mYOffset<0){// 向上滑动

intdistance=Math.abs(mYOffset);

// 如果向上滑动的距离小于 child 内容下滑到其 parent 底部的距离, 则向上滑动 child 内容 distance 距离

if(distance

mChildView.scrollBy(0,distance);

}else{

mChildView.scrollBy(0,distanceFromBottom);

scrollBy(0,distance-distanceFromBottom);

}

}

}

}

关键在于方法

scroll(View mChildView, int mYOffset)

里面的处理注释很详细, 请自行参阅

最后附上源码的下载地址: https://github.com/JustinRoom/JscKit/tree/master/rebound

来源: http://www.jianshu.com/p/53d13719a6c4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了实现这个系统,我们需要先收集一些数据,如钢筋弯曲角和回弹角的测量值。然后,我们可以使用机器学习算法来训练模型,以预测回弹角度。在这里,我们将使用 PyQt5 库来构建用户界面并集成机器学习模型。 首先,我们需要安装 PyQt5 和 Scikit-learn 库,可以在命令行中使用以下命令进行安装: ```python pip install PyQt5 scikit-learn ``` 接下来,我们将创建一个名为 "BendRebound.py" 的Python脚本来编写代码。 ```python import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import Qt from sklearn.linear_model import LinearRegression class BendRebound(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.setWindowTitle('Bend and Rebound Prediction') self.setGeometry(100, 100, 400, 200) bend_label = QLabel('Bend Angle:', self) bend_label.move(20, 20) self.bend_edit = QLineEdit(self) self.bend_edit.move(130, 20) rebound_label = QLabel('Rebound Angle:', self) rebound_label.move(20, 60) self.rebound_edit = QLineEdit(self) self.rebound_edit.move(130, 60) self.rebound_edit.setReadOnly(True) predict_button = QPushButton('Predict', self) predict_button.move(150, 100) predict_button.clicked.connect(self.predict) self.show() def predict(self): bend_angle = float(self.bend_edit.text()) model = LinearRegression() model.fit([[10], [20], [30], [40], [50]], [1.2, 2.4, 3.6, 4.8, 6.0]) # 训练数据 rebound_angle = model.predict([[bend_angle]])[0] self.rebound_edit.setText(str(round(rebound_angle, 2))) if __name__ == '__main__': app = QApplication(sys.argv) ex = BendRebound() sys.exit(app.exec_()) ``` 在这个代码中,我们创建了一个名为 "BendRebound" 的类,继承自QWidget。在initUI()方法中,我们创建了两个标签和两个文本框,用于输入弯曲角和显示预测的回弹角。我们还创建了一个“预测”按钮,并将其与predict()方法连接。 在predict()方法中,我们首先从文本框中获取弯曲角度。然后,我们使用Scikit-learn库中的LinearRegression模型来训练模型,并使用新的弯曲角度进行预测。最后,我们将预测的回弹角显示在回弹角文本框中。 注意,在这个例子中,我们使用了一个非常简单的数据集来训练模型。在实际应用中,你需要收集更多的数据,并使用更复杂的模型来预测回弹角。 接下来,我们可以在命令行中运行脚本: ```python python BendRebound.py ``` 这将打开一个名为 "Bend and Rebound Prediction" 的窗口,其中包含输入框和预测按钮。输入弯曲角度并点击预测按钮,预测结果将显示在回弹角文本框中。 这就是使用Python和PyQt5构建钢筋弯曲回弹角预测系统的简单示例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值