Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android上拉查看詳情實現

Android上拉查看詳情實現

編輯:關於Android編程

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

data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022314104677.gif

實現原理其實是利用了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沒有效果,而是直接到了某一點)。

 

 地址

 

 
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved