搞了好几天,各种bug,现在终于搞定了!!赶紧开一篇blog,废话不说了 上代码记录一下,方便以后查看~~
MainActivity代码:
package com.example.lenovo.pulltorefreshlistview;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.google.gson.Gson;
import org.xutils.common.Callback;
import org.xutils.http.RequestParams;
import org.xutils.x;
import java.util.ArrayList;
import java.util.List;
import Adapter.MyBaseAdapter;
import Adapter.MyViewPagerAdapter;
import Bean.NewsBean;
public class MainActivity extends Activity {
private PullToRefreshListView listView;
private ViewPager viewPager;
private LinearLayout linearLayout;
private ImageView[] points;
private String jsonStr = "http://www.imooc.com/api/teacher?type=4&num=30";
private List<NewsBean.DataBean> listData = new ArrayList<>();
private String[] imagesUrl = {
"http://bbs.uc.cn/data/attachment/forum/201302/17/163510xsv14x35i9ix41i0.jpg",
"http://p3.so.qhimg.com/t0121ddd5bc66dcc9e8.jpg",
"http://p3.so.qhimg.com/t0181e8d7355386f79d.jpg",
"http://bbs.liebao.cn/data/attachment/forum/201210/25/182447qee2e922myyw8y8m.jpg"};
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
handler.sendEmptyMessageDelayed(1, 3000);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initPoint();
viewPager.setCurrentItem(Integer.MAX_VALUE / 2);
handler.sendEmptyMessageDelayed(1, 3000);
viewPager.setAdapter(new MyViewPagerAdapter(this, imagesUrl));
requestNet();
//viewpager页面滑动监听
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
for (int i = 0; i < points.length; i++) {
if (position % imagesUrl.length == i) {
points[i].setImageResource(R.drawable.point_focus);
} else {
points[i].setImageResource(R.drawable.point_noraml);
}
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
listView.setOnRefreshListener(new PullToRefreshListView.onRefreshListener() {
@Override
public void onRefresh() {
//请求服务器获取数据
}
@Override
public void onLandmore() {
//请求服务器获取数据
}
});
//listview中item的点事件
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//listview真正的position
position = position-listView.getHeaderViewsCount();
Toast.makeText(MainActivity.this, "当前位置:"+position, Toast.LENGTH_SHORT).show();
}
});
}
/**
* 模拟请求服务器数据
*/
private void requestNet() {
RequestParams params = new RequestParams(jsonStr);
x.http().get(params, new Callback.CommonCallback<String>() {
@Override
public void onSuccess(String s) {
NewsBean news = new Gson().fromJson(s,NewsBean.class);
listData.addAll(news.getData());
//一请求完数据就更新UI
listView.setAdapter(new MyBaseAdapter(MainActivity.this,listData));
}
@Override
public void onError(Throwable throwable, boolean b) {
}
@Override
public void onCancelled(CancelledException e) {
}
@Override
public void onFinished() {
}
});
}
/**
* 初始化小圆点
*/
private void initPoint() {
points = new ImageView[imagesUrl.length];
for(int i=0;i<points.length;i++){
points[i] = (ImageView) linearLayout.getChildAt(i);
}
points[0].setImageResource(R.drawable.point_focus);
}
private void initView() {
listView = (PullToRefreshListView) findViewById(R.id.listview);
View view = View.inflate(this,R.layout.headerview,null);
linearLayout = (LinearLayout) view.findViewById(R.id.linearlayout);
viewPager = (ViewPager) view.findViewById(R.id.viewpager);
listView.addHeaderView(view);
}
}
ListView的数据Adapter代码:
package Adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.lenovo.pulltorefreshlistview.R;
import org.xutils.x;
import java.util.List;
import Bean.NewsBean;
/**
* Created by shan on 2016/6/28.
*/
public class MyBaseAdapter extends BaseAdapter {
private Context context;
private List<NewsBean.DataBean> listData;
public MyBaseAdapter(Context context, List<NewsBean.DataBean> listData) {
this.context = context;
this.listData = listData;
}
@Override
public int getCount() {
return listData.size();
}
@Override
public Object getItem(int position) {
return listData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView==null){
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.news_item,parent,false);
holder.news_icon = (ImageView) convertView.findViewById(R.id.news_icon);
holder.news_title = (TextView) convertView.findViewById(R.id.news_title);
holder.news_description = (TextView) convertView.findViewById(R.id.news_description);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
x.image().bind(holder.news_icon,listData.get(position).getPicBig());
holder.news_title.setText(listData.get(position).getName());
holder.news_description.setText(listData.get(position).getDescription());
return convertView;
}
private class ViewHolder{
private ImageView news_icon;
private TextView news_title,news_description;
}
}
ViewPager的数据Adapter代码:
package Adapter;
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import org.xutils.x;
import Utils.ToastUtil;
/**
* Created by shan on 2016/6/28.
*/
public class MyViewPagerAdapter extends PagerAdapter {
private Context context;
private String[] imagesUrl;
public MyViewPagerAdapter(Context context, String[] imagesUrl) {
this.context = context;
this.imagesUrl = imagesUrl;
}
@Override
public int getCount() {
return Integer.MAX_VALUE;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
@Override
public Object instantiateItem(ViewGroup container, final int position) {
ImageView view = new ImageView(context);
view.setScaleType(ImageView.ScaleType.CENTER_CROP);
container.addView(view);
//轮播图中图片的监听
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switch(position%imagesUrl.length){
case 0:
ToastUtil.showShort(context,"点击了图片1");
break;
case 1:
ToastUtil.showShort(context,"点击了图片2");
break;
case 2:
ToastUtil.showShort(context,"点击了图片3");
break;
case 3:
ToastUtil.showShort(context,"点击了图片4");
break;
}
}
});
x.image().bind(view,imagesUrl[position%imagesUrl.length]);
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
ListView的新闻列表item样式代码:
<?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="8dp"
android:paddingBottom="8dp"
android:paddingRight="10dp">
<ImageView
android:id="@+id/news_icon"
android:layout_width="100dp"
android:layout_height="70dp"
android:scaleType="centerCrop"
android:layout_marginLeft="10dp"
android:src="@drawable/ic_launcher"/>
<TextView
android:id="@+id/news_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="新闻标题"
android:maxLines="1"
android:textSize="16sp"
android:layout_marginLeft="5dp"
android:textColor="#000"
android:layout_toRightOf="@+id/news_icon"/>
<TextView
android:id="@+id/news_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/news_icon"
android:layout_below="@+id/news_title"
android:layout_alignLeft="@+id/news_title"
android:layout_marginTop="3dp"
android:maxLines="2"
android:text="新闻内容介绍"/>
</RelativeLayout>
ListView的HeaderView(ViewPager+圆点)的xml代码:
<?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.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="150dp">
</android.support.v4.view.ViewPager>
<LinearLayout
android:id="@+id/linearlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_horizontal"
android:layout_marginTop="130dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/point_noraml"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:background="@drawable/point_noraml"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:background="@drawable/point_noraml"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:background="@drawable/point_noraml"/>
</LinearLayout>
</RelativeLayout>
接下来是刷新头view和加载脚view的xml代码:
刷新头xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pull_to_refresh_header"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:gravity="center_horizontal">
<RelativeLayout
android:id="@+id/refresh_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ProgressBar
android:id="@+id/pulldown_progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateDrawable="@drawable/custom_progressbar"
android:visibility="invisible"/>
<ImageView
android:id="@+id/arrow_down"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/arrow"
android:layout_centerInParent="true"
android:visibility="visible" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_centerInParent="true"
android:layout_toRightOf="@+id/refresh_progress">
<TextView
android:id="@+id/pulldown_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="下拉刷新"
android:textColor="#969696"
android:textSize="16sp" />
<TextView
android:id="@+id/pulldown_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="最近更新:12:00"
android:layout_below="@+id/pulldown_text"/>
</RelativeLayout>
</RelativeLayout>
</LinearLayout>
加载脚view代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pull_to_refresh_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateDrawable="@drawable/custom_progressbar"
android:visibility="visible"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="正在加载..."
android:layout_marginLeft="15dp"
android:textColor="#969696"
android:textSize="16sp" />
</LinearLayout>
说明一下:这里用的自定义的Progressbar,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%">
<shape
android:shape="ring"
android:useLevel="false"
android:innerRadius="10dp"
android:thickness="3dp">
<!--sweep横扫而过的方式-->
<gradient android:startColor="#fff"
android:endColor="#00ffff"
android:centerColor="#9f00"
android:type="sweep"></gradient>
</shape>
</rotate>
引用方式:android:indeterminateDrawable=”@drawable/custom_progressbar
最后,PullToRefreshListView:
package com.example.lenovo.pulltorefreshlistview;
import android.content.Context;
import android.util.AttributeSet;
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;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Created by shan on 2016/6/26.
*
* 下拉刷新的listview
*/
public class PullToRefreshListView extends ListView implements AbsListView.OnScrollListener{
private static final int STATE_PULL_TO_REFRESH = 1;
private static final int STATE_RELEASE_TO_REFRESH = 2;
private static final int STATE_REFRESHING = 3;
private int mCurrentState = STATE_PULL_TO_REFRESH;//当前状态
//下拉刷新的头view
private View headerview;
private int headerviewHeight;//下拉刷新view的高度
private int startY = -1;//起始Y坐标
private int endY;//终点坐标
//下拉刷新布局中的子view
private TextView pulldown_text;
private TextView pulldown_time;
private ImageView arrow_down;
private ProgressBar pulldown_progressbar;
private RotateAnimation animUp; //向上的箭头
private RotateAnimation animDown;//向下的箭头
//上拉加载更多的脚view
private View footerview;
private int footerviewHeight;//下拉刷新view的高度
//上拉加载布局中的子view
public PullToRefreshListView(Context context) {
super(context);
initHeaderView();
initFooterView();
}
public PullToRefreshListView(Context context, AttributeSet attrs) {
super(context, attrs);
initHeaderView();
initFooterView();
}
public PullToRefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initHeaderView();
initFooterView();
}
public PullToRefreshListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initHeaderView();
initFooterView();
}
/**
* 初始化头布局
*/
private void initHeaderView(){
headerview = View.inflate(getContext(), R.layout.refresh_header, null);
this.addHeaderView(headerview);
pulldown_text = (TextView) headerview.findViewById(R.id.pulldown_text);
pulldown_time = (TextView) headerview.findViewById(R.id.pulldown_time);
arrow_down = (ImageView) headerview.findViewById(R.id.arrow_down);
pulldown_progressbar = (ProgressBar) headerview.findViewById(R.id.pulldown_progressbar);
//隐藏下拉刷新布局
headerview.measure(0, 0);
//获得下拉刷新view的高度
headerviewHeight = headerview.getMeasuredHeight();
//隐藏下拉刷新view
headerview.setPadding(0, -headerviewHeight, 0, 0);
//初始化箭头的动画
initAnimation();
setCurrentTime();
}
/**
* 初始化脚view
*/
private void initFooterView(){
footerview = View.inflate(getContext(), R.layout.refresh_footer, null);
this.addFooterView(footerview);
footerviewHeight = getMeasuredHeight();
footerview.measure(0, 0);
footerview.setPadding(0, -footerviewHeight, 0, 0);
this.setOnScrollListener(this);//滑动监听
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch(ev.getAction()){
case MotionEvent.ACTION_DOWN:
startY = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
//当用户按住viewpager进行下拉时,ACTION_DOWN会被viewpager消费掉,导致startY没有赋值,
// 此处需要重新获取一下
if(startY == -1){
startY = (int) ev.getY();
}
if(mCurrentState==STATE_REFRESHING){
//如果是正在刷新,跳出循环
break;
}
endY = (int) ev.getY();
//计算滑动【偏移量
int dy = endY - startY;
int firstVisiblePositin = getFirstVisiblePosition();//当前显示的第一个item的位置
//如果当前显示的位置是ListView的第一项并且偏移量>0 再执行下拉操作
if(dy>0&&firstVisiblePositin==0){
//计算下拉刷新view被拉下来的高度
int padding = dy-headerviewHeight;
headerview.setPadding(0,padding,0,0);
if(padding>0&&mCurrentState!=STATE_RELEASE_TO_REFRESH){
//改为松开刷新
mCurrentState = STATE_RELEASE_TO_REFRESH;
refreshState();
}else if(padding<0&&mCurrentState!=STATE_PULL_TO_REFRESH){
//改为下拉刷新
mCurrentState = STATE_PULL_TO_REFRESH;
refreshState();
}
super.onTouchEvent(ev);
return true;
}
break;
case MotionEvent.ACTION_UP:
startY = -1;
if(mCurrentState==STATE_RELEASE_TO_REFRESH){
mCurrentState = STATE_REFRESHING;
refreshState();
//完整展示头view
headerview.setPadding(0, 0, 0, 0);
//4.进行回调
if(mListener!=null){
mListener.onRefresh();
}
}else if(mCurrentState==STATE_PULL_TO_REFRESH){
headerview.setPadding(0,-headerviewHeight,0,0);
}
break;
}
return super.onTouchEvent(ev);
}
/**
* 根据当前状态刷新界面
*/
private void refreshState() {
switch(mCurrentState){
case STATE_PULL_TO_REFRESH:
pulldown_text.setText("下拉刷新");
pulldown_progressbar.setVisibility(View.INVISIBLE);
arrow_down.setVisibility(View.VISIBLE);
arrow_down.startAnimation(animDown);
break;
case STATE_RELEASE_TO_REFRESH:
pulldown_text.setText("释放立即刷新");
pulldown_progressbar.setVisibility(View.INVISIBLE);
arrow_down.setVisibility(View.VISIBLE);
arrow_down.startAnimation(animUp);
break;
case STATE_REFRESHING:
pulldown_text.setText("正在刷新...");
arrow_down.clearAnimation();//清除箭头动画,否则无法隐藏
pulldown_progressbar.setVisibility(View.VISIBLE);
arrow_down.setVisibility(View.INVISIBLE);
break;
}
}
/**
* 设置刷新当前时间
*/
private void setCurrentTime(){
SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm");
String time = format.format(new Date());
pulldown_time.setText("上次更新:"+time);
}
/**
* 初始化箭头动画
*/
private void initAnimation(){
animUp = new RotateAnimation(0,-180,
Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
animUp.setDuration(200);
animUp.setFillAfter(true);
animDown = new RotateAnimation(-180,0,
Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
animDown.setDuration(200);
animDown.setFillAfter(true);
}
/**
* 刷新完毕,收起刷新view,在网络请求结束刷新完毕后调用该方法,复原状态
*
* 即使网络请求失败导致刷新失败,也要执行此步骤,以便再刷新
*
*
*/
public void onRefreshComplete(boolean success){
if(!isLoadingMore){
headerview.setPadding(0,-headerviewHeight,0,0);
mCurrentState = STATE_PULL_TO_REFRESH;
pulldown_text.setText("下拉刷新");
pulldown_progressbar.setVisibility(View.INVISIBLE);
arrow_down.setVisibility(View.VISIBLE);
//刷新success了再更新上次刷新时间,刷新失败的话,不需要更新本次刷新时间
if(success){
setCurrentTime();
}
}else{
//加载更多
footerview.setPadding(0,-footerviewHeight,0,0);//隐藏脚view
isLoadingMore = false;
}
}
public onRefreshListener mListener;//3.定义成员变量,接收监听对象
/**
* 2.暴露接口,设置监听
*/
public void setOnRefreshListener(onRefreshListener listener){
mListener = listener;
}
private boolean isLoadingMore;//标记是否正在加载动作
/**
* 滑动状态发生变化
*/
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(scrollState==SCROLL_STATE_IDLE){//空闲状态
int lastVisiblePositin = getLastVisiblePosition();
//表示滑到底,而且没有正在加载更多
if(lastVisiblePositin==getCount()-1&&!isLoadingMore){
isLoadingMore = true;
footerview.setPadding(0,0,0,0);//到底了,显示脚view
setSelection(getCount()-1);//将footerview显示在最后的一个位置上
//通知主界面加载下一页
if(mListener!=null){
mListener.onLandmore();
}
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
/**
* 1.下拉刷新 上拉加载回调接口
*/
public interface onRefreshListener{
public void onRefresh();
public void onLandmore();
}
}
时间: 2024-10-29 00:11:04