Android學習之 Scroller的介紹與使用
阿新 • • 發佈:2019-02-19
類概述
Android裡
Scroller
類是為了實現View平滑滾動的一個Helper類。通常在自定義的View時使用,在View中定義一個私有成員mScroller = new Scroller(context)
。設定mScroller滾動的位置時,並不會導致View的滾動,通常是用mScroller*記錄/計算View滾動的位置*,再重寫View的computeScroll()
,呼叫View的scrollTo(int x,int y)
方法完成實際的滾動。主要方法介紹
使用介紹-小例項-自定義一個支援滑動刪除事件的控制元件[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]如需要轉載,請註明出處,謝謝!!