类概述
Android里
Scroller
类是为了实现View平滑滚动的一个Helper类。通常在自定义的View时使用,在View中定义一个私有成员mScroller = new Scroller(context)
。设置mScroller滚动的位置时,并不会导致View的滚动,通常是用mScroller*记录/计算View滚动的位置*,再重写View的computeScroll()
,调用View的scrollTo(int x,int y)
方法完成实际的滚动。主要方法介绍
更多关于Scroller类API详细介绍可前往
http://api.apkbus.com/reference/android/widget/Scroller.html
使用介绍-小实例-自定义一个支持滑动删除事件的控件[SlideView]
首先看一下实例的效果演示:
下面是实现代码
- 自定义控件布局文件:slide_view.xml
<?xml version="1.0" encoding="utf-8"?><merge xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/view_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> </LinearLayout> <LinearLayout android:id="@+id/holder" android:layout_width="80dp" android:layout_height="wrap_content" android:clickable="true" android:orientation="horizontal" android:background="@android:color/darker_gray"> <TextView android:id="@+id/delete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="20dp" android:layout_centerInParent="true" android:gravity="center" android:textColor="@android:color/white" android:text="detele"/> </LinearLayout></merge>
- 自定义控件实现类:SlideView.java [内含Scroller的使用介绍]
import android.content.Context;import android.util.AttributeSet;import android.view.Gravity;import android.view.MotionEvent;import android.view.View;import android.widget.LinearLayout;import android.widget.Scroller;import android.widget.TextView;/** * Created by ice on 15/5/4. */public class SlideView extends LinearLayout{ private Context mContext; private LinearLayout mViewContent; private LinearLayout mHolder; private TextView tv_delete; // 弹性滑动对象,实现View平滑滚动的一个帮助类 private Scroller mScroller; // 滑动回调接口,用来向上层通知滑动事件 private OnSlideListener mOnSlideListener; private int mHolderWidth = 100; private int mLastX = 0; private int mLastY = 0; private static final int TAN = 2; public SlideView(Context context) { super(context); initView(); } public SlideView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } private void initView(){ mContext = getContext(); mScroller = new Scroller(mContext); setOrientation(LinearLayout.HORIZONTAL); setGravity(Gravity.CENTER_VERTICAL); View.inflate(mContext, R.layout.slide_view, this); mViewContent = (LinearLayout)findViewById(R.id.view_content); mHolder = (LinearLayout)findViewById(R.id.holder); tv_delete = (TextView)findViewById(R.id.delete); } public void setButtonText(CharSequence text){ tv_delete.setText(text); } public void setContentView(View view){ mViewContent.addView(view); } public void onRequireTouchEvent(MotionEvent event){ int x = (int)event.getX(); int y = (int)event.getY(); int scrollX = getScrollX(); switch (event.getAction()){ case MotionEvent.ACTION_DOWN: if(!mScroller.isFinished()){ mScroller.abortAnimation(); } if(mOnSlideListener != null){ mOnSlideListener.onSlide(this, OnSlideListener.SLIDE_STATUS_START_SCROLL); } break; case MotionEvent.ACTION_MOVE: int deltaX = x - mLastX; int deltaY = y - mLastY; if(Math.abs(deltaX) < Math.abs(deltaY)*TAN){ // 滑动不满足条件 不做横向滑动 break; } int newScrollX = scrollX - deltaX; if(deltaX != 0){ if(newScrollX < 0){ newScrollX = 0; }else if(newScrollX > mHolderWidth){ newScrollX = mHolderWidth; } this.scrollTo(newScrollX, 0); } break; case MotionEvent.ACTION_UP: int newScrollx = 0; if(scrollX - mHolderWidth*0.75 > 0){ newScrollx = mHolderWidth; } this.smoothScrollTo(newScrollx, 0); // 通知上层滑动事件 if(mOnSlideListener != null){ mOnSlideListener.onSlide(this, newScrollx == 0 ? OnSlideListener.SLIDE_STATUS_OFF : OnSlideListener.SLIDE_STATUS_ON); } break; default: break; } mLastX = x; mLastY = y; } /** * 调用此方法滚动到目标位置 * @param fx 目标x坐标 * @param fy 目标Y坐标 */ private void smoothScrollTo(int fx, int fy){ int scrollX = getScrollX(); int dx = fx - scrollX; int scrollY = getScrollY(); int dy = fy - scrollY; //设置mScroller的滚动偏移量 mScroller.startScroll(scrollX, scrollY, dx, dy, Math.abs((dx)*3)); invalidate(); } /** * 由mScroller记录/计算好View滚动的位置后,最后由View的computeScroll(),完成实际的滚动 */ @Override public void computeScroll() { //先判断mScroller滚动是否完成 if(mScroller.computeScrollOffset()){ //这里调用View的scrollTo()完成实际的滚动 scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); //必须调用该方法,否则不一定能看到滚动效果 postInvalidate(); } super.computeScroll(); } /** * 设置滑动回调 * @param onSlideListener */ public void setOnSlideListener(OnSlideListener onSlideListener){ this.mOnSlideListener = onSlideListener; } public interface OnSlideListener { public static final int SLIDE_STATUS_OFF = 0; public static final int SLIDE_STATUS_START_SCROLL = 1; public static final int SLIDE_STATUS_ON = 2; public void onSlide(View view, int status); }}
- Activity布局文件:activity_main.xml
<RelativeLayout 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:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <TextView android:id="@+id/tv_content" android:text="向左滑动控件删除" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <demo.ice.com.helloapple.SlideView android:id="@+id/sv_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/tv_content" > </demo.ice.com.helloapple.SlideView></RelativeLayout>
- Activity类:MainActivity.java
import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.view.MotionEvent;import android.view.View;import android.widget.LinearLayout;import android.widget.Toast;public class MainActivity extends ActionBarActivity implements SlideView.OnSlideListener, View.OnClickListener{ private SlideView slideView; private LinearLayout slide_delete; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); slideView = (SlideView)findViewById(R.id.sv_view); View slideContentView = View.inflate(MainActivity.this, R.layout.slide_list_item, null); slideView.setContentView(slideContentView); slideView.setButtonText("删除"); slide_delete = (LinearLayout)findViewById(R.id.holder); slideView.setOnSlideListener(this); slide_delete.setOnClickListener(this); } @Override public boolean onTouchEvent(MotionEvent event) { // 将事件交由slideView自身处理 slideView.onRequireTouchEvent(event); return super.onTouchEvent(event); } @Override public void onClick(View view) { if(view.getId() == R.id.holder){ Toast.makeText(MainActivity.this, "你点击了删除按钮", Toast.LENGTH_LONG).show(); } } @Override public void onSlide(View view, int status) { }}
- 填充自定义控件内容布局文件:slide_list_item.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@android:drawable/ic_menu_camera"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="13岁iOS开发者:Swift开发Sprite Kit游戏实践"/></LinearLayout>
如果您对文章内容有任何疑问或有更好的见解, 欢迎通过留言或发邮件的方式联系我:
[email protected]如需要转载,请注明出处,谢谢!!