`
zdphpn
  • 浏览: 11551 次
  • 性别: Icon_minigender_1
  • 来自: 邯郸市
社区版块
存档分类
最新评论
阅读更多
        下拉刷新,上拉加载,很流行的啊,总的来说有两种。一种当ListView下拉时整个页面一块下移,露出顶部的提示,另一种当ListView下拉到最顶端时,页面不移动,而是在上面出现一层提示或图标。上拉加载都是判断页面有没有快要滑到底部。


注:第二种想贴知乎的下拉效果,无奈知乎在模拟器上怎么都装不上

        这里来实现第二种。原理就是自定一种布局,包含一个ListView和头部的刷新提示,代码里就在触摸事件函数判断状态,改变刷新提示的显示位置、信息就可以。新建一个类继承自RelativeLayout(提示图标在中间而且位于ListView上层,所以选择RelativeLayout):
public class QListView extends RelativeLayout {

	public QListView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
	}

}

        为了简单,新建了一个对应的布局文件,在类构造中引入布局文件,获取其中的控件(ListView和提示布局等)操作,而不是在类中用代码去新生成一个ListView和提示布局等(当然这也可以,各有利弊),layout_qlistview:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    
    <RelativeLayout
          android:id="@+id/rl_refresh"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:paddingTop="-42dp" >
	    <ImageView
			android:id="@+id/iv_refresh"
			android:layout_width="38dp"
			android:layout_height="38dp"
			android:layout_centerHorizontal="true"
			android:padding="8dp"
			android:background="@drawable/shaper_oval_apptheme"
			android:src="@drawable/refresh"
			android:tint="@color/white_dark"
			android:rotation="90"/>
    </RelativeLayout>

</RelativeLayout>

注:仅是包括了一个提示用的图标,并没有ListView,因为ListView要加头和尾并且要控制,方便点在代码里新生成的
        QListView构造方法中:
public QListView(Context context, AttributeSet attrs) {
	super(context, attrs);
	// TODO Auto-generated constructor stub
	LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	inflater.inflate(R.layout.layout_qlistview, this);
		
	RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
	clv_list=new CListView(context);
	clv_list.setLayoutParams(lp);
	this.addView(clv_list, 0);
		
	initView(context);
	initListener();
}

        引入了layout_qlistview,新生成CListView并加入到最底层,CListView为一个自定义内部类,继承自ListView。
private class CListView extends ListView {

	public CListView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}
	//触摸事件处理,放到ListView里,放到外层的RelativeLayout不知道可不可以。
	public boolean dispatchTouchEvent(MotionEvent ev) {
		// TODO Auto-generated constructor stub
		return super.dispatchTouchEvent(ev);
	}

}

        QListView初始化相关函数:
private void initView(Context context){
	iv_refresh=(ImageView)findViewById(R.id.iv_refresh);
	rl_refresh=(RelativeLayout)findViewById(R.id.rl_refresh);
	rl_refresh.setPadding(0, -200, 0, 0);
	anim_rotate=AnimationUtils.loadAnimation(context, R.anim.anim_rotate_round);//先不管它
				
	clv_list.setDividerHeight(0);
	clv_list.setSelector(R.drawable.shaper_rect_null);
}

private void initListener(){
	
}


        QListView还要实现(加入)一些ListView常用的方法,以使QListView和ListView用法一致,如:
public void setAdapter(ListAdapter adapter){
	this.clv_list.setAdapter(adapter);
}

        将上节中的ListView都改为QListView(布局要写全路径),运行,确定不会崩溃。

注:这是一个.gif动图,ctrl点击图片查看,布局改过,之后会说

        接着,实现滑动时的图标提示,触摸事件处理dispatchTouchEvent中:
switch(ev.getAction()){
	case MotionEvent.ACTION_DOWN:
	if(getFirstVisiblePosition()==0&&!isRefresh){
		isDown=true;
		downY=ev.getY();
	}
	break;
	case MotionEvent.ACTION_MOVE:
	if(isDown){
		float dY=ev.getY()-downY;
		dY/=1.414f;
		int maxH=header.getHeight()-iv_refresh.getHeight()/2;
		float scale=dY/maxH;
		if(dY>0){
			if(rl_refresh.getPaddingTop()<=maxH){
				if(scale<2){
					iv_refresh.setRotation(scale*360);
					iv_refresh.setAlpha(scale*1.414f);
					if(dY-iv_refresh.getHeight()<maxH){
						rl_refresh.setPadding(0, (int)dY-iv_refresh.getHeight(), 0, 0);
					}
					else{
						rl_refresh.setPadding(0, maxH, 0, 0);
					}
				}
			}
			isMove=true;
			return true;
		}
		else{
			if(isMove){
				return true;
			}
		} 
	}
	break;
	default:
	isDown=false;
	if(isMove){
		int temp=header.getHeight()+iv_refresh.getHeight()/2;
		if(ev.getY()-downY>temp*1.2f){
			iv_refresh.setRotation(360);
			iv_refresh.setAlpha(1.0f);
	
			rl_refresh.setPadding(0, temp-iv_refresh.getHeight(), 0, 0);
						
			isPull=true;
		}
					
		if(isPull){
			isPull=false;
			iv_refresh.startAnimation(anim_rotate);
			if(pulllistener!=null){//刷新监听器,下节会说
				pulllistener.onRefresh();
				isRefresh=true;
			}
		}
		else{
			rl_refresh.setPadding(0, -iv_refresh.getHeight(), 0, 0);
		}
				
		isMove=false;
		return true;
	}
	break;
}

        代码比较乱,CListView添加了个头和尾,如下:
public CListView(Context context) {
	super(context);
	// TODO Auto-generated constructor stub
	
	initView(context);
	initListener();
}
private void initView(Context context){
	this.addHeaderView(new View(context));//添加空,便于操作
	
	header=new CHeader(context);//头部,见下
	footer=new CFooter(context);//尾部,见下
	this.addHeaderView(header,null,false);//添加
	this.addFooterView(footer, null, false);
}
private class CHeader extends RelativeLayout{
	public CHeader(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		inflater.inflate(R.layout.view_listheader, this);
	}
}
private class CFooter extends RelativeLayout{
	public CFooter(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		inflater.inflate(R.layout.view_listfooter, this);
	}
}

        头尾布局如下:
view_listheader

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 	xmlns:android="http://schemas.android.com/apk/res/android"
    	android:layout_width="match_parent"
    	android:layout_height="wrap_content"
    	android:paddingTop="@dimen/padding_s"
    	android:paddingLeft="@dimen/padding_s"
	android:paddingRight="@dimen/padding_s"
    	android:paddingBottom="0.5dp" >
    	<RelativeLayout
		android:layout_width="match_parent"
	    	android:layout_height="wrap_content"
	    	android:paddingTop="@dimen/padding_ll"
		android:paddingBottom="@dimen/padding_ll"
	    	android:paddingLeft="@dimen/padding_n"
		android:paddingRight="@dimen/padding_n"
	    	android:background="@color/white_dark" >
    
	    	<TextView
	      	android:layout_width="wrap_content"
	    		android:layout_height="wrap_content"
	    		android:layout_alignParentLeft="true"
	    		android:textSize="@dimen/text_level2"
		  	android:textColor="@color/text_level3"
		    	android:text="列表:全部" />
	    
	    	<TextView
	        	android:layout_width="wrap_content"
	    		android:layout_height="wrap_content"
	    		android:layout_alignParentRight="true"
	    		android:textSize="@dimen/text_level2"
		   	android:textColor="@color/text_level3"
		    	android:text="最近更新:23:22" />
	</RelativeLayout>
</RelativeLayout>


view_listfooter
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 	xmlns:android="http://schemas.android.com/apk/res/android"
    	android:layout_width="match_parent"
    	android:layout_height="wrap_content"
    	android:paddingTop="0dp"
    	android:paddingLeft="@dimen/padding_s"
    	android:paddingRight="@dimen/padding_s"
    	android:paddingBottom="@dimen/padding_s" >
    	<RelativeLayout
		android:layout_width="match_parent"
	    	android:layout_height="wrap_content"
	    	android:paddingTop="@dimen/padding_ll"
		android:paddingBottom="@dimen/padding_ll"
	    	android:paddingLeft="@dimen/padding_n"
		android:paddingRight="@dimen/padding_n"
	    	android:background="@color/white_dark" >
    
	    	<TextView
	      	android:layout_width="wrap_content"
	    		android:layout_height="wrap_content"
	    		android:layout_alignParentLeft="true"
	    		android:textSize="@dimen/text_level2"
		    	android:textColor="@color/text_level3"
		    	android:text="加载中•••" />
	    
	    	<TextView
	        	android:layout_width="wrap_content"
	    		android:layout_height="wrap_content"
	    		android:layout_alignParentRight="true"
	    		android:textSize="@dimen/text_level2"
		    	android:textColor="@color/text_level3"
		    	android:text="已加载:36条" />
	</RelativeLayout>
</RelativeLayout>

运行效果:

注:头部的重影不知是怎么回事,真机是正常的,拉下来后并不会自动弹回去

重新启动——2017/05/15




  • 大小: 110.6 KB
  • 大小: 61.1 KB
  • 大小: 1.4 MB
  • 大小: 1.8 MB
分享到:
评论

相关推荐

    C# 强大的自定义ListView ObjectListViewFull-2.4.1

    本文将深入探讨C#中的自定义ListView以及ObjectListViewFull-2.4.1这个强大的工具。 ObjectListView是一个开源的.NET组件,它扩展了Windows Forms的ListView控件,提供了更多的功能和易用性。这个库的版本2.4.1带来...

    自定义ListView实现下拉刷新+加载更多功能Demo

    在Android开发中,自定义ListView实现下拉刷新和加载更多的功能是常见的需求,尤其是在构建具有数据流滚动和实时更新的应用程序时。这个"自定义ListView实现下拉刷新+加载更多功能Demo"旨在帮助开发者理解如何集成...

    Android中的自定义ListView

    本篇文章将深入探讨如何在Android中使用ListView,以及如何实现自定义ListView。 首先,理解ListView的基本概念至关重要。ListView是一个视图容器,可以动态加载并显示一串可滚动的项目列表。每个列表项通常由一个...

    C# 自定义ListView

    针对这一需求,开发者常常需要自定义ListView,以实现图文并茂的展示效果。 自定义ListView的关键在于扩展ListView的基本功能,增加对图片的支持。这通常涉及到以下几个方面: 1. **Item模板**:通过修改ListView...

    自定义listview下拉刷新上拉加载更多以及与google官方的下拉刷新结合使用

    本教程将探讨如何自定义ListView实现下拉刷新和上拉加载更多,并将其与Google官方的SwipeRefreshLayout结合使用。 首先,我们要理解下拉刷新和上拉加载更多的基本概念。下拉刷新是指用户在ListView顶部向下拉动时,...

    自定义listview

    自定义ListView可以帮助开发者根据需求实现更复杂、更具个性化的界面。在这个主题中,我们将深入探讨如何设计自定义ListView,包括创建适配器(Adapter)以及解决滑动冲突的问题。 首先,自定义ListView通常涉及到...

    android自定义listview使用方法

    自定义ListView可以实现更丰富的界面效果和交互功能,提升用户体验。本教程将详细讲解如何在Android中实现自定义ListView,包括基本的ListView、带图片的ListView以及带有按钮的ListView。 1. **基本的ListView** ...

    自定义ListView

    自定义ListView是提升用户体验、实现个性化界面的关键步骤。本教程将深入探讨如何在Android中实现自定义ListView,结合源码分析,帮助开发者更好地理解和运用这一核心组件。 首先,自定义ListView主要涉及以下几个...

    完美仿QQ侧滑操作,自定义listview

    自定义的listview来做的,本来的思路是自定义item的根...于是改用自定义listview,结果很喜人,个人觉得比较完美,支持3.0以下, 由于是属性动画需要支持到3.0以下,所以使用了nineoldandroid这个开源的属性动画库。

    1.8 自定义ListView中的行

    `1.8 自定义ListView中的行`这个主题主要涉及如何根据应用需求调整ListView中每一行的显示样式,使其更加个性化和符合用户界面设计。以下将详细介绍这个过程,以及相关的知识点。 首先,自定义ListView的行通常涉及...

    自定义ListView(适配器和布局)

    自定义ListView是开发者经常需要面对的任务,因为默认的ListView可能无法满足所有需求。本文将深入探讨如何通过适配器(Adapter)和自定义布局来实现一个功能丰富的自定义ListView。 一、适配器(Adapter)的理解与...

    Android 自定义ListView(下拉刷新PullToRefreshListView 上拉加载LoadListView)

    Android 自定义ListView,分别实现下拉刷新的ListView及上拉加载的ListView 详情可以参考我的博客 http://blog.csdn.net/sunshanai/article/details/51622917

    TabHost中填充自定义ListView

    在Android开发中,`TabHost` 是一个非常重要的组件,用于实现多标签页面的切换,而将自定义的`ListView`填充到`TabHost`中则可以构建出复杂的交互界面。下面我们将详细探讨如何实现这一功能。 首先,我们需要了解`...

    android 自定义ListView实现单选

    本篇文章将详细探讨如何通过自定义ListView来实现单选功能,旨在帮助开发者解决这一问题。 一、自定义ListView的必要性 系统自带的ListView默认并未提供单选模式,而是多选或全选。当用户需要在列表中选择一个项目...

    安卓listview相关相关-自定义listview继承最新控件.zip

    这个压缩包文件“安卓listview相关相关-自定义listview继承最新控件.zip”显然包含了与自定义ListView相关的资料,以及可能的源码示例。以下是关于自定义ListView及其相关知识点的详细讲解: 1. **ListView基础**:...

    自定义listview的item控件

    当列表中的每一项需要有不同的显示样式或包含不同内容时,我们就需要自定义ListView的Adapter。这个过程涉及到Android的视图复用机制、数据绑定以及事件处理等多个核心知识点。 1. **Adapter原理**: Android的...

    自定义ListView+fragment

    自定义ListView是开发者经常需要面对的任务,因为默认的ListView可能无法满足所有需求。本项目“自定义ListView+Fragment”显然涉及到如何将自定义的ListView与Android的Fragment机制相结合,以实现更灵活、功能丰富...

    Android 自定义listview 轻松实现360软件详情页

    本篇将详细讲解如何通过自定义ListView轻松实现360软件详情页的效果,即ListView滑动到顶部时固定头部视图。 首先,"360软件详情页"的效果通常包含一个固定的头部视图,当用户滚动列表时,头部视图始终保持在屏幕...

    自定义listview实现联系人排序

    它允许用户滚动查看信息,而自定义ListView则是为了满足特定需求,如提供独特的视图样式、交互效果或者复杂的数据处理。本教程将深入探讨如何通过自定义ListView来实现联系人排序功能。 首先,我们需要了解ListView...

Global site tag (gtag.js) - Google Analytics