下拉刷新:继承listView控件

1、首先初始化的时候给控件监听OnScrollListener,其中onScroll的参数里得到第一个显示的条目,当第一个条目为0的时候就可以执行下啦刷新了。第二覆写的方法是

onScrollStateChanged就是滑动状态的监听,3种状态都是常量:快速滑动,触摸移动,闲置状态,当为第二种时候调用getlastVisiableposition()得到显示的最后一个条目,当为总条目的个数-1时就可以上移加载更多没在初始化的时候跟header一样加上Foot。当显示最后一个的时候就显示foot,并加载数据。

1下啦刷新时候,可以给listview加一个头,为了开始隐藏头就必须知道头的高度,调用setpadding方法,但是在定义控件时候不知道view的高度,手动调用header.measure()方法测量高度时候出现异常,因为还没有显示是无法测量的(个人认为,在看的较早的视频里发现过定义时候测量的)。我们可以在主程序加载后立即来用measure和setpadding,隐藏listview的头(本文是通过主程序获得后在控件定义中处理的,如果主程序中实现,则ontouchevent和OnScrollListener都得在主程序里实现)。其他的接口之类跟上一篇类似,就不多说了。同样的方法也可以实现:上划到底部加载更多的条目。

注意:方法中简单的设计了触摸移动,没有监听到如果开始1看不见,从顶部划到底部到1出现然后刷新,其中没有记下downY,因此最好的方法是给屏幕上设置3种状态:看不见1和最后一个item;看到1;看到最后一条的状态。一旦看到1就记下为DownY,若看到最后一条则为UpY,其后下啦刷新和上啦加载更多都分三种状态,以下啦为例:下啦、拉到大于一半释放刷新、拉到一定距离后上移。

2、其实每一个空间都是通过计算后才滑到屏幕上的,分别通过measure、onLayout()、ondraw三层,每个控件的大小都是由其父视图和本身决定的,这里不多说看下面几篇文章:http://blog.csdn.net/fengye810130/article/details/9181531;http://blog.csdn.net/guolin_blog/article/details/16330267;http://blog.csdn.net/cauchyweierstrass/article/details/41317247

下面是自定义的一个下拉刷新的操作:

3给出code

xml文件

<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.refresh.MainActivity$PlaceholderFragment" >

    <com.example.refresh.myListView.MyListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/mylist"
         />

</RelativeLayout>

  header的文件

<?xml version="1.0" encoding="utf-8"?>
<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" >

    <ProgressBar
        android:id="@+id/progressBar1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="3dp"
       	android:visibility="invisible"
        />

    <ImageView
        android:id="@+id/arrow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/common_listview_headview_red_arrow"
        android:layout_marginLeft="20dp"
		android:layout_marginTop="3dp"
        />

    <TextView
        android:id="@+id/tev1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
		android:layout_marginTop="15dp"
        android:text="下拉刷新"
        />
	<TextView
	    android:id="@+id/tev2"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"
	    android:layout_below="@id/tev1"
	    android:layout_centerHorizontal="true"

	    />
</RelativeLayout>

  3控件定义:

package com.example.refresh.myListView;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import com.example.refresh.R;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.rtp.RtpStream;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.ListView;
import  android.widget.AbsListView.OnScrollListener;
import android.widget.ProgressBar;
import android.widget.TextView;

public class MyListView extends ListView implements OnScrollListener
{
	private Context context;
	private final static int UP_MOVE=2;
	private final static int PREPARE_FLASHING=1;
	private final static int DOWN_MOVE=0;
	public View header;
	private int firstCellIndex;
	private int headHignt=100;
	private LoadDatasListener loadDatasListener;

	public void setOnloadDatasListener(LoadDatasListener l)
	{
		this.loadDatasListener=l;
	}

	public MyListView(Context context) {
		super(context);
		this.context=context;
		init();
	}

	public MyListView(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.context=context;
		init();
		}

	public MyListView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		this.context=context;
		init();
	}
	public void init()
	{
		addHeader();
//		int h=header.getHeight();//测量出现异常
//		System.out.println(h);
		setOnScrollListener(this);//监听滑动事件,时刻找到第一个显示的控件,即onScroll的第二个参数。

	}

	int downY=0;int currentY=0;int dis=0;//记住上一次的移动距离
	@Override
	public boolean onTouchEvent(MotionEvent ev) {

		if(firstCellIndex==0){
		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			downY=(int) ev.getY();
			ProgressBar bar2=(ProgressBar) header.findViewById(R.id.progressBar1);
			bar2.setVisibility(INVISIBLE);
			header.findViewById(R.id.arrow).setBackgroundResource(R.drawable.common_listview_headview_red_arrow);
			header.findViewById(R.id.arrow).setVisibility(VISIBLE);
			((TextView)header.findViewById(R.id.tev1)).setText("下啦刷新");
			break;

		case MotionEvent.ACTION_MOVE:
			currentY=(int) ev.getY();
			int dis2=currentY-downY;//pad值
			int dis3=currentY-downY;//实际dis
			if(dis2>=headHignt)
			{
				dis2=headHignt;
				((TextView)header.findViewById(R.id.tev1)).setText("释放刷新");
			}
//			header.setPadding(0, -headHignt+dis, 0, 0);
			if(dis3>=dis)
				header.findViewById(R.id.arrow).setBackgroundResource(R.drawable.common_listview_headview_red_arrow);
			if(dis3<dis)
			{//向上移动时
			header.findViewById(R.id.arrow).setBackgroundResource(R.drawable.up);
			}
			dis=dis3;

			header.setPadding(0, dis2-headHignt, 0, 0);
			break;

		case MotionEvent.ACTION_UP:

			Calendar c = Calendar.getInstance();
			int year = c.get(Calendar.YEAR);
			int month = c.get(Calendar.MONTH)+1;//月是从0开始的
			int date = c.get(Calendar.DATE);
			int hour = c.get(Calendar.HOUR_OF_DAY);
			int minute = c.get(Calendar.MINUTE);
			String time="上次刷新:"+year+"-"+month+"-"+date+" "+hour+":"+minute;
			TextView t=(TextView) header.findViewById(R.id.tev2);
			t.setText(time);
			ProgressBar bar=(ProgressBar) header.findViewById(R.id.progressBar1);
			bar.setVisibility(View.VISIBLE);
			header.findViewById(R.id.arrow).setVisibility(INVISIBLE);
			((TextView)header.findViewById(R.id.tev1)).setText("正在刷新");
			if(dis>headHignt/2)
			header.setPadding(0, 0, 0, 0);
			else
			{
				header.setPadding(0, -headHignt, 0, 0);
				 loadDatasListener.onloadData();
			}
				dis=0;
			break;

		default:
			break;
		}
		}
		return super.onTouchEvent(ev);
	}

	public void addHeader()
	{
		header=View.inflate(context, R.layout.header, null);
//		header.measure(0, 0);//		System.out.println(this.getMeasuredHeight());
		addHeaderView(header);

		header.setPadding(0, -headHignt, 0, 0);
	}

	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {

		firstCellIndex=firstVisibleItem;

	}

}

  4控件接口:

package com.example.refresh.myListView;

public interface LoadDatasListener {

	public void onloadData();

}

  5 activity文件

public class MainActivity extends Activity {

	private MyListView list;
	private ArrayList<String> newsdata;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        list=(MyListView) findViewById(R.id.mylist);
        init();
        list.setAdapter(new MyListAdapter());
        list.measure(0, 0);
//        list.header.getMeasuredHeight();
        System.out.println(list.header.getMeasuredHeight());

    }

    class MyListAdapter extends BaseAdapter
    {

		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return newsdata.size();
		}

		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return newsdata.get(position);
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			TextView view=null;
			ViewHolder holder=null;

			if(convertView!=null)
			{
				holder=(ViewHolder) convertView.getTag();
				view=holder.txview;
			}
			else {
				view=new TextView(MainActivity.this);
				holder=new ViewHolder();
				holder.txview=view;
				view.setTag(holder);
			}
			view.setText(newsdata.get(position));

			return view;
		}

    }
    static class  ViewHolder
    {
    	TextView txview;
    }

    public void init()
    {
    	newsdata=new ArrayList<String>();
    	for(int x=0;x<30;x++)
    		newsdata.add("新闻条目:"+x);

    }

}

  

时间: 2024-10-05 17:34:03

下拉刷新:继承listView控件的相关文章

Jquery+json绑定带层次下拉框(select控件)

一.实现的效果图 二.主要代码 html代码 <select id="pid" runat="server"> <option value="0" data="|0|">不选父级类</option> </select> Jquery代码 var html = ['<option value="0">不选父级模块</option>'];

Asp.net绑定带层次下拉框(select控件)

1.效果图 2.数据库中表数据结构 3.前台页面 <select id="pid" runat="server"> <option value="0" data="|0|">不选父级类</option> </select> 备注:查看源代码 4.后台代码 using System; using System.Data; using System.Web.UI.WebControl

Android---可以实现下拉刷新的ListView

1.效果 这个效果在很多App里都可以用到,基本上就已经泛滥了.这里就记录一下如何实现这一种效果.(截图没注意大小,丢帧也严重,所以看上去有点卡顿) 2.实现步骤 2.1布局文件 首先要明确的是,这一块也是一个布局文件,我们首先写出这个layout,代码比较简单,就不做说明了: pull_to_refesh.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=

Android 博客园客户端 (八) 下拉刷新、分页,AsyncTask

一直以来,无论是博客.新闻.还是推荐用户列表.只能加载固定的数量,也没有刷新功能. 为了实现这个功能,也试过很多第三方的开源控件,如PullToRefreshListVie等.无意中发现了Google官方发布了一个新的控件(SwipeRefreshLayout),支持下拉刷新,这个控件在Google应用中都有出现过.效果也是非常的不错. 具体的使用方法及代码如下: 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/r

Android做下拉刷新的时候,在做些什么

1. 简介 好长时间没有写博客了,一来是工作忙,抽不出空,二来是迷上了王者荣耀.现在正好赶上项目空闲期,写一篇关于下拉刷新的文章,个人觉得上来加载更多功能使用场景非常少,而且没有必要做的那么麻烦,文章最后会提一下加载更多的实现. 最近项目中遇见了下拉刷新的需求,正好研究了一下,分享一下自己的心得. 主要参考文章或工程: 郭霖大神-Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能 自个儿写Android的下拉刷新/上拉加载控件 XListView 这三篇文章各自提供了实现下拉刷新的思

SuperSwipeRefreshLayout 一个功能强大的自己定义下拉刷新组件

SuperSwipeRefreshLayout 一个功能强大的自己定义下拉刷新组件. Why? 下拉刷新这样的控件.想必大家用的太多了,比方使用非常多的XListView等. 近期.项目中非常多列表都是使用ReyclerView实现的.取代了原有的ListView,原有下拉刷新方式遭到挑战.本来Google推出的SwipeRefreshLayout已经能够满足大部分的需求了. 然而,因为其定制性较差.下拉刷新的样式无法改动.并且被嵌套的View也无法尾随手指的滑动而滑动.基于以上考虑,定制自己强

iOS学习之路--下拉刷新和上拉加载更多

iOS学习之路--下拉刷新和上拉加载更多 简介 本文中笔者将和大家分享应用app中常用到的表单内容的下拉刷新和上拉加载更多的功能实现的方法. 内容 1.有哪些实现方法与各方法的优劣 使用过美团,大众点评的朋友们应该有注意到,当你向上滑动表单的时候会有更多的店铺加载进你的表单中,而当你下滑表单顶的时候,则会刷新表单的内容并从网络上获取最新的信息.通过下拉刷新和上拉加载更多的功能,使app可以获取更多用户想要的信息和获取最新的信息.那么这种功能如何实现呢,还请跟着笔者继续往下看. 目前来说,主要的实

【好程序员笔记分享】——下拉刷新和上拉加载更多

-iOS培训,iOS学习-------型技术博客.期待与您交流!------------ iOS学习之路--下拉刷新和上拉加载更多 简介 本文中笔者将和大家分享应用app中常用到的表单内容的下拉刷新和上拉加载更多的功能实现的方法. 内容 1.有哪些实现方法与各方法的优劣 使用过美团,大众点评的朋友们应该有注意到,当你向上滑动表单的时候会有更多的店铺加载进你的表单中,而当你下滑表单顶的时候,则会刷新表单的内容 并从网络上获取最新的信息.通过下拉刷新和上拉加载更多的功能,使app可以获取更多用户想要

打造通用的Android下拉刷新组件(适用于ListView、GridView等各类View)

前言 最近在做项目时,使用了一个开源的下拉刷新ListView组件,极其的不稳定,bug还多.稳定的组件又写得太复杂了,jar包较大.在我的一篇博客中也讲述过下拉刷新的实现,即Android打造(ListView.GridView等)通用的下拉刷新.上拉自动加载的组件.但是这种通过修改Margin的形式感觉不是特别的流畅,因此在这漫长的国庆长假又花了点时间用另外的原理实现了一遍,特此分享出来. 基本原理 原理就是自定义一个ViewGroup,将Header View, Content View,