页签页面修改
添加pager_tab_detail.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="@+id/vp_table_detail"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<ListView
android:id="@+id/lv_table_detail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="50dp"
/>
</LinearLayout>
/**
* 12个页签的页面对象TabDetailPager
* @author Administrator
*
*/
public class TabDetailPager extends BaseMenuDetailPager {
private NewsTabData mTableData;
@ViewInject(R.id.lv_table_detail)
private ListView lvList;
@ViewInject(R.id.vp_table_detail)
private ViewPager mViewPager;
private String mUrl;
private NewsData mNewsTabData;
private ArrayList<TopNews> mTopNewsList;
private TopNewAdapter mTopNewAdapter;
private View view;
public TabDetailPager(Activity activity,NewsTabData tabData) {
super(activity);
mTableData=tabData;
mUrl=Constants.SERVER_URL+tabData.url;
}
@Override
public View initView() {
view = View.inflate(mActivity, R.layout.pager_tab_detail, null);
ViewUtils.inject(this,view);
return view;
}
@Override
public void initData() {
String cache = CacheUtils.getCache(mUrl, mActivity);
if(!TextUtils.isEmpty(cache)){
processResult(cache);
}
getDataFromServer();
}
private void getDataFromServer(){
HttpUtils utils=new HttpUtils();
utils.send(HttpMethod.GET, mUrl, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
String result = responseInfo.result;
System.out.println(result);
processResult(result);
CacheUtils.setCache(mUrl, result, mActivity);
}
@Override
public void onFailure(HttpException error, String msg) {
System.err.println(error+"msg"+msg);
}
});
}
protected void processResult(String result) {
Gson gson=new Gson();
mNewsTabData = gson.fromJson(result, NewsData.class);
mTopNewsList = mNewsTabData.data.topnews;
//初始化头条新闻
if(mTopNewsList!=null){
mTopNewAdapter = new TopNewAdapter();
mViewPager.setAdapter(mTopNewAdapter);
}
System.out.println(mNewsTabData);
}
class TopNewAdapter extends PagerAdapter{
BitmapUtils mBitmapUtils;
public TopNewAdapter(){
mBitmapUtils=new BitmapUtils(mActivity);
}
@Override
public int getCount() {
return mTopNewsList.size();
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0==arg1;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView view=new ImageView(mActivity);
//view.setScaleType(ScaleType.FIT_XY);//设置图片填充效果,表示填充父窗口
//获取图片链接,使用链接下载图片,将图片设置为ImageView,考虑内存溢出问题
mBitmapUtils.display(view, mTopNewsList.get(position).topimage);
container.addView(view);
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
}
}
效果
页签面页划动冲突解决,自定义ViewPage
public class HorizontalScrollViewPager extends ViewPager {
private int startX;
private int startY;
private int endX;
private int endY;
public HorizontalScrollViewPager(Context context) {
super(context);
}
public HorizontalScrollViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 3种情况需要父控件拦截事件
* 1.上下划动需要拦截
* 2.向右划第一个页面,需要拦截
* 3.向左划最后一个页面,需要拦截
*/
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
// 请求父控件及祖宗控件不要拦截当前控件的事件
getParent().requestDisallowInterceptTouchEvent(true);
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = (int) ev.getX();
startY = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
endX = (int) ev.getX();
endY = (int) ev.getY();
int dx=endX-startX;
int dy=endY-startY;
if(Math.abs(dx)-Math.abs(dy)>0){//左右滑动
if(dx>0&&this.getCurrentItem()==0){//向右划动第一个页面
// 请求父控件及祖宗控件不要拦截当前控件的事件
getParent().requestDisallowInterceptTouchEvent(false);
}else if(dx<0&&this.getCurrentItem()==getAdapter().getCount()-1){//向左划动最后一个页面
getParent().requestDisallowInterceptTouchEvent(false);
}
}else
getParent().requestDisallowInterceptTouchEvent(false);
break;
default:
break;
}
// 请求父控件及祖控件不要拦截事件
return super.dispatchTouchEvent(ev);
}
}
添加图片标题栏
使用ViewPagerIndicatorLibrary框架中的
自定义控件com.viewpagerindicator.CirclePageIndicator
页签xml文件 pager_tab_detail.xml修改为
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000"
android:orientation="vertical" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="180dp">
<com.example.zhsh.view.HorizontalScrollViewPager
android:id="@+id/vp_table_detail"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:layout_gravity="bottom"
android:background="#a000"
>
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标题"
android:textColor="#fff"
android:textSize="18sp"
/>
<com.viewpagerindicator.CirclePageIndicator
android:id="@+id/indicator"
android:padding="10dip"
android:layout_alignParentRight="true"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
app:radius="3dp"
app:fillColor="#f00"
app:pageColor="#9e9e9e"
app:strokeWidth="0dp"
/>
</RelativeLayout>
</FrameLayout>
<ListView
android:id="@+id/lv_table_detail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="50dp"
/>
</LinearLayout>
页签java类 TabDetailPager
添加
效果
页签页面Listview
list_refresh_header.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingTop="10dp"
android:paddingRight="10dp"
>
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="@drawable/common_listview_headview_red_arrow"
/>
<ProgressBar
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:indeterminateDrawable="@drawable/custom_progress"
/>
</FrameLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="下拉刷新"
android:textColor="#f00"
android:textSize="17sp"
/>
<TextView
android:id="@+id/tv_time"
android:textColor="#9e9e9e"
android:textSize="15sp"
android:layout_marginTop="5dp"
android:text="2016-07-08 14:35"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
pager_tab_detail.xml修改为
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/lv_table_detail"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
TabDetailPaper类 修改部分颜色为灰色背景
/**
* 12个页签的页面对象
* @author Administrator
*
*/
public class TabDetailPager extends BaseMenuDetailPager {
private NewsTabData mTableData;
@ViewInject(R.id.lv_table_detail)
private ListView lvList;
@ViewInject(R.id.vp_table_detail)
private HorizontalScrollViewPager mViewPager;
@ViewInject(R.id.indicator)
private CirclePageIndicator mIndicator;
@ViewInject(R.id.tv_title)
private TextView tvTopNewsTitle;
private String mUrl;
private NewsData mNewsTabData;
private ArrayList<TopNews> mTopNewsList;
private TopNewAdapter mTopNewAdapter;
private View view;
private View header;
private ArrayList<News> mNewsList;
public TabDetailPager(Activity activity,NewsTabData tabData) {
super(activity);
mTableData=tabData;
mUrl=Constants.SERVER_URL+tabData.url;
}
@Override
public View initView() {
view = View.inflate(mActivity, R.layout.pager_tab_detail, null);
ViewUtils.inject(this,view);
header = View.inflate(mActivity, R.layout.list_header_topnews, null);
ViewUtils.inject(this,header);//必须也将布局注入到ViewUtils
lvList.addHeaderView(header);
return view;
}
@Override
public void initData() {
String cache = CacheUtils.getCache(mUrl, mActivity);
if(!TextUtils.isEmpty(cache)){
processResult(cache);
}
getDataFromServer();
}
private void getDataFromServer(){
HttpUtils utils=new HttpUtils();
utils.send(HttpMethod.GET, mUrl, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
String result = responseInfo.result;
System.out.println(result);
processResult(result);
CacheUtils.setCache(mUrl, result, mActivity);
}
@Override
public void onFailure(HttpException error, String msg) {
System.err.println(error+"msg"+msg);
}
});
}
protected void processResult(String result) {
Gson gson=new Gson();
mNewsTabData = gson.fromJson(result, NewsData.class);
mTopNewsList = mNewsTabData.data.topnews;
//初始化头条新闻
if(mTopNewsList!=null){
mTopNewAdapter = new TopNewAdapter();
mViewPager.setAdapter(mTopNewAdapter);
mIndicator.setViewPager(mViewPager);
mIndicator.setSnap(true);//快照模式
mIndicator.setCurrentItem(0);
tvTopNewsTitle.setText(mTopNewsList.get(0).title);
mIndicator.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
tvTopNewsTitle.setText(mTopNewsList.get(arg0).title);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
mIndicator.onPageSelected(0);//将小圆点位置归零,否则它会在页面销毁时仍记录上次位置的bug
}
mNewsList = mNewsTabData.data.news;
if(mNewsList!=null){
NewAdapter mNewAdapter=new NewAdapter();
lvList.setAdapter(mNewAdapter);
}
System.out.println(mNewsTabData);
}
class TopNewAdapter extends PagerAdapter{
BitmapUtils mBitmapUtils;
public TopNewAdapter(){
mBitmapUtils=new BitmapUtils(mActivity);
}
@Override
public int getCount() {
return mTopNewsList.size();
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0==arg1;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView view=new ImageView(mActivity);
view.setScaleType(ScaleType.FIT_XY);//设置图片填充效果,表示填充父窗口
//获取图片链接,使用链接下载图片,将图片设置为ImageView,考虑内存溢出问题
mBitmapUtils.display(view, mTopNewsList.get(position).topimage);
container.addView(view);
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
}
class NewAdapter extends BaseAdapter{
public BitmapUtils mBitmapUtils;
public NewAdapter(){
mBitmapUtils = new BitmapUtils(mActivity);
mBitmapUtils.configDefaultLoadFailedImage(R.drawable.pic_item_list_default);
}
@Override
public int getCount() {
return mNewsList.size();
}
@Override
public News getItem(int arg0) {
return mNewsList.get(arg0);
}
@Override
public long getItemId(int arg0) {
return arg0;
}
@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
ViewHolde holder;
if(arg1==null){
arg1=View.inflate(mActivity, R.layout.list_item_news, null);
holder=new ViewHolde();
holder.tvTitle=(TextView) arg1.findViewById(R.id.tv_title);
holder.tvDate=(TextView) arg1.findViewById(R.id.tv_date);
holder.ivIcon=(ImageView) arg1.findViewById(R.id.iv_icon);
arg1.setTag(holder);
}else{
holder=(ViewHolde) arg1.getTag();
}
News news= getItem(arg0);
holder.tvTitle.setText(news.title);
holder.tvDate.setText(news.pubdate);
mBitmapUtils.display(holder.ivIcon, news.listimage);
return arg1;
}
}
static class ViewHolde{
public TextView tvTitle;
public TextView tvDate;
public ImageView ivIcon;
}
}
效果
自定义下拉刷新页面
RefreshListView
public class RefreshListView extends ListView {
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 View mHeaderView ;
private int mHeaderViewHeight;
private int startY;
private int endY;
private int mCurrentState=STATE_PULL_TO_REFRESH;//默认是下拉刷新
private TextView tvTitle;
private ImageView ivArrow;
private ProgressBar pbLoading;
private RotateAnimation animDown;
private RotateAnimation animUp;
public RefreshListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView();
}
public RefreshListView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public RefreshListView(Context context) {
super(context);
initView();
}
private void initView(){
mHeaderView = View.inflate(getContext(), R.layout.list_refresh_header, null);
this.addHeaderView(mHeaderView);//添加布局
//隐藏布局(1.获取头布局高度,2.设置负paddingTop,布局就会往上走)
int height=mHeaderView.getHeight();//为0 此处无法获取高度,因为布局还没有绘制完成
//绘制之前就要获取布局高度
mHeaderView.measure(0, 0);//手动测量布局
mHeaderViewHeight = mHeaderView.getMeasuredHeight();
mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);
tvTitle = (TextView) findViewById(R.id.tv_title);
ivArrow = (ImageView) mHeaderView.findViewById(R.id.iv_arrow);
pbLoading = (ProgressBar) mHeaderView.findViewById(R.id.pb_loading);
tvTime = (TextView) findViewById(R.id.tv_time);
initAnim();
setCurrentTime();
}
/**
* 初始化箭头动画
*/
private void initAnim(){
animUp = new RotateAnimation(0,-180,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
animUp.setDuration(500);
animUp.setFillAfter(true);//保持状态
animDown = new RotateAnimation(-180,0,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
animDown.setDuration(500);
animDown.setFillAfter(true);//保持状态
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
startY = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
if(startY==-1){//如果用户按住头条新闻向下滑动,会导致listview无法拿到ACTIVITY_DOWN,此时呀重新获取startY
startY=(int) ev.getY();
}
//如果当前正在刷新,什么都不做了
if(mCurrentState==STATE_REFRESHING){
break;
}
endY = (int) ev.getY();
int dy=endY-startY;
if(dy>0&&getFirstVisiblePosition()==0){//向下滑动&&当前显示的第一个item,才允许下拉刷新出来
int paddingTop=dy-mHeaderViewHeight;//计算当前paddingTop值
System.out.println(paddingTop+"===="+mHeaderViewHeight);
if(paddingTop>=0&&mCurrentState!=STATE_RELEASE_TO_REFRESH){//切换到松开刷新
mCurrentState=STATE_RELEASE_TO_REFRESH;
refreshState();
}else if(paddingTop<0&&mCurrentState!=STATE_PULL_TO_REFRESH){//切换到下拉刷新
mCurrentState=STATE_PULL_TO_REFRESH;
refreshState();
}
mHeaderView.setPadding(0, paddingTop, 0, 0);//重新设置头布局padding
return true;
}
break;
case MotionEvent.ACTION_UP:
startY=-1;//起始坐标归零
if(mCurrentState==STATE_RELEASE_TO_REFRESH){
//如果当前是松开刷新,就要切换到正在刷新
mCurrentState=STATE_REFRESHING;
refreshState();
//显示头布局
mHeaderView.setPadding(0, 0, 0, 0);
}else if(mCurrentState==STATE_REFRESHING){
//隐藏头布局
mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);
}
break;
default:
break;
}
return super.onTouchEvent(ev);
}
/**
* 根据当前状态刷新界面
*/
private void refreshState(){
switch (mCurrentState) {
case STATE_PULL_TO_REFRESH:
tvTitle.setText("下拉刷新");
ivArrow.startAnimation(animDown);
pbLoading.setVisibility(View.INVISIBLE);
break;
case STATE_RELEASE_TO_REFRESH:
tvTitle.setText("松开刷新");
ivArrow.startAnimation(animUp);
pbLoading.setVisibility(View.INVISIBLE);
//下拉刷新毁掉
if(mListener!=null){
mListener.onRefresh();
}
break;
case STATE_REFRESHING:
tvTitle.setText("正在刷新...");
pbLoading.setVisibility(View.VISIBLE);
ivArrow.clearAnimation();//必须清除动画才能隐藏
ivArrow.setVisibility(View.INVISIBLE);
break;
default:
break;
}
}
/**
* 设置上次刷新时间
*/
private void setCurrentTime(){
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//HH表示24小时制
String time=format.format(new Date());
tvTime.setText(time);
}
/**
* 刷新完成
*/
public void refreshComplete(boolean success){
//隐藏头布局
mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);
mCurrentState=STATE_PULL_TO_REFRESH;
tvTitle.setText("下拉刷新");
pbLoading.setVisibility(View.INVISIBLE);
ivArrow.setVisibility(View.VISIBLE);
if(success)
setCurrentTime();
}
private OnRefreshListener mListener;
private TextView tvTime;
public void setOnRefreshListener(OnRefreshListener listener){
mListener=listener;
}
public interface OnRefreshListener{
public void onRefresh();
}
}
TabDetailPager里面修改
@Override
public View initView() {
view = View.inflate(mActivity, R.layout.pager_tab_detail, null);
ViewUtils.inject(this,view);
header = View.inflate(mActivity, R.layout.list_header_topnews, null);
ViewUtils.inject(this,header);//必须也将布局注入到ViewUtils
lvList.addHeaderView(header);
lvList.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh() {
getDataFromServer();
}
});
return view;
}
/**
* 从网络获取数据
*/
private void getDataFromServer(){
HttpUtils utils=new HttpUtils();
utils.send(HttpMethod.GET, mUrl, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
String result = responseInfo.result;
System.out.println(result);
processResult(result);
CacheUtils.setCache(mUrl, result, mActivity);
//收起下拉刷新控件
lvList.refreshComplete(true);
}
@Override
public void onFailure(HttpException error, String msg) {
//收起下拉刷新控件
lvList.refreshComplete(false);
Toast.makeText(mActivity, msg, Toast.LENGTH_SHORT).show();
System.err.println(error+"msg"+msg);
}
});
}
/**
* 从网络获取数据
*/
private void getDataFromServer(){
HttpUtils utils=new HttpUtils();
utils.send(HttpMethod.GET, mUrl, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
String result = responseInfo.result;
System.out.println(result);
processResult(result);
CacheUtils.setCache(mUrl, result, mActivity);
//收起下拉刷新控件
lvList.refreshComplete(true);
}
@Override
public void onFailure(HttpException error, String msg) {
//收起下拉刷新控件
lvList.refreshComplete(false);
Toast.makeText(mActivity, msg, Toast.LENGTH_SHORT).show();
System.err.println(error+"msg"+msg);
}
});
}
Listview头部布局RelativeLayout可能会有bug会崩溃掉
加载更多
RefreshListView 类
public class RefreshListView extends ListView implements 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 View mHeaderView ;
private int mHeaderViewHeight;
private int startY;
private int endY;
private int mCurrentState=STATE_PULL_TO_REFRESH;//默认是下拉刷新
private TextView tvTitle;
private ImageView ivArrow;
private ProgressBar pbLoading;
private RotateAnimation animDown;
private RotateAnimation animUp;
private View mFooterView;
private int mFooterViewHeight;
public RefreshListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initHeaderView();
initFooterView();
}
public RefreshListView(Context context, AttributeSet attrs) {
super(context, attrs);
initHeaderView();
initFooterView();
}
public RefreshListView(Context context) {
super(context);
initHeaderView();
initFooterView();
}
private void initHeaderView(){
mHeaderView = View.inflate(getContext(), R.layout.list_refresh_header, null);
this.addHeaderView(mHeaderView);//添加布局
//隐藏布局(1.获取头布局高度,2.设置负paddingTop,布局就会往上走)
// int height=mHeaderView.getHeight();//为0 此处无法获取高度,因为布局还没有绘制完成
//绘制之前就要获取布局高度
mHeaderView.measure(0, 0);//手动测量布局
mHeaderViewHeight = mHeaderView.getMeasuredHeight();
mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);
tvTitle = (TextView) findViewById(R.id.tv_title);
ivArrow = (ImageView) mHeaderView.findViewById(R.id.iv_arrow);
pbLoading = (ProgressBar) mHeaderView.findViewById(R.id.pb_loading);
tvTime = (TextView) findViewById(R.id.tv_time);
initAnim();
setCurrentTime();
}
/**
* 初始化脚步布局
*/
private void initFooterView(){
mFooterView = View.inflate(getContext(), R.layout.list_refresh_footer, null);
this.addFooterView(mFooterView);//添加布局mHeaderView.measure(0, 0);//手动测量布局
mFooterView.measure(0, 0);//手动测量布局
mFooterViewHeight = mFooterView.getMeasuredHeight();
mFooterView.setPadding(0, -mFooterViewHeight, 0, 0);
this.setOnScrollListener(this);
}
/**
* 初始化箭头动画
*/
private void initAnim(){
animUp = new RotateAnimation(0,-180,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
animUp.setDuration(500);
animUp.setFillAfter(true);//保持状态
animDown = new RotateAnimation(-180,0,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
animDown.setDuration(500);
animDown.setFillAfter(true);//保持状态
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
startY = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
if(startY==-1){//如果用户按住头条新闻向下滑动,会导致listview无法拿到ACTIVITY_DOWN,此时呀重新获取startY
startY=(int) ev.getY();
}
//如果当前正在刷新,什么都不做了
if(mCurrentState==STATE_REFRESHING){
break;
}
endY = (int) ev.getY();
int dy=endY-startY;
if(dy>0&&getFirstVisiblePosition()==0){//向下滑动&&当前显示的第一个item,才允许下拉刷新出来
int paddingTop=dy-mHeaderViewHeight;//计算当前paddingTop值
System.out.println(paddingTop+"===="+mHeaderViewHeight);
if(paddingTop>=0&&mCurrentState!=STATE_RELEASE_TO_REFRESH){//切换到松开刷新
mCurrentState=STATE_RELEASE_TO_REFRESH;
refreshState();
}else if(paddingTop<0&&mCurrentState!=STATE_PULL_TO_REFRESH){//切换到下拉刷新
mCurrentState=STATE_PULL_TO_REFRESH;
refreshState();
}
mHeaderView.setPadding(0, paddingTop, 0, 0);//重新设置头布局padding
return true;
}
break;
case MotionEvent.ACTION_UP:
startY=-1;//起始坐标归零
if(mCurrentState==STATE_RELEASE_TO_REFRESH){
//如果当前是松开刷新,就要切换到正在刷新
mCurrentState=STATE_REFRESHING;
refreshState();
//显示头布局
mHeaderView.setPadding(0, 0, 0, 0);
}else if(mCurrentState==STATE_REFRESHING){
//隐藏头布局
mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);
}
break;
default:
break;
}
return super.onTouchEvent(ev);
}
/**
* 根据当前状态刷新界面
*/
private void refreshState(){
switch (mCurrentState) {
case STATE_PULL_TO_REFRESH:
tvTitle.setText("下拉刷新");
ivArrow.startAnimation(animDown);
pbLoading.setVisibility(View.INVISIBLE);
break;
case STATE_RELEASE_TO_REFRESH:
tvTitle.setText("松开刷新");
ivArrow.startAnimation(animUp);
pbLoading.setVisibility(View.INVISIBLE);
//下拉刷新毁掉
if(mListener!=null){
mListener.onRefresh();
}
break;
case STATE_REFRESHING:
tvTitle.setText("正在刷新...");
pbLoading.setVisibility(View.VISIBLE);
ivArrow.clearAnimation();//必须清除动画才能隐藏
ivArrow.setVisibility(View.INVISIBLE);
break;
default:
break;
}
}
/**
* 设置上次刷新时间
*/
private void setCurrentTime(){
SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//HH表示24小时制
String time=format.format(new Date());
tvTime.setText(time);
}
/**
* 刷新完成
*/
public void refreshComplete(boolean success){
if(!isLoadingMore){
//隐藏头布局
mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);
mCurrentState=STATE_PULL_TO_REFRESH;
tvTitle.setText("下拉刷新");
pbLoading.setVisibility(View.INVISIBLE);
ivArrow.setVisibility(View.VISIBLE);
//刷新失败不用更新时间
if(success)
setCurrentTime();
}else{
System.out.println("=======complete"+mFooterViewHeight);
mFooterView.setPadding(0, -mFooterViewHeight, 0, 0);
isLoadingMore=false;
}
}
private OnRefreshListener mListener;
private TextView tvTime;
private boolean isLoadingMore;
public void setOnRefreshListener(OnRefreshListener listener){
mListener=listener;
}
public interface OnRefreshListener{
public void onRefresh();
public void loadMore();
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(scrollState==SCROLL_STATE_IDLE){
int lastVisiblePosition = getLastVisiblePosition();//当前界面显示的最后一个item的位置
if(lastVisiblePosition>=getCount()-1&&!isLoadingMore){
isLoadingMore=true;
System.out.println("onScroll========");
//显示底部
mFooterView.setPadding(0, 0, 0, 0);
//listview设置当前要展示的item的位置
setSelection(getCount()-1);//跳到加载更多item的位置去展示
if(mListener!=null){
mListener.loadMore();
}
}
}
}
}
TabDetailPager 类
public class TabDetailPager extends BaseMenuDetailPager {
private NewsTabData mTableData;
@ViewInject(R.id.lv_table_detail)
private RefreshListView lvList;
@ViewInject(R.id.vp_table_detail)
private HorizontalScrollViewPager mViewPager;
@ViewInject(R.id.indicator)
private CirclePageIndicator mIndicator;
@ViewInject(R.id.tv_title)
private TextView tvTopNewsTitle;
private String mUrl;
private NewsData mNewsTabData;
private ArrayList<TopNews> mTopNewsList;
private TopNewAdapter mTopNewAdapter;
private View view;
private View header;
private ArrayList<News> mNewsList;
private String mMoreUrl;
private NewAdapter mNewAdapter;
public TabDetailPager(Activity activity,NewsTabData tabData) {
super(activity);
mTableData=tabData;
mUrl=Constants.SERVER_URL+tabData.url;
}
@Override
public View initView() {
view = View.inflate(mActivity, R.layout.pager_tab_detail, null);
ViewUtils.inject(this,view);
header = View.inflate(mActivity, R.layout.list_header_topnews, null);
ViewUtils.inject(this,header);//必须也将布局注入到ViewUtils
lvList.addHeaderView(header);
lvList.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh() {
getDataFromServer();
}
@Override
public void loadMore() {
if(mMoreUrl!=null)
getMoreDataFromServer();
else{
Toast.makeText(mActivity, "没有更多数据了", 0).show();
//收起下拉刷新控件
lvList.refreshComplete(false);
}
}
});
return view;
}
@Override
public void initData() {
String cache = CacheUtils.getCache(mUrl, mActivity);
if(!TextUtils.isEmpty(cache)){
processResult(cache,false);
}
getDataFromServer();
}
/**
* 加载更多数据
*/
private void getMoreDataFromServer() {
HttpUtils utils=new HttpUtils();
utils.send(HttpMethod.GET, mMoreUrl, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
String result = responseInfo.result;
processResult(result,true);
//收起下拉刷新控件
lvList.refreshComplete(false);
}
@Override
public void onFailure(HttpException error, String msg) {
//收起下拉刷新控件
lvList.refreshComplete(false);
Toast.makeText(mActivity, msg, Toast.LENGTH_SHORT).show();
System.err.println(error+"msg"+msg);
}
});
}
/**
* 从网络获取数据
*/
private void getDataFromServer(){
HttpUtils utils=new HttpUtils();
utils.send(HttpMethod.GET, mUrl, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
String result = responseInfo.result;
System.out.println(result);
processResult(result,false);
CacheUtils.setCache(mUrl, result, mActivity);
//收起加载更多控件
lvList.refreshComplete(true);
}
@Override
public void onFailure(HttpException error, String msg) {
//收起加载更多控件
lvList.refreshComplete(false);
Toast.makeText(mActivity, msg, Toast.LENGTH_SHORT).show();
System.err.println(error+"msg"+msg);
}
});
}
/**
* 解析json数据
* @param result
*/
protected void processResult(String result,boolean isMore) {
Gson gson=new Gson();
mNewsTabData = gson.fromJson(result, NewsData.class);
mTopNewsList = mNewsTabData.data.topnews;
if(!TextUtils.isEmpty(mNewsTabData.data.more))
mMoreUrl=Constants.SERVER_URL+mNewsTabData.data.more;
else
mMoreUrl=null;
if(!isMore){
//初始化头条新闻
if(mTopNewsList!=null){
mTopNewAdapter = new TopNewAdapter();
mViewPager.setAdapter(mTopNewAdapter);
mIndicator.setViewPager(mViewPager);
mIndicator.setSnap(true);//快照模式
mIndicator.setCurrentItem(0);
tvTopNewsTitle.setText(mTopNewsList.get(0).title);
mIndicator.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
tvTopNewsTitle.setText(mTopNewsList.get(arg0).title);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
mIndicator.onPageSelected(0);//将小圆点位置归零,否则它会在页面销毁时仍记录上次位置的bug
}
mNewsList = mNewsTabData.data.news;
if(mNewsList!=null){
mNewAdapter = new NewAdapter();
lvList.setAdapter(mNewAdapter);
}
}else{
ArrayList<News> moreData = mNewsTabData.data.news;
mNewsList.addAll(moreData);//追加数据
mNewAdapter.notifyDataSetChanged();//刷新listview
}
System.out.println(mNewsTabData);
}
class TopNewAdapter extends PagerAdapter{
BitmapUtils mBitmapUtils;
public TopNewAdapter(){
mBitmapUtils=new BitmapUtils(mActivity);
}
@Override
public int getCount() {
return mTopNewsList.size();
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0==arg1;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView view=new ImageView(mActivity);
view.setScaleType(ScaleType.FIT_XY);//设置图片填充效果,表示填充父窗口
//获取图片链接,使用链接下载图片,将图片设置为ImageView,考虑内存溢出问题
mBitmapUtils.display(view, mTopNewsList.get(position).topimage);
container.addView(view);
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
}
class NewAdapter extends BaseAdapter{
public BitmapUtils mBitmapUtils;
public NewAdapter(){
mBitmapUtils = new BitmapUtils(mActivity);
mBitmapUtils.configDefaultLoadFailedImage(R.drawable.pic_item_list_default);
}
@Override
public int getCount() {
return mNewsList.size();
}
@Override
public News getItem(int arg0) {
return mNewsList.get(arg0);
}
@Override
public long getItemId(int arg0) {
return arg0;
}
@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
ViewHolde holder;
if(arg1==null){
arg1=View.inflate(mActivity, R.layout.list_item_news, null);
holder=new ViewHolde();
holder.tvTitle=(TextView) arg1.findViewById(R.id.tv_title);
holder.tvDate=(TextView) arg1.findViewById(R.id.tv_date);
holder.ivIcon=(ImageView) arg1.findViewById(R.id.iv_icon);
arg1.setTag(holder);
}else{
holder=(ViewHolde) arg1.getTag();
}
News news= getItem(arg0);
holder.tvTitle.setText(news.title);
holder.tvDate.setText(news.pubdate);
mBitmapUtils.display(holder.ivIcon, news.listimage);
return arg1;
}
}
static class ViewHolde{
public TextView tvTitle;
public TextView tvDate;
public ImageView ivIcon;
}
}
list_refresh_footer.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal" >
<ProgressBar
android:id="@+id/pb_loading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:indeterminateDrawable="@drawable/custom_progress"
/>
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="加载中..."
android:textColor="#f00"
android:textSize="17sp"
android:layout_marginLeft="5dp"
/>
</ LinearLayout >