zoukankan      html  css  js  c++  java
  • 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没有效果,而是直接到了某一点)。

    这就实现了上拉查看详情和下拉隐藏详情页的效果。

    效果图中用到了一个下拉刷新的组件是v4包里的SwipeRefreshLayout控件。这个非常好用的,大家能够试试哦。好了就到这里了:Demo下载地址







  • 相关阅读:
    Nodejs服务器搭建
    CRC8校验,生成多项式:X8 + X2 + X + 1
    windows server 2019添加开机启动项
    Ubuntu20.04下SSH2安装, gulp live报错解决
    Ubuntu 20.04 开机执行自定义脚本
    STUN/TURN服务器搭建
    PostgreSQL开启远程连接
    Ubuntu 20.04 开机执行自定义脚本
    CentOS下 rpm软件包的安装与卸载
    Ubuntu18.04安装JDK1.8.0_11
  • 原文地址:https://www.cnblogs.com/mthoutai/p/6892440.html
Copyright © 2011-2022 走看看