<?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"
android:gravity="center"
>
<ImageView
android:id="@+id/image_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/indicator_arrow"
/>
<ProgressBar
android:id="@+id/progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateDrawable="@mipmap/indicate_rotate"
android:visibility="invisible"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_toRightOf="@id/image_arrow"
>
<TextView
android:id="@+id/tv_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:text="下拉刷新"
/>
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginTop="20dp"
android:text="最后刷新2016-6-17"
/>
</LinearLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ProgressBar
android:id="@+id/itme1bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:indeterminateDrawable="@mipmap/indicate_rotate"
android:visibility="visible"
/>
<TextView
android:id="@+id/itme1textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ff00"
android:layout_marginLeft="30dp"
android:textStyle="bold"
android:textSize="25sp"
android:text="加载更多........"
/>
</LinearLayout>
package com.example.administrator.app4;
import android.content.Context;
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.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
/**
* Created by Administrator on 2016/6/17 0017.
* <p/>
* 自定义ListView,把布局加载到ListView中
*/
public class PullListView extends ListView {
private ImageView image_arrow;//箭头图片(顶部、底部)
private ProgressBar progressBar,itme1bar;//进度条(顶部)
private TextView tv_state, tv_time,itme1textview;//顶部显示的文字、底部
private int headerHeight;//添加的顶部布局高度
private View headerView;//添加的布局(View对象,顶部)
private View footerView;//底部布局
private boolean isComplete = false;//判断是否拖动到底部了
public PullListView(Context context) {
super(context);
init();
}
public PullListView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
initHeaderView();//初始化顶部View
initFooterView();//底部View
initAnimation();//动画的方法
this.setOnScrollListener(//ListrView添加滑动事件
new OnScrollListener() {
@Override//开始和结束拖地时会调用该方法
public void onScrollStateChanged(AbsListView view, int scrollState) {
//停止拖地 到底部
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE && isComplete) {
//加载更多的数据
footerView.setPadding(0, 0, 0, 0);
if (pullRefreshInterface != null) {
itme1textview.setText("正在加载更多......");
itme1bar.setVisibility(VISIBLE);//显示进度条
itme1bar.startAnimation(animationBar);//设置进度条启动动画
pullRefreshInterface.onMore();
}
}
}
@Override//拖地的过程中会调用该方法
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
isComplete = firstVisibleItem + visibleItemCount == totalItemCount;//到底了
}
}
);
}
private void initFooterView() {//底部布局View
LayoutInflater inflater = LayoutInflater.from(getContext());
footerView = inflater.inflate(R.layout.itme1, null);
itme1bar= (ProgressBar) footerView.findViewById(R.id.itme1bar);
itme1textview= (TextView) footerView.findViewById(R.id.itme1textview);//找到底部的控件
footerView.measure(0, 0);//强制执行该方法,测量控件大小
int footer_height = footerView.getMeasuredHeight();
//设置内边距(隐藏)
footerView.setPadding(0,-footer_height,0,0);
//把View对象添加到ListView的底部
this.addFooterView(footerView);
}
private void initHeaderView() {//顶部View
LayoutInflater inflater = LayoutInflater.from(getContext());
headerView = inflater.inflate(R.layout.itme, null);
image_arrow = (ImageView) headerView.findViewById(R.id.image_arrow);
progressBar = (ProgressBar) headerView.findViewById(R.id.progressbar);
tv_state = (TextView) headerView.findViewById(R.id.tv_state);
tv_time = (TextView) headerView.findViewById(R.id.tv_time);
//获取布局的高度
headerView.measure(0, 0);
headerHeight = headerView.getMeasuredHeight();
headerView.setPadding(0, -headerHeight, 0, 0);//设置内边距,不可见
this.addHeaderView(headerView);//把View对象加载到ListView的顶部
}
private float down_y;//点击的Y坐标
//定义表示ListView状态的常量
private final int PULLREFRESH = 0;//下拉刷新
private final int RELLRESH = 1;//松开刷新
private final int RELLRESHING = 2;//正在刷新
private int currentState = PULLREFRESH;//记录当前状态(初始化为下拉刷新)
private int paddingTop = 0;
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {//判断ListView的状态
case MotionEvent.ACTION_DOWN://按下状态
down_y = ev.getY();//获得按下的Y坐标(高度)
break;
case MotionEvent.ACTION_MOVE://移动状态
float y = ev.getY();
//往下拉(获得用户往下拉的距离,高度)
int length = (int) (y - down_y);
paddingTop = length - headerHeight;//往下拉的距离和顶部View的内边距
//正在刷新
if (currentState == RELLRESHING) {
break;
}
//大于顶部View的高度
if (paddingTop > -headerHeight && getFirstVisiblePosition() == 0) {
headerView.setPadding(0, paddingTop, 0, 0);//设置顶部的内边距
//下拉刷新
if (paddingTop >= 0 && currentState == PULLREFRESH) {//正在刷新
currentState = RELLRESH;//松开刷新
refreshState(); //松开刷新
} else if (paddingTop < 0 && currentState == RELLRESH) {
currentState = PULLREFRESH;//正在刷新
refreshState();//处理事件的方法
}
return true;//ListView不用处理滑动事件
}
break;
case MotionEvent.ACTION_UP://松开状态
if (currentState == PULLREFRESH) {//下拉刷新
headerView.setPadding(0, -headerHeight, 0, 0);
} else if (currentState == RELLRESH) {//松开刷新
currentState = RELLRESHING;//正在刷新
refreshState();
if (pullRefreshInterface!=null) {//接口对象不为空
pullRefreshInterface.onPull();//调用自己的方法
}
}
}
return super.onTouchEvent(ev);//不消费此次触屏事件
}
private PullRefreshInterface pullRefreshInterface;//接口对象
private RotateAnimation animationUp,animationDown,animationBar;//旋转的补间动画对象
public void setPullRefreshInterface(PullRefreshInterface pullRefreshInterface) {
this.pullRefreshInterface = pullRefreshInterface;
}
public interface PullRefreshInterface {//回调的接口
public void onPull();
public void onMore();
}
private void refreshState() {//修改界面的显示
switch (currentState) {//当前状态
case PULLREFRESH://下拉刷新
tv_state.setText("下拉刷新");
//图片控件开始执行动画
image_arrow.startAnimation(animationDown);
break;
case RELLRESH://松开刷新
tv_state.setText("松开刷新");
image_arrow.startAnimation(animationUp);
break;
case RELLRESHING://正在刷新
tv_state.setText("正在刷新");
headerView.setPadding(0, 0, 0, 0);//设置内边距(完全显示)
//动画取消、箭头消失
image_arrow.clearAnimation();//取消动画
image_arrow.setVisibility(INVISIBLE);//隐藏控件
//进度条显示
progressBar.setVisibility(VISIBLE);
progressBar.startAnimation(animationBar);//启动动画
progressBar.setIndeterminate(true);
break;
}
}
public void initAnimation(){
//创建旋转动画
animationUp=new RotateAnimation(0,-180,
RotateAnimation.RELATIVE_TO_SELF,0.5f,
Animation.RELATIVE_TO_SELF,0.5f);
animationUp.setDuration(1000);
animationUp.setFillAfter(true);
animationDown=new RotateAnimation(-180,-360,
RotateAnimation.RELATIVE_TO_SELF,0.5f,
RotateAnimation.RELATIVE_TO_SELF,0.5f);
animationDown.setDuration(1000);
animationDown.setFillAfter(true);
//进度条的旋转
animationBar=new RotateAnimation(
0,360,RotateAnimation.RELATIVE_TO_PARENT,0.5f,
RotateAnimation.RELATIVE_TO_SELF,0.5f);
animationBar.setDuration(1000);
animationBar.setFillAfter(true);
animationBar.setRepeatCount(Animation.INFINITE);//无限循环
}
public void complete(boolean isPull){
if(isPull){
currentState=PULLREFRESH;//下拉刷新
tv_state.setText("下拉刷新");
tv_time.setText("2016-6-18");
progressBar.clearAnimation();//取消动画
progressBar.setVisibility(INVISIBLE);//进度条隐藏
headerView.setPadding(0,-headerHeight,0,0);//隐藏顶部View
}else{//隐藏底部View
itme1textview.setText("加载更多.......");
itme1bar.clearAnimation();//取消动画
itme1bar.setVisibility(INVISIBLE);//隐藏进度条
footerView.setPadding(0, -footerView.getMeasuredHeight(),0,0);
}
}
}
在主UI的XML文件中使用自定义的ListView
<pre name="code" class="html"><?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"
tools:context="com.example.administrator.app4.MainActivity">
<com.example.administrator.app4.PullListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
package com.example.administrator.app4;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.widget.ArrayAdapter;
import java.util.ArrayList;
import java.util.List;
/**
* 下拉刷新上拉加载
* 自定义的ListView
*/
public class MainActivity extends AppCompatActivity {
private PullListView listView;//自定义的ListView
private List<String> strs;//适配器需要的数据
private ArrayAdapter adapter;//适配器
private int connt1=1,connt2=1;
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
int what=msg.what;//获取发送过来的空消息
if(what==1){
//下拉刷新完成(添加到集合里面,最上面)
strs.add(0, "第"+connt1+"次下拉刷新的新数据哦!");
adapter.notifyDataSetChanged();//提醒控件更新显示
connt1++;
//下拉刷新需要改变状态
listView.complete(true);
}else if(what==2){
//加载更多数据(底部的View)
for(int i=0;i<10;i++){
strs.add("第"+connt2+"次,加载更多的数据"+(i+1)+"号");
}
connt2++;//自增
adapter.notifyDataSetChanged();//通知更新
listView.complete(false);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView= (PullListView) findViewById(R.id.listview);
init();
adapter=new ArrayAdapter(this,android.R.layout.simple_list_item_1,strs);
listView.setAdapter(adapter);//设置适配器
setOnList();//设置监听
}
private void setOnList() {
listView.setPullRefreshInterface(//回调ListView里面的接口
new PullListView.PullRefreshInterface() {
@Override
public void onPull() {
//执行具体的操作
new Thread(){//创建子线程
@Override
public void run() {
try {
Thread.sleep(3000);//线程休眠
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.sendEmptyMessage(1);//发送空消息回主线程(增加上面的内容)
}
}.start();//启动线程
}
@Override
public void onMore() {
new Thread(){//创建线程
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.sendEmptyMessage(2);//发送空消息(增加下面的内容)
}
}.start();//开启线程
}
}
);
}
private void init() {//初始化集合
strs=new ArrayList<String>();
for(int i=0;i<30;i++){
strs.add("List原来的第"+(i+1)+"条数据");
}
}
}