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

一.自定義View的設(shè)計(jì)代碼
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;
/**
* 實(shí)現(xiàn)了可以有下拉彈回的ScrollView的自定義View
*/
public class SpringScrollView extends ScrollView {
private View inner;// 孩子
private float y;// 坐標(biāo)
private Rect normal = new Rect();// 矩形空白
public SpringScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
/***
* 根據(jù) XML 生成視圖工作完成.該函數(shù)在生成視圖的最后調(diào)用,在所有子視圖添加完之后. 即使子類覆蓋了 onFinishInflate
* 方法,也應(yīng)該調(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();// 獲取點(diǎn)擊y坐標(biāo)
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);// 獲取滑動(dòng)距離
y = nowY;
// 當(dāng)滾動(dòng)到最上或者最下時(shí)就不會(huì)再滾動(dòng),這時(shí)移動(dòng)布局
if (isNeedMove()) {
if (normal.isEmpty()) {
// 填充矩形,目的:就是告訴this:我現(xiàn)在已經(jīng)有了,你松開的時(shí)候記得要執(zhí)行回歸動(dòng)畫.
normal.set(inner.getLeft(), inner.getTop(),
inner.getRight(), inner.getBottom());
}
// 移動(dòng)布局
inner.layout(inner.getLeft(), inner.getTop() - deltaY / 2,
inner.getRight(), inner.getBottom() - deltaY / 2);
}
break;
default:
break;
}
}
/***
* 開啟動(dòng)畫移動(dòng)
*/
public void animation() {
// 開啟移動(dòng)動(dòng)畫
TranslateAnimation ta = new TranslateAnimation(0, 0, inner.getTop(),
normal.top);
ta.setDuration(300);
inner.startAnimation(ta);
// 設(shè)置回到正常的布局位置
inner.layout(normal.left, normal.top, normal.right, normal.bottom);
normal.setEmpty();// 清空矩形
}
/***
* 是否需要開啟動(dòng)畫
* <p>
* 如果矩形不為空,返回true,否則返回false.
*
* @return
*/
public boolean isNeedAnimation() {
return !normal.isEmpty();
}
/***
* 是否需要移動(dòng)布局 inner.getMeasuredHeight():獲取的是控件的高度
* getHeight():獲取的是當(dāng)前控件在屏幕中顯示的高度
*
* @return
*/
public boolean isNeedMove() {
int offset = inner.getMeasuredHeight() - getHeight();
int scrollY = getScrollY();
// 0是頂部,后面那個(gè)是底部
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)用就可以了,邏輯操作的實(shí)現(xiàn)已經(jīng)在自定義的View中完成了, 對(duì)應(yīng)這些工具類,沒有必要很深入去理解,學(xué)會(huì)調(diào)用就可以了。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android XmlResourceParser出錯(cuò)解決辦法
這篇文章主要介紹了Android XmlResourceParser出錯(cuò)解決辦法的相關(guān)資料,需要的朋友可以參考下2017-05-05
Android 自定義SeekBar 實(shí)現(xiàn)分段顯示不同背景顏色的示例代碼
這篇文章主要介紹了Android 自定義SeekBar 實(shí)現(xiàn)分段顯示不同背景顏色,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06
Android筆記之:深入為從右向左語言定義復(fù)雜字串的詳解
本篇文章是對(duì)Android中為從右向左語言定義復(fù)雜字串進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
Android仿英語流利說取詞放大控件的實(shí)現(xiàn)方法(附demo源碼下載)
這篇文章主要介紹了Android仿英語流利說取詞放大控件的實(shí)現(xiàn)方法,較為詳細(xì)的分析了取詞放大控件的實(shí)現(xiàn)步驟與相關(guān)技巧,需要的朋友可以參考下2016-02-02
Android 實(shí)現(xiàn)控件懸浮效果實(shí)例代碼
本篇文章主要介紹了Android 實(shí)現(xiàn)控件懸浮效果實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-01-01
深入理解Android熱修復(fù)技術(shù)原理之代碼熱修復(fù)技術(shù)
在各種 Android 熱修復(fù)方案中,Andfix的即時(shí)生效令人印象深刻,它稍顯另類, 并不需要重新啟動(dòng),而是在加載補(bǔ)丁后直接對(duì)方法進(jìn)行替換就可以完成修復(fù),然而它的使用限制也遭遇到更多的質(zhì)疑2021-06-06

