Android ScrollView實現(xiàn)下拉彈回動畫效果
這里設計一個自定義View,繼承了ScrollView,實現(xiàn)可以下拉里面的內(nèi)容,松手后畫面彈回,這個自定義的View可以當做ScrollView來使用。
一般設計時的應用效果:

一.自定義View的設計代碼
package com.lwz.mathbox.weight;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.TranslateAnimation;
import android.widget.ScrollView;
/**
* 實現(xiàn)了可以有下拉彈回的ScrollView的自定義View
*/
public class SpringScrollView extends ScrollView {
private View inner;// 孩子
private float y;// 坐標
private Rect normal = new Rect();// 矩形空白
public SpringScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
/***
* 根據(jù) XML 生成視圖工作完成.該函數(shù)在生成視圖的最后調(diào)用,在所有子視圖添加完之后. 即使子類覆蓋了 onFinishInflate
* 方法,也應該調(diào)用父類的方法,使該方法得以執(zhí)行.
*/
@Override
protected void onFinishInflate() {
if (getChildCount() > 0) {
inner = getChildAt(0);// 獲取其孩子
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (inner != null) {
commOnTouchEvent(ev);
}
return super.onTouchEvent(ev);
}
/***
* 觸摸事件
*
* @param ev
*/
public void commOnTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
y = ev.getY();// 獲取點擊y坐標
break;
case MotionEvent.ACTION_UP:
if (isNeedAnimation()) {
animation();
}
break;
case MotionEvent.ACTION_MOVE:
final float preY = y;
float nowY = ev.getY();
int deltaY = (int) (preY - nowY);// 獲取滑動距離
y = nowY;
// 當滾動到最上或者最下時就不會再滾動,這時移動布局
if (isNeedMove()) {
if (normal.isEmpty()) {
// 填充矩形,目的:就是告訴this:我現(xiàn)在已經(jīng)有了,你松開的時候記得要執(zhí)行回歸動畫.
normal.set(inner.getLeft(), inner.getTop(),
inner.getRight(), inner.getBottom());
}
// 移動布局
inner.layout(inner.getLeft(), inner.getTop() - deltaY / 2,
inner.getRight(), inner.getBottom() - deltaY / 2);
}
break;
default:
break;
}
}
/***
* 開啟動畫移動
*/
public void animation() {
// 開啟移動動畫
TranslateAnimation ta = new TranslateAnimation(0, 0, inner.getTop(),
normal.top);
ta.setDuration(300);
inner.startAnimation(ta);
// 設置回到正常的布局位置
inner.layout(normal.left, normal.top, normal.right, normal.bottom);
normal.setEmpty();// 清空矩形
}
/***
* 是否需要開啟動畫
* <p>
* 如果矩形不為空,返回true,否則返回false.
*
* @return
*/
public boolean isNeedAnimation() {
return !normal.isEmpty();
}
/***
* 是否需要移動布局 inner.getMeasuredHeight():獲取的是控件的高度
* getHeight():獲取的是當前控件在屏幕中顯示的高度
*
* @return
*/
public boolean isNeedMove() {
int offset = inner.getMeasuredHeight() - getHeight();
int scrollY = getScrollY();
// 0是頂部,后面那個是底部
if (scrollY == 0 || scrollY == offset) {
return true;
}
return false;
}
}
二.簡單調(diào)用示例
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
//包名+類型
<com.lwz.mathbox.weight.SpringScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:orientation="vertical">
<EditText
android:id="@+id/et_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:gravity="top"
android:hint="輸入文字"
android:minLines="4"
android:singleLine="false"
android:textSize="14sp" />
<TextView
android:id="@+id/tv_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:gravity="right"
android:text="0/255" />
</LinearLayout>
</com.lwz.mathbox.weight.SpringScrollView>
</LinearLayout>
調(diào)用的話只需要在xml中調(diào)用就可以了,邏輯操作的實現(xiàn)已經(jīng)在自定義的View中完成了, 對應這些工具類,沒有必要很深入去理解,學會調(diào)用就可以了。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android XmlResourceParser出錯解決辦法
這篇文章主要介紹了Android XmlResourceParser出錯解決辦法的相關資料,需要的朋友可以參考下2017-05-05
Android 自定義SeekBar 實現(xiàn)分段顯示不同背景顏色的示例代碼
這篇文章主要介紹了Android 自定義SeekBar 實現(xiàn)分段顯示不同背景顏色,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06
Android仿英語流利說取詞放大控件的實現(xiàn)方法(附demo源碼下載)
這篇文章主要介紹了Android仿英語流利說取詞放大控件的實現(xiàn)方法,較為詳細的分析了取詞放大控件的實現(xiàn)步驟與相關技巧,需要的朋友可以參考下2016-02-02

