`

ScrollView做的上拉效果

阅读更多


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) {
		// TODO Auto-generated method stub
		// 屏蔽touch事件,才能在监听其子控件的touch事件
		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;
	}

}


import android.app.Activity;
import android.content.Context;
import android.graphics.Point;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.RelativeLayout.LayoutParams;

import com.mb.door.MyScrollView.OnScrollChangedListeneer;
import com.ywl5320.scrollanima.R;

public class MainActivity extends Activity {

	private View layout_content;
	private MyScrollView scrollView;
	private int offsetsum = 0;// 总的手指滑动距离
	private Point point = new Point();
	private View layout_sliding;

	private boolean isOpen = false; // true:显示详情 false 反之
	private int screenHeight = 0;

	private int handlerHeight = 100;// 把手的高度,该高度最好动态获取
	private int threshold=300; 
	private Context context;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		context = this;
		initViews();
	}

	private void initViews(){
		handlerHeight = dip2px(context, 100);// 把手的高度,该高度最好动态获取
		int statusBarHeight=getStatusBarHeight();
		
		scrollView = (MyScrollView) findViewById(R.id.scrollView);
		layout_content = findViewById(R.id.layout_content);
		layout_sliding = findViewById(R.id.layout_sliding);

		// 设置滑动层为屏幕高度
		LayoutParams lp = (LayoutParams) layout_content.getLayoutParams();
		screenHeight = getScreenHeight();
		lp.height = screenHeight - statusBarHeight;
		layout_content.setLayoutParams(lp);

		// 设置详细层的高度:等于屏幕高度-状态栏高度-阴影提示高度
		LayoutParams lp2 = (LayoutParams) layout_sliding.getLayoutParams();
		lp2.height = screenHeight  - statusBarHeight- handlerHeight;
		layout_sliding.setLayoutParams(lp2);

		// 为上层添加touch事件,控制详情页显示隐藏
		layout_content.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;
					break;
				case MotionEvent.ACTION_MOVE:
					y = (int) event.getRawY();
					offsety = y - point.y;
					offsetsum += offsety;
					point.y = (int) event.getRawY();
					scrollView.scrollBy(0, -offsety);
					break;
				case MotionEvent.ACTION_UP:
					if(offsetsum==0){
						return true;
					}
					if (offsetsum > 0) {// offsetsum大于0时是往下拉
						if (offsetsum > threshold) {
							close();
						} else {
							open();
						}
					} else {// offsetsum小于0时是往上拉
						if (offsetsum < -threshold) {
							open();
						} else {
							close();
						}
					}

					break;
				}
				return true;
			}
		});

		scrollView.setOnScrollChangedListeneer(new OnScrollChangedListeneer() {

			@Override
			public void onScrollChanged(int l, int t, int oldl, int oldt) {
				// TODO Auto-generated method stub
				Log.i("tag", l + "--" + t + "--" + oldl + "--"+ oldt);
			}
		});
	}
	
	private void open() {
		scrollView.smoothScrollTo(0, screenHeight - handlerHeight);
		isOpen = true;
	}

	private void close() {
		scrollView.smoothScrollTo(0, 0);
		isOpen = false;
	}

	public void toggle(){
		if(isOpen){
			close();
		}else{
			open();
		}
	}
	
	/**
	 * 获取屏幕高度
	 * 
	 * @return
	 */
	public int getScreenHeight() {
		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
	 */
	public int getStatusBarHeight() {
		int result = 0;
		int resourceId = getResources().getIdentifier("status_bar_height",
				"dimen", "android");
		if (resourceId > 0) {
			result = getResources().getDimensionPixelSize(resourceId);
		}
		return result;
	}

}


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

    <com.mb.door.MyScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="none" >

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

            <FrameLayout
                android:id="@+id/layout_content"
                android:layout_width="match_parent"
                android:layout_height="match_parent" >

                <FrameLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_gravity="center"
                    android:background="@android:color/holo_blue_dark" >
                </FrameLayout>

                <TextView
                    android:id="@+id/handler"
                    android:layout_width="match_parent"
                    android:layout_height="100dip"
                    android:layout_gravity="bottom"
                    android:background="#aa000000"
                    android:gravity="center"
                    android:text="上滑查看详情"
                    android:textColor="#ffffff" />
            </FrameLayout>

            <FrameLayout 
                android:id="@+id/layout_sliding"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_below="@id/layout_content"
                android:background="@android:color/white"
                >
            </FrameLayout>
            
        </RelativeLayout>
    </com.mb.door.MyScrollView>

</RelativeLayout>


事实上,同样的效果可以使用 ViewDragHelper实现
http://gundumw100.iteye.com/blog/2114716
  • 大小: 33.1 KB
分享到:
评论

相关推荐

    安卓ScrollView下拉刷新上拉加载效果

    当需要实现更复杂的滚动交互,如下拉刷新和上拉加载更多数据时,就需要对ScrollView进行扩展或者结合其他组件来实现。本文将详细探讨如何在Android中创建带有下拉刷新和上拉加载功能的ScrollView。 一、基础概念 1....

    嵌套ListView的ScrollView实现上拉和下拉

    这种布局方式通常被称为嵌套滚动,而这里的主题是“嵌套ListView的ScrollView实现上拉和下拉”。这涉及到自定义View的知识,以及如何处理触摸事件和滚动事件。以下是关于这个主题的详细解释: 1. **嵌套滚动**: 当...

    Android 支持ListView,GridView以及ScrollView上拉下拉控件源码以及Demo

    在Android开发中,ListView、GridView和ScrollView是常用的布局控件,用于展示大量数据或实现滚动效果。本资源提供了这些控件实现上拉下拉功能的源码和Demo,有助于开发者深入理解其工作原理并实现在自己的应用中。...

    ScrollView中图片拉伸阻尼效果

    要创建这样一个自定义的ScrollView,我们需要做以下几步: 1. **创建自定义ScrollView**: 首先,我们需要继承Android原生的ScrollView类,并重写其滚动相关的函数,例如`onTouchEvent()`和`onScrollChanged()`。...

    ScrollView+TableView滑动分层效果

    同时,为了实现上拉和下拉的手势,可能还需要自定义手势识别器(UIPanGestureRecognizer),并将其添加到ScrollView上,以便在手势发生时调整内容视图。 接下来,动画效果的添加是提升用户体验的重要环节。使用`...

    SwipeRefreshLayout 支持scrollview,listview上拉加载

    在Android开发中,为了提供更好的用户体验,我们常常需要在列表视图(ListView)或滚动视图(ScrollView)中实现上拉加载更多的功能。SwipeRefreshLayout是Android SDK提供的一种原生组件,用于实现下拉刷新的效果,...

    Android scrollview ListView GridView上拉下拉刷新

    总结来说,Android中的ScrollView、ListView和GridView上拉下拉刷新功能的实现涉及到自定义视图、滑动事件监听、数据加载逻辑和缓冲效果优化。熟练掌握这些技术,能有效提升应用的用户体验,使用户在浏览大量数据时...

    android scrollView 拉到最低和最顶端 反弹效果

    在Android开发中,ScrollView是常用的...总的来说,实现Android ScrollView的拉到最低和最顶端的反弹效果,主要涉及滚动监听、动画控制和视图操作。通过自定义监听器和动画,开发者可以为用户带来更丰富的交互体验。

    ScrollView实现可上下拉动

    ScrollView是Android开发中一个常用的布局组件,主要用于展示可以滚动的内容,比如当内容超过屏幕大小时,用户可以通过上拉和下拉来查看所有信息。在Android应用设计中,ScrollView通常用于构建具有多视图或者长文本...

    高仿IOS ScrollView,可持续上下拉,橡皮筋效果

    总之,"高仿IOS ScrollView,可持续上下拉,橡皮筋效果"是一个涉及Android自定义视图、触摸事件处理、动画和物理模拟的综合实践。`ReboundScrollView.java`文件中的代码应该包含了实现这些功能的关键逻辑。开发者...

    ScrollView之阻尼特效

    在本主题"ScrollView之阻尼特效"中,我们将探讨如何为ScrollView添加一种特殊的动画效果,这种效果通常被称为“阻尼”或“弹性”效果。这种效果在用户滑动时,会使得ScrollView的滚动速度逐渐减缓,模拟出类似物理...

    Android ListView,GridView,ScrollView上拉下拉刷新

    一个android上拉下拉刷新的基类,支持ListView,GridView和ScrollView的上拉下拉刷新,刷新效果不错。 是我从别的地方看到的,我把它搬了过来。 来自http://gundumw100.iteye.com/blog/1764763

    弹性拉伸Scrollview、scrollview嵌套listview和scrollview滑动监听demo

    这种效果使得ScrollView在内容不足时能够拉伸以填充整个屏幕,增加用户的交互体验。要实现这一效果,可以自定义一个ScrollView,并重写onMeasure()方法。在该方法中,计算ScrollView的测量宽度和高度,使其与父视图...

    ScrollView实现图片拉伸效果,仿QQ好友动态头部效果

    综上所述,实现“ScrollView实现图片拉伸效果,仿QQ好友动态头部效果”需要掌握自定义布局、滚动事件监听、图片拉伸算法以及性能优化等多方面的Android开发技能。通过实践这些技术,你可以创造出一个具有专业感且...

    带阻尼效果的scrollview,仿QQ空间

    综上所述,"带阻尼效果的scrollview,仿QQ空间"这个项目涵盖了移动应用开发中的多个重要知识点,包括ScrollView的使用、物理效果模拟、界面设计的还原以及性能优化等。开发者通过修复已知问题和持续改进,为用户提供...

    ViewPager局部滑动指引效果+ScrollView弹性异步加载效果

    为了优化用户体验,可以使用`RefreshLayout`组件,如`SwipeRefreshLayout`,提供下拉刷新和上拉加载更多的手势支持。 为了将这两种效果整合到一起,我们可以创建一个包含`ViewPager`的主页面,每个页面内部是一个...

    android 能上下弹性拉动的ScrollView

    在标题“android 能上下弹性拉动的ScrollView”中,所提及的是一个具有弹性的ScrollView,这意味着它增加了超出正常滚动范围的动画效果,为用户提供了更丰富的交互体验。这种效果通常被称为“橡皮筋效果”,模拟了...

    自定义弹性scrollviewDemo

    该组件实现了下拉弹回和上拉弹回的功能,与下拉刷新的效果类似,但更具趣味性和交互性。 首先,我们需要了解`ScrollView`的基本概念。`ScrollView`是Android提供的一个可滚动视图,可以容纳单个子视图,并允许用户...

Global site tag (gtag.js) - Google Analytics