編輯:關於Android編程
京東淘寶有那麼一種效果就是,上拉可以查看寶貝的詳情,這裡我也實現了一個類似的效果,也可以移植到商業項目上:先看看簡單的效果圖
實現原理其實是利用了ScrollView的滾動和view的touch事件監聽完成的:圖片層(也可以是其他布局)和詳情頁層其實是從上到下布局到ScrollView中的,首先要屏蔽ScrollView的touch事件,然後初始化的時候給上層設置為屏幕的高度,詳情頁設置高度為屏幕高度 - 狀態欄高度 - 上層灰色提示信息的高度。再給圖片層添加touch事件,獲取手指移動的距離,當達到一定的距離就上滑或下滑,否則就回彈回去。就是這麼簡單 哈哈
一:自定義ScrollView屏蔽touch事件(不然,圖片層不能監聽到touch事件)
package com.ywl5320.scrollanima; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.ScrollView; public class MyScrollView extends ScrollView { private OnScrollChangedListeneer onScrollChangedListeneer;// 滾動監聽接口 public MyScrollView(Context context) { super(context); // TODO Auto-generated constructor stub } public MyScrollView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // TODO Auto-generated constructor stub } @Override public boolean onTouchEvent(MotionEvent ev) { // 屏蔽touch事件,才能在監聽其子控件的touch事件 // TODO Auto-generated method stub super.onTouchEvent(ev); return false; } @Override public boolean onInterceptTouchEvent(MotionEvent event)// 屏蔽touch事件傳遞,才能在監聽其子控件的touch事件 { super.onInterceptTouchEvent(event); return false; } @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { // TODO Auto-generated method stub super.onScrollChanged(l, t, oldl, oldt); if(onScrollChangedListeneer != null) { onScrollChangedListeneer.onScrollChanged(l, t, oldl, oldt); } } // 滾動事件監聽,獲取滾動的距離,用戶處理一些其他事 public interface OnScrollChangedListeneer { public void onScrollChanged(int l, int t, int oldl, int oldt); } public void setOnScrollChangedListeneer(OnScrollChangedListeneer onScrollChangedListeneer) { this.onScrollChangedListeneer = onScrollChangedListeneer; } }這裡屏蔽touch事件的同時,還為滾動事件添加了一個回調接口,方便在使用的時候獲取滾動的狀態,以實現其他需要的效果。
二:動態設置圖片層和詳情頁的高度
// 設置滑動層為屏幕高度 LayoutParams lp = (LayoutParams) lyView.getLayoutParams(); screenHeight = measureHeight(); lp.height = screenHeight; lyView.setLayoutParams(lp); // 設置詳細層的高度:等於屏幕高度-狀態欄高度-陰影提示高度 LayoutParams lp2 = (LayoutParams) swipeRefreshLayout.getLayoutParams(); lp2.height = screenHeight - dip2px(MainActivity.this, 150) - getStatusBarHeight(); swipeRefreshLayout.setLayoutParams(lp2);
用到的工具方法:
/** * 獲取屏幕高度 * * @return */ public int measureHeight() { WindowManager wManager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics(); wManager.getDefaultDisplay().getMetrics(dm); return dm.heightPixels; } /** * dip轉換為px * * @param context * @param dipValue * @return */ public int dip2px(Context context, float dipValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dipValue * scale + 0.5f); } /** * 獲取狀態欄高度 * * @return */ private int getStatusBarHeight() { int result = 0; int resourceId = getResources().getIdentifier(status_bar_height, dimen, android); if (resourceId > 0) { result = getResources().getDimensionPixelSize(resourceId); } return result; }初始化工作就完成了
三:為圖片層添加touch事件
// 為上層添加touch事件,控制詳情頁顯示隱藏 lyView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub int action = event.getAction(); int offsety = 0; int y = 0; switch (action) { case MotionEvent.ACTION_DOWN: point.y = (int) event.getRawY(); offsetsum = 0; // System.out.println(event.getX() + ---------- + event.getY()); break; case MotionEvent.ACTION_MOVE: y = (int) event.getRawY(); offsety = y - point.y; offsetsum += offsety; point.y = (int) event.getRawY(); sv.scrollBy(0, -offsety); // System.out.println(offsetnum: + offsetsum); break; case MotionEvent.ACTION_UP: if (offsetsum > 0) {// offsetsum大於0時是往下拉,只有當顯示詳情頁是下拉才有效果,所以這裡先判斷isOpen的值。 if (isOpen) { if (offsetsum > 300) { sv.smoothScrollTo(0, 0); isOpen = false; } else { sv.smoothScrollTo(0, screenHeight); isOpen = true; } } else { sv.smoothScrollTo(0, 0); isOpen = false; } } else {// offsetsum小於0時是往上拉,只有當隱藏詳情頁是下拉才有效果,所以這裡先判斷isOpen的值。 if(!isOpen) { if (offsetsum < -300) { sv.smoothScrollTo( 0, screenHeight - dip2px(MainActivity.this, 150)); isOpen = true; } else { sv.smoothScrollTo(0, 0); isOpen = false; } } else { sv.smoothScrollTo( 0, screenHeight - dip2px(MainActivity.this, 150)); isOpen = true; } } break; } return true; } });首先判斷當前是否顯示詳情頁,然後根據手指移動距離是否大於0,判斷是向上(小於0)還是向下(大於0)滑動,當滑動了一定的距離後就執行滑動操作,利用ScrollView的smoothScrollTo方法動態的滑動到指定位置,注意:touch-move滑動時不要用smoothScrollTo這個方法,會導致Up時smoothScrollTo沒有效果(我想應該是move時的動畫監聽還沒有完成,up是就沒有添加成功動畫的監聽,導致up是smoothScrollTo沒有效果,而是直接到了某一點)。
地址
?在上篇文章《Android Span 架構介紹》,我們講述了Android Span的基本概念和用法,這篇文章我們就來擴展一下我們對Android Span的了解,這一
先上圖看卡結果:GITHUB:Android多線程下載斷點續傳如圖所示點擊下載就開始下載,點擊停止就會停止再次點擊下載就會接著下載了。設計思路是這樣的:首先通過廣播將下載
直接上圖: 在android 中導入項目後 包出現錯誤的解決方法 選中項目,右擊打開Proper
幾年前,看到過有個牛人用HTML5繪制了浪漫的愛心表白動畫。發現原來程序員也是可以很浪……漫…..的(PS:剛過520,被妹子罵