Android學習之 Scroller的介紹與使用
類概述
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>
如果您對文章內容有任何疑問或有更好的見解, 歡迎通過留言或發郵件的方式聯絡我:
ice_zhengbin@163.com如需要轉載,請註明出處,謝謝!!
相關文章
- 深度學習之遷移學習介紹與使用深度學習遷移學習
- Android 動畫 介紹與使用Android動畫
- Android JetPack~ LiveData (一) 介紹與使用AndroidJetpackLiveData
- Android JetPack~ ViewModel (一) 介紹與使用AndroidJetpackView
- Android 常用佈局 介紹與使用Android
- Android RxJava:基礎介紹與使用AndroidRxJava
- Android之Zygote介紹AndroidGo
- 多工學習模型之ESMM介紹與實現模型
- 多工學習模型之DBMTL介紹與實現模型
- 1.Django介紹與學習Django
- Dubbo原始碼學習之-SPI介紹原始碼
- JQuery的介紹與使用jQuery
- Spring Cloud認知學習(一):Spring Cloud介紹與Eureka使用SpringCloud
- 機器學習入門之sklearn介紹機器學習
- Android系統介紹與框架Android框架
- Linux之cat的使用介紹Linux
- 表示學習介紹
- xtrabackup 2.4 的介紹與使用
- FastAPI 的路由介紹與使用ASTAPI路由
- item的介紹與使用-2.0
- GoogleTagManager 介紹與使用Go
- Influxdb 介紹與使用UX
- ClickHouse學習系列之七【系統命令介紹】
- Go 標準庫之 GoRequests 介紹與基本使用Go
- Go 效能壓測工具之wrk介紹與使用Go
- 深度學習與CV教程(8) | 常見深度學習框架介紹深度學習框架
- tensorflow學習率指數衰減ExponentialDecay的引數介紹與使用方法
- Android執行緒池使用介紹Android執行緒
- Android入門教程 | AsyncTask 使用介紹Android
- 學習內容介紹
- dapr學習:dapr介紹
- 學習python前言介紹Python
- 新媒體運營學習之私域流量的介紹
- JavaScript高階程式設計學習(一)之介紹JavaScript程式設計
- IIS Express介紹與使用Express
- java ShutdownHook介紹與使用JavaHook
- Go 常用標準庫之 fmt 介紹與基本使用Go
- Vue入門到關門之Vue介紹與使用Vue
- 最通俗的機器學習介紹機器學習