一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術(shù)及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Android - Android ScrollView的頂部下拉和底部上拉回彈效果

Android ScrollView的頂部下拉和底部上拉回彈效果

2022-02-17 17:16Denluoyia Android

本篇文章主要介紹了Android ScrollView的頂部下拉和底部上拉回彈效果,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

要實現(xiàn)ScrollView的回彈效果,需要對其進行觸摸事件處理。先來看一下簡單的效果:

Android ScrollView的頂部下拉和底部上拉回彈效果

根據(jù)Android的View事件分發(fā)處理機制,下面對dispatchTouchEvent進行詳細分析:

在加載布局完成之后,獲取ScrollView的第一個子元素,保存它的參數(shù),left top right bottom參數(shù),根據(jù)頂部下拉操作和底部上拉操作進行子View的布局參數(shù)根據(jù)滑動距離改變,ACTION_UP的時候判斷是否存在回彈,如果需要則進行動畫回彈到原來的位置,可以添加一個回彈結(jié)束監(jiān)聽,比如監(jiān)聽回彈處理跳轉(zhuǎn)到其他的頁面的操作等。

具體的實現(xiàn)如下,添加了是否禁用頂部和底部回彈的參數(shù)設置,以及回彈效果結(jié)束監(jiān)聽。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/**
 * A Simple Rebound ScrollView
 * @author Denluoyia
 */
public class ReboundScrollView extends ScrollView{
 
  private boolean mEnableTopRebound = true;
  private boolean mEnableBottomRebound = true;
  private OnReboundEndListener mOnReboundEndListener;
  private View mContentView;
  private Rect mRect = new Rect();
 
  public ReboundScrollView(Context context) {
    super(context);
  }
 
  public ReboundScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }
 
  public ReboundScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
  }
 
  /** after inflating view, we can get the width and height of view */
  @Override
  protected void onFinishInflate() {
    super.onFinishInflate();
    mContentView = getChildAt(0);
  }
 
  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);
    if (mContentView == null) return;
    // to remember the location of mContentView
    mRect.set(mContentView.getLeft(), mContentView.getTop(), mContentView.getRight(), mContentView.getBottom());
  }
 
  public ReboundScrollView setOnReboundEndListener(OnReboundEndListener onReboundEndListener){
    this.mOnReboundEndListener = onReboundEndListener;
    return this;
 
  }
 
  public ReboundScrollView setEnableTopRebound(boolean enableTopRebound){
    this.mEnableTopRebound = enableTopRebound;
    return this;
  }
 
  public ReboundScrollView setEnableBottomRebound(boolean mEnableBottomRebound){
    this.mEnableBottomRebound = mEnableBottomRebound;
    return this;
  }
 
  private int lastY;
  private boolean rebound = false;
  private int reboundDirection = 0; //<0 表示下部回彈 >0 表示上部回彈 0表示不回彈
 
  @Override
  public boolean dispatchTouchEvent(MotionEvent ev) {
    if (mContentView == null){
      return super.dispatchTouchEvent(ev);
    }
    switch (ev.getAction()){
      case MotionEvent.ACTION_DOWN:
        lastY = (int) ev.getY();
        break;
 
      case MotionEvent.ACTION_MOVE:
        if (!isScrollToTop() && !isScrollToBottom()){
          lastY = (int) ev.getY();
          break;
        }
        //處于頂部或者底部
        int deltaY = (int) (ev.getY() - lastY);
        //deltaY > 0 下拉 deltaY < 0 上拉
 
 
        //disable top or bottom rebound
        if ((!mEnableTopRebound && deltaY > 0) || (!mEnableBottomRebound && deltaY < 0)){
          break;
        }
 
        int offset = (int) (deltaY * 0.48);
        mContentView.layout(mRect.left, mRect.top + offset, mRect.right, mRect.bottom + offset);
        rebound = true;
        break;
 
      case MotionEvent.ACTION_UP:
        if (!rebound) break;
        reboundDirection = mContentView.getTop() - mRect.top;
        TranslateAnimation animation = new TranslateAnimation(0, 0, mContentView.getTop(), mRect.top);
        animation.setDuration(300);
        animation.setAnimationListener(new Animation.AnimationListener() {
          @Override
          public void onAnimationStart(Animation animation) {
 
          }
 
          @Override
          public void onAnimationEnd(Animation animation) {
            if (mOnReboundEndListener != null){
              if (reboundDirection > 0){
                mOnReboundEndListener.onReboundTopComplete();
              }
              if (reboundDirection < 0){
                mOnReboundEndListener.onReboundBottomComplete();
              }
              reboundDirection = 0;
            }
          }
 
          @Override
          public void onAnimationRepeat(Animation animation) {
 
          }
        });
        mContentView.startAnimation(animation);
        mContentView.layout(mRect.left, mRect.top, mRect.right, mRect.bottom);
        rebound = false;
        break;
    }
    return super.dispatchTouchEvent(ev);
  }
 
  @Override
  public void setFillViewport(boolean fillViewport) {
    super.setFillViewport(true); //默認是填充ScrollView 或者再XML布局文件中設置fillViewport屬性
  }
 
  /**
   * 判斷當前ScrollView是否處于頂部
   */
  private boolean isScrollToTop(){
    return getScrollY() == 0;
  }
 
  /**
   * 判斷當前ScrollView是否已滑到底部
   */
  private boolean isScrollToBottom(){
    return mContentView.getHeight() <= getHeight() + getScrollY();
  }
 
  /**
   * listener for top and bottom rebound
   * do your implement in the following methods
   */
  public interface OnReboundEndListener{
 
    void onReboundTopComplete();
 
    void onReboundBottomComplete();
  }
}

 使用:

直接在XML布局文件中把ScrollView替換成ReboundScrollView就可以了。還可以拓展把回彈頂部和底部添加其他的動畫效果(之后再拓展試下)。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
  tools:context=".TestActivity">
 
  <com.denluoyia.dtils.widget.ReboundScrollView
    android:id="@+id/reboundScrollView"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:background="#eefade"
      android:padding="16dp">
 
      <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="15sp"
        android:lineSpacingExtra="5dp"
        android:text="@string/content"/>
    </LinearLayout>
  </com.denluoyia.dtils.widget.ReboundScrollView>
 
</LinearLayout>

 如果需要禁用回彈,可以直接設置enableTopRebound和enableBottomRebound參數(shù),同樣設置回彈結(jié)束(或開始)監(jiān)聽。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class TestActivity extends AppCompatActivity {
 
  private ReboundScrollView reboundScrollView;
 
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);
 
    reboundScrollView = findViewById(R.id.reboundScrollView);
    //reboundScrollView.setEnableTopRebound(false);
    //reboundScrollView.setEnableBottomRebound(false);
    reboundScrollView.setOnReboundEndListener(new ReboundScrollView.OnReboundEndListener() {
      @Override
      public void onReboundTopComplete() {
        Toast.makeText(TestActivity.this, "頂部回彈", Toast.LENGTH_SHORT).show();
      }
 
      @Override
      public void onReboundBottomComplete() {
        Toast.makeText(TestActivity.this, "底部回彈", Toast.LENGTH_SHORT).show();
      }
    });
  }
}

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://www.cnblogs.com/denluoyia/p/8995589.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 精品欧美日韩一区二区三区 | 高h扶她文肉| 日本三级在线观看免费 | 国产成人久久精品推最新 | 国产高清在线播放刘婷91 | 男人影院天堂网址 | 美女gif趴跪式抽搐动态图 | avtt在线观看 | 精品91自产拍在线观看99re | 精品成人网 | 啊啊啊好爽在线观看 | 日本一道高清不卡免费 | 亚洲第一页综合 | 秀婷程仪公欲息肉婷在线观看 | 欧美日韩国产精品va | 亚洲成人黄色 | 黑人巨大初黑人解禁作品 | 久久久久久88色偷偷 | 99国产国人青青视频在线观看 | 国产视频分类 | 日产中文乱码卡一卡二 | 农村妇女野外性生话免费视频 | 亚洲区一| 99久9在线视频 | 98在线视频噜噜噜国产 | jazz中国女人护士 | 天天爽天天干天天操 | 日韩一区在线播放 | 男人晚上适合偷偷看的污污 | 91精品国产91热久久p | 国产乱码免费卡1卡二卡3卡四 | 青草悠悠视频在线观看 | 菠萝视频在线完整版 | 我半夜摸妺妺的奶C了她软件 | 99ri国产在线 | 免费午夜影院 | 99热都是精品 | 国产麻豆流白浆在线观看 | 婷婷综合缴情亚洲五月伊 | 色综合色狠狠天天久久婷婷基地 | 精品一区二区视频 |