Android通过scroller实现缓慢移动
2015-11-29 10:16
447 查看
Android中实现view的移动有多种方式,
1.可以通过动画,但普通的动画实际上并没有真正改变View的位置,如果上面有Click事件,你会发现Click事件其实还在原来的位置。所以如果View没有交互,可以使用动画。2.可以通过layoutparams,此方法的弊端是操作稍微复杂一些,如果View有交互可以使用此方法。
我们这里讲解相对简单的可以通过scroller类来实现View的移动。
我们新建一个自定义view,它继承自LinearLayout。我们在初始化的时候创建一个Scroller对象。然后添加一个滑动的方法:
private void init(Context context) {
mScroller = new Scroller(context);
}
/**
* 缓慢滑动的方法
*
* @param destX 水平滑动的距离
* @param destY 竖起滑动的距离
*/
public void smoothScrollTo(int destX, int destY) {
int scrollX = getScrollX();
int delta = destX - scrollX;
mScroller.startScroll(scrollX, 0, delta, 0, 1000);
invalidate();
}
当调用startScroll的方法时,只是准备好了数据,并没有真正意义上滑动,我们还需要重写computeScroll方法。
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}
Scroller是如何让View实现弹性滑动的呢?答案就是startScroller方法下面的invalidate方法。调用这个方法会导致View重绘,在View的draw方法中又会去调用computeScroll方法。computeScroll又会去向Scroller获取当前的scrollX和scrollY,然后通过scrollTo方法实现滑动。接着又调用postInvalidate方法来进行第二次重绘,这一次重绘的过程和第一次重绘一样,还是会导致computeScroll方法被调用;然后继续向Scroller获取当前的scrollX和scrollY,并通过scrollTo方法滑动到新的位置,如此反复,直到整个滑动过程结束。
在xml中引用,通过点击button让layout滑动:
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<com.example.administrator.myapplication.ScrollLayout
android:id="@+id/scroll_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="80dp"
android:layout_height="50dp"
android:background="#F00"
android:gravity="center"
android:text="i will scroll"
android:textColor="#FFF" />
</com.example.administrator.myapplication.ScrollLayout>
<Button
android:id="@+id/click_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="click" />
</LinearLayout>
之后在Activity中调用:
private ScrollLayout scrollLayout;
private int i = -200;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scrollLayout = (ScrollLayout) findViewById(R.id.scroll_layout);
findViewById(R.id.click_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
scrollLayout.smoothScrollTo(i, 0);
//再次点击滑回原处
i = (i == 0) ? -200 : 0;
}
});
}
效果图:
![](http://img.blog.csdn.net/20151129143437158?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
demo地址
1.可以通过动画,但普通的动画实际上并没有真正改变View的位置,如果上面有Click事件,你会发现Click事件其实还在原来的位置。所以如果View没有交互,可以使用动画。2.可以通过layoutparams,此方法的弊端是操作稍微复杂一些,如果View有交互可以使用此方法。
我们这里讲解相对简单的可以通过scroller类来实现View的移动。
我们新建一个自定义view,它继承自LinearLayout。我们在初始化的时候创建一个Scroller对象。然后添加一个滑动的方法:
private void init(Context context) {
mScroller = new Scroller(context);
}
/**
* 缓慢滑动的方法
*
* @param destX 水平滑动的距离
* @param destY 竖起滑动的距离
*/
public void smoothScrollTo(int destX, int destY) {
int scrollX = getScrollX();
int delta = destX - scrollX;
mScroller.startScroll(scrollX, 0, delta, 0, 1000);
invalidate();
}
computeScroll
当调用startScroll的方法时,只是准备好了数据,并没有真正意义上滑动,我们还需要重写computeScroll方法。
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}
Scroller是如何让View实现弹性滑动的呢?答案就是startScroller方法下面的invalidate方法。调用这个方法会导致View重绘,在View的draw方法中又会去调用computeScroll方法。computeScroll又会去向Scroller获取当前的scrollX和scrollY,然后通过scrollTo方法实现滑动。接着又调用postInvalidate方法来进行第二次重绘,这一次重绘的过程和第一次重绘一样,还是会导致computeScroll方法被调用;然后继续向Scroller获取当前的scrollX和scrollY,并通过scrollTo方法滑动到新的位置,如此反复,直到整个滑动过程结束。
在xml中引用,通过点击button让layout滑动:
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<com.example.administrator.myapplication.ScrollLayout
android:id="@+id/scroll_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="80dp"
android:layout_height="50dp"
android:background="#F00"
android:gravity="center"
android:text="i will scroll"
android:textColor="#FFF" />
</com.example.administrator.myapplication.ScrollLayout>
<Button
android:id="@+id/click_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="click" />
</LinearLayout>
之后在Activity中调用:
private ScrollLayout scrollLayout;
private int i = -200;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scrollLayout = (ScrollLayout) findViewById(R.id.scroll_layout);
findViewById(R.id.click_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
scrollLayout.smoothScrollTo(i, 0);
//再次点击滑回原处
i = (i == 0) ? -200 : 0;
}
});
}
效果图:
demo地址
相关文章推荐
- Android-SQLite3_1-下载和安装SQLite
- android116 轮播 viewPager实现
- 优化Android studio的编译速度
- android 基础 之 Dialog
- Android 修改签名文件keystore文件密码
- 读《50 Android Hacks》笔记整理Hack 9~Hack 17
- Android通过session与服务端保持一致
- Android TextView
- Draw 9-patch(点9图)
- material design
- Android之集成友盟推送功能
- Android Studio——R文件小问题
- Android开发之动画(转)
- Android手机出现"已安装了存在签名冲突的同名数据包"的原因及解决办法
- Android:Style详解
- Android:drawable汇总
- Android RelativeLayout 学习
- GSON使用实践
- android 下拉刷新,上拉加载
- Android开发常用的工具类