編輯:關於Android編程
前言
在微信是的處理方法是讓用戶滑動,但最終還是回滾到最初的地方,這樣的效果很生動(畢竟成功還是取決於細節)。那麼在安卓我們要怎麼弄呢。下面為大家介紹一下JellyScrollView,是我繼承ScrollView的一個有阻尼的效果的果凍滑動控件。
下面話不多說了,先來看看效果圖

(在虛擬機或者真機跑起來是很流暢,可能是錄制視頻做成gif的時候有點卡頓。)
實現原理
其實只需要重寫下它的攔截方法的邏輯就好了,ScrollView的攔截方法onInterceptTouchEvent一般情況下都默認地返回false,表示不攔截該事件。我們只需要在用戶滑動了界面的情況下,攔截下來並移動布局就好了,當用戶松開手就恢復布局。很簡單
第一步:集成ScrollView重寫幾個構造方法;
第二步:重寫下onFinishInflate方法,獲得第一個子view;
第三步:在攔截方法裡面處理上面所說的邏輯;
public class JellyScrollView extends ScrollView {
private View inner;// 子View
private float y;// 點擊時y坐標
private Rect normal = new Rect();// 矩形(這裡只是個形式,只是用於判斷是否需要動畫.)
private boolean isCount = false;// 是否開始計算
private boolean isMoving = false;// 是否開始移動.
private int top;// 拖動時時高度。
private int mTouchSlop;//系統最少滑動距離
public JellyScrollView(Context context) {
super(context);
}
public JellyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public JellyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
/***
* 根據 XML 生成視圖工作完成.該函數在生成視圖的最後調用,在所有子視圖添加完之後. 即使子類覆蓋了 onFinishInflate
* 方法,也應該調用父類的方法,使該方法得以執行.
*/
@Override
protected void onFinishInflate() {
if (getChildCount() > 0) {
inner = getChildAt(0);
}
}
/**攔截事件*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (inner != null) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
y = ev.getY();
top = 0;
break;
case MotionEvent.ACTION_UP:
// 手指松開.
isMoving = false;
if (isNeedAnimation()) {
animation();
}
break;
/***
* 排除出第一次移動計算,因為第一次無法得知y坐標, 在MotionEvent.ACTION_DOWN中獲取不到,
* 因為此時是ScrollView的touch事件傳遞到到了ListView的子item上面.所以從第二次計算開始.
* 然而我們也要進行初始化,就是第一次移動的時候讓滑動距離歸0. 之後記錄准確了就正常執行.
*/
case MotionEvent.ACTION_MOVE:
final float preY = y;// 按下時的y坐標
float nowY = ev.getY();// 每時刻y坐標
int deltaY = (int) (nowY - preY);// 滑動距離
if (!isCount) {
deltaY = 0; // 在這裡要歸0.
}
if (Math.abs(deltaY) < mTouchSlop && top <= 0)
return true;
// 當滾動到最上或者最下時就不會再滾動,這時移動布局
isNeedMove();
if (isMoving) {
// 初始化頭部矩形
if (normal.isEmpty()) {
// 保存正常的布局位置
normal.set(inner.getLeft(), inner.getTop(), inner.getRight(), inner.getBottom());
}
// 移動布局
inner.layout(inner.getLeft(), inner.getTop() + deltaY / 3, inner.getRight(), inner.getBottom() + deltaY / 3);
top += (deltaY / 6);
}
isCount = true;
y = nowY;
break;
}
}
return super.onInterceptTouchEvent(ev);
}
/***
* 回縮動畫
*/
public void animation() {
// 開啟移動動畫
TranslateAnimation ta = new TranslateAnimation(0, 0, inner.getTop(), normal.top);
ta.setDuration(200);
inner.startAnimation(ta);
// 設置回到正常的布局位置
inner.layout(normal.left, normal.top, normal.right, normal.bottom);
normal.setEmpty();
// 手指松開要歸0.
isCount = false;
y = 0;
}
// 是否需要開啟動畫
public boolean isNeedAnimation() {
return !normal.isEmpty();
}
/***
* 是否需要移動布局
* inner.getMeasuredHeight():獲取的是控件的總高度
* getHeight():獲取的是屏幕的高度
*
* @return
*/
public void isNeedMove() {
int offset = inner.getMeasuredHeight() - getHeight();
int scrollY = getScrollY();
// scrollY == 0是頂部
// scrollY == offset是底部
if (scrollY == 0 || scrollY == offset) {
isMoving = true;
}
}
}
然後在布局裡面在最外層就使用我們的JellyScrollView
(為了方便展示,我只是大概寫了一部分布局代碼)
<?xml version="1.0" encoding="utf-8"?><cn.ichengxi.fang.view.JellyScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/bg" android:scrollbars="none"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/personal_setting_txt" android:layout_width="match_parent" android:layout_height="wrap_content" android:alpha="0.8" android:gravity="center_vertical" android:text="設置" android:textColor="@android:color/black" /> </LinearLayout></cn.ichengxi.fang.view.JellyScrollView>12345678910111213141516171819202122231234567891011121314151617181920212223
總結
好了,這樣就可以很優雅的實現了果凍控件的效果啦。以上就是本文的全部內容了,希望這篇文章的內容對大家能有所幫助,如果有疑問大家可以留言交流。
Android學習JNI,使用JNI實現字符串加密
本節學習使用C語言加密字符串,大家都知道使用JAVA實現的加密都可以反編譯的,而使用C寫的加密是很難被反編譯的。所以我們使用JNI學習如何使用C實現對字符串的加密。首先:
Android圖文詳解屬性動畫
Android中的動畫分為視圖動畫(View Animation)、屬性動畫(Property Animation)以及Drawable動畫。從Android 3.0(A
Android使用開源框架ANDROID-IMAGE-INDICATOR實現圖片輪播部署
之前的博文中有介紹關於圖片輪播的實現方式,分別為(含超鏈接):1、《Android中使用ViewFlipper實現屏幕切換》2、《Android中使用ViewPager實
Android Drawable之GradientDrawable
GradientDrawable可以在res/drawable目錄下以xml文件用標簽來定義。看看官方文檔給出的xml定義說明吧。