京東淘寶有那么一種效果就是,上拉能夠查看寶貝的詳情,這里我也實現了一個類似的效果,也能夠移植到商業項目上:先看看簡單的效果圖

實現原理事實上是利用了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沒有效果,而是直接到了某一點)。 這就實現了上拉查看詳情和下拉隱藏詳情頁的效果。
效果圖中用到了一個下拉刷新的組件是v4包里的SwipeRefreshLayout控件。這個非常好用的,大家能夠試試哦。好了就到這里了:Demo下載地址
