彈性ScrollView,和下啦刷新的效果類似 實現下拉彈回和上拉彈回


今天做了一個彈性ScrollView,和下啦刷新的效果類似,我想這個很多需求都用的這種效果

其實這是一個自定義的scrollView,上代碼,這是我寫在一個公共的組件包里的

package com.pb.soft.widget;

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;

/**

 * 有彈性的ScrollView 實現下拉彈回和上拉彈回

 * 

 * @author shaozuhceng

 */

public class UserDefineScrollView extends ScrollView {

private static final String TAG = "UserDefineScrollView ";

// 移動因子, 是一個百分比, 比如手指移動了100px, 那么View就只移動50px

// 目的是達到一個延遲的效果

private static final float MOVE_FACTOR = 0.5f;

// 松開手指后, 界面回到正常位置需要的動畫時間

private static final int ANIM_TIME = 300;

// ScrollView的子View, 也是ScrollView的唯一一個子View

private View contentView;

// 手指按下時的Y值, 用於在移動時計算移動距離

// 如果按下時不能上拉和下拉, 會在手指移動時更新為當前手指的Y值

private float startY;

// 用於記錄正常的布局位置

private Rect originalRect = new Rect();

// 手指按下時記錄是否可以繼續下拉

private boolean canPullDown = false;

// 手指按下時記錄是否可以繼續上拉

private boolean canPullUp = false;

// 在手指滑動的過程中記錄是否移動了布局

private boolean isMoved = false;

public UserDefineScrollView(Context context) {

super(context);

}

public UserDefineScrollView(Context context, AttributeSet attrs) {

super(context, attrs);

}

@Override

protected void onFinishInflate() {

if (getChildCount() > 0) {

contentView = getChildAt(0);

}

}

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

super.onLayout(changed, l, t, r, b);

if (contentView == null)

return;

// ScrollView中的唯一子控件的位置信息, 這個位置信息在整個控件的生命周期中保持不變

originalRect.set(contentView.getLeft(), contentView.getTop(), contentView.getRight(), contentView.getBottom());

}

/**

* 在觸摸事件中, 處理上拉和下拉的邏輯

*/

@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

if (contentView == null) {

return super.dispatchTouchEvent(ev);

}

// 手指是否移動到了當前ScrollView控件之外

boolean isTouchOutOfScrollView = ev.getY() >= this.getHeight() || ev.getY() <= 0;

if (isTouchOutOfScrollView) { // 如果移動到了當前ScrollView控件之外

if (isMoved) // 如果當前contentView已經被移動, 首先把布局移到原位置, 然后消費點這個事件

boundBack();

return true;

}

int action = ev.getAction();

switch (action) {

case MotionEvent.ACTION_DOWN:

// 判斷是否可以上拉和下拉

canPullDown = isCanPullDown();

canPullUp = isCanPullUp();

// 記錄按下時的Y值

startY = ev.getY();

break;

case MotionEvent.ACTION_UP:

boundBack();

break;

case MotionEvent.ACTION_MOVE:

// 在移動的過程中, 既沒有滾動到可以上拉的程度, 也沒有滾動到可以下拉的程度

if (!canPullDown && !canPullUp) {

startY = ev.getY();

canPullDown = isCanPullDown();

canPullUp = isCanPullUp();

break;

}

// 計算手指移動的距離

float nowY = ev.getY();

int deltaY = (int) (nowY - startY);

// 是否應該移動布局

boolean shouldMove = (canPullDown && deltaY > 0) // 可以下拉, 並且手指向下移動

|| (canPullUp && deltaY < 0) // 可以上拉, 並且手指向上移動

|| (canPullUp && canPullDown); // 既可以上拉也可以下拉(這種情況出現在ScrollView包裹的控件比ScrollView還小)

if (shouldMove) {

// 計算偏移量

int offset = (int) (deltaY * MOVE_FACTOR);

// 隨着手指的移動而移動布局

contentView.layout(originalRect.left, originalRect.top + offset, originalRect.right, originalRect.bottom + offset);

isMoved = true; // 記錄移動了布局

}

break;

default:

break;

}

return super.dispatchTouchEvent(ev);

}

/**

* 將內容布局移動到原位置 可以在UP事件中調用, 也可以在其他需要的地方調用, 如手指移動到當前ScrollView外時

*/

private void boundBack() {

if (!isMoved)

return; // 如果沒有移動布局, 則跳過執行

// 開啟動畫

TranslateAnimation anim = new TranslateAnimation(0, 0, contentView.getTop(), originalRect.top);

anim.setDuration(ANIM_TIME);

contentView.startAnimation(anim);

// 設置回到正常的布局位置

contentView.layout(originalRect.left, originalRect.top, originalRect.right, originalRect.bottom);

// 將標志位設回false

canPullDown = false;

canPullUp = false;

isMoved = false;

}

/**

* 判斷是否滾動到頂部

*/

private boolean isCanPullDown() {

return getScrollY() == 0 || contentView.getHeight() < getHeight() + getScrollY();

}

/**

* 判斷是否滾動到底部

*/

private boolean isCanPullUp() {

return contentView.getHeight() <= getHeight() + getScrollY();

}

}

然后就是你在布局文件中引用你的自定義scrollView,需要注意的是,使用自定義的scrollView需要帶上你的全部包名

<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"

    tools:context=".MainActivity" >

<!-注意這里的使用全部的包名-->

    <com.pb.soft.widget.UserDefineScrollView

        android:id="@+id/set_scrollview"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:fadingEdge="none"

        android:focusable="false"

        android:overScrollMode="never"

        android:scrollbars="none" >

        <LinearLayout

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:layout_marginLeft="10dp"

            android:layout_marginRight="10dp"

            android:layout_marginTop="10dp"

            android:background="@drawable/bg_input_background"

            android:orientation="vertical" >

            <RelativeLayout

                android:id="@+id/relativelayout_01"

                android:layout_width="match_parent"

                android:layout_height="wrap_content" >

                <TextView

                    android:id="@+id/personinfo_head_name"

                    android:layout_width="wrap_content"

                    android:layout_height="50dp"

                    android:layout_marginLeft="15dp"

                    android:ellipsize="end"

                    android:gravity="center_vertical"

                    android:includeFontPadding="false"

                    android:singleLine="true"

                    android:text="單元測試1"

                    android:textSize="16sp" />

                <ImageView

                    android:id="@+id/rel_set_personinfromation_arrow"

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:layout_alignParentRight="true"

                    android:layout_centerVertical="true"

                    android:layout_marginRight="10dp"

                    android:contentDescription="@null"

                    android:src="@drawable/ic_set_arrow" />

            </RelativeLayout>

            <ImageView

                android:id="@+id/line0"

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:background="@drawable/list_divide_line"

                android:contentDescription="@null" />

            <RelativeLayout

                android:id="@+id/relativelayout_02"

                android:layout_width="match_parent"

                android:layout_height="wrap_content" >

                <TextView

                    android:id="@+id/textview01"

                    android:layout_width="wrap_content"

                    android:layout_height="50dp"

                    android:layout_marginLeft="15dp"

                    android:ellipsize="end"

                    android:gravity="center_vertical"

                    android:includeFontPadding="false"

                    android:singleLine="true"

                    android:text="單元測試2"

                    android:textSize="16sp" />

                <ImageView

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:layout_alignParentRight="true"

                    android:layout_centerVertical="true"

                    android:layout_marginRight="10dp"

                    android:contentDescription="@null"

                    android:src="@drawable/ic_set_arrow" />

            </RelativeLayout>

            <ImageView

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:background="@drawable/list_divide_line"

                android:contentDescription="@null" />

            <RelativeLayout

                android:layout_width="match_parent"

                android:layout_height="wrap_content" >

                <TextView

                    android:id="@+id/textview02"

                    android:layout_width="wrap_content"

                    android:layout_height="50dp"

                    android:layout_marginLeft="15dp"

                    android:ellipsize="end"

                    android:gravity="center_vertical"

                    android:includeFontPadding="false"

                    android:singleLine="true"

                    android:text="單元測試3"

                    android:textSize="16sp" />

                <ImageView

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:layout_alignParentRight="true"

                    android:layout_centerVertical="true"

                    android:layout_marginRight="10dp"

                    android:contentDescription="@null"

                    android:src="@drawable/ic_set_arrow" />

            </RelativeLayout>

            <ImageView

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:background="@drawable/list_divide_line"

                android:contentDescription="@null" />

            <RelativeLayout

                android:layout_width="match_parent"

                android:layout_height="wrap_content" >

                <TextView

                    android:layout_width="wrap_content"

                    android:layout_height="50dp"

                    android:layout_marginLeft="15dp"

                    android:ellipsize="end"

                    android:gravity="center_vertical"

                    android:includeFontPadding="false"

                    android:singleLine="true"

                    android:text="單元測試4"

                    android:textSize="16sp" />

                <ImageView

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:layout_alignParentRight="true"

                    android:layout_centerVertical="true"

                    android:layout_marginRight="10dp"

                    android:contentDescription="@null"

                    android:src="@drawable/ic_set_arrow" />

            </RelativeLayout>

            <ImageView

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:background="@drawable/list_divide_line"

                android:contentDescription="@null" />

            <RelativeLayout

                android:layout_width="match_parent"

                android:layout_height="50dp" >

                <TextView

                    android:layout_width="wrap_content"

                    android:layout_height="40dp"

                    android:layout_marginLeft="15dp"

                    android:ellipsize="end"

                    android:gravity="center_vertical"

                    android:includeFontPadding="false"

                    android:singleLine="true"

                    android:text="單元測試5"

                    android:textSize="16sp" />

                <ImageView

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:layout_alignParentRight="true"

                    android:layout_centerVertical="true"

                    android:layout_marginRight="10dp"

                    android:contentDescription="@null"

                    android:src="@drawable/ic_set_arrow" />

            </RelativeLayout>

            <ImageView

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:background="@drawable/list_divide_line"

                android:contentDescription="@null" />

            <RelativeLayout

                android:layout_width="match_parent"

                android:layout_height="50dp" >

                <TextView

                    android:layout_width="wrap_content"

                    android:layout_height="40dp"

                    android:layout_marginLeft="15dp"

                    android:ellipsize="end"

                    android:gravity="center_vertical"

                    android:includeFontPadding="false"

                    android:singleLine="true"

                    android:text="單元測試6"

                    android:textSize="16sp" />

                <ImageView

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:layout_alignParentRight="true"

                    android:layout_centerVertical="true"

                    android:layout_marginRight="10dp"

                    android:contentDescription="@null"

                    android:src="@drawable/ic_set_arrow" />

            </RelativeLayout>

            <ImageView

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:background="@drawable/list_divide_line"

                android:contentDescription="@null" />

            <RelativeLayout

                android:layout_width="match_parent"

                android:layout_height="50dp" >

                <TextView

                    android:layout_width="wrap_content"

                    android:layout_height="40dp"

                    android:layout_marginLeft="15dp"

                    android:ellipsize="end"

                    android:gravity="center_vertical"

                    android:includeFontPadding="false"

                    android:singleLine="true"

                    android:text="單元測試7"

                    android:textSize="16sp" />

                <ImageView

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:layout_alignParentRight="true"

                    android:layout_centerVertical="true"

                    android:layout_marginRight="10dp"

                    android:contentDescription="@null"

                    android:src="@drawable/ic_set_arrow" />

            </RelativeLayout>

            <ImageView

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:background="@drawable/list_divide_line"

                android:contentDescription="@null" />

            <RelativeLayout

                android:layout_width="match_parent"

                android:layout_height="50dp" >

                <TextView

                    android:layout_width="wrap_content"

                    android:layout_height="40dp"

                    android:layout_marginLeft="15dp"

                    android:ellipsize="end"

                    android:gravity="center_vertical"

                    android:includeFontPadding="false"

                    android:singleLine="true"

                    android:text="單元測試8"

                    android:textSize="16sp" />

                <ImageView

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:layout_alignParentRight="true"

                    android:layout_centerVertical="true"

                    android:layout_marginRight="10dp"

                    android:contentDescription="@null"

                    android:src="@drawable/ic_set_arrow" />

            </RelativeLayout>

            <ImageView

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:background="@drawable/list_divide_line"

                android:contentDescription="@null" />

            <RelativeLayout

                android:layout_width="match_parent"

                android:layout_height="50dp" >

                <TextView

                    android:layout_width="wrap_content"

                    android:layout_height="40dp"

                    android:layout_marginLeft="15dp"

                    android:ellipsize="end"

                    android:gravity="center_vertical"

                    android:includeFontPadding="false"

                    android:singleLine="true"

                    android:text="單元測試9"

                    android:textSize="16sp" />

                <ImageView

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:layout_alignParentRight="true"

                    android:layout_centerVertical="true"

                    android:layout_marginRight="10dp"

                    android:contentDescription="@null"

                    android:src="@drawable/ic_set_arrow" />

            </RelativeLayout>

        </LinearLayout>

    </com.pb.soft.widget.UserDefineScrollView>

</RelativeLayout>

然后在MainActivity中調用

package com.soft.userdefinescrollview;

import android.app.Activity;

import android.os.Bundle;

public class MainActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

}

運行后的效果圖

本人在這里還做了一個Demo。需要下載的朋友可以去下載,這里提供一個下載鏈接http://download.csdn.net/detail/shaozucheng/7752629


 






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM