Android 仿硅谷新聞下拉刷新/上拉加載更多
1.添加加載更多布局
1_初始化和隱藏代碼
在RefreshListView構(gòu)造方法中調(diào)用
private void initFooterView(Context context) {
View footerView = View.inflate(context, R.layout.refresh_listview_footer, null);
//隱藏代碼
footerView.measure(0, 0);
int footerViewHeight = footerView.getMeasuredHeight();
footerView.setPadding(0, -footerViewHeight, 0, 0);
this.addFooterView(footerView);
}
2_布局文件refresh_listview_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="wrap_content" android:gravity="center" android:orientation="horizontal" > <ProgressBar android:layout_margin="5dip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:indeterminateDrawable="@drawable/custom_progressbar" /> <TextView android:layout_marginLeft="10dip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="加載更多中..." android:textColor="#ff0000" android:textSize="25sp" /> </LinearLayout>
2.拖動到底部的時候
/**
* 菜單頁面對應(yīng)的新聞頁簽頁面
* 總共有12個
* @author Administrator
*
*/
public class TabMenuDetailPager extends MenuDetailBasePagerimplements OnPageChangeListener {
/**
* 新聞中心-新聞菜單對應(yīng)的標(biāo)簽對應(yīng)的數(shù)據(jù)
*/
private NewCenterTag newCenterTag;
.......................
/**
* 加載更多數(shù)據(jù)的URL
*/
private String moreUrl;
/**
* 是否加載更多數(shù)據(jù)中
*/
protected boolean isLoadingMore = false;
...................
@Override
public View initView() {
View view = View.inflate(mActivity, R.layout.tab_detail, null);
//把View注入到XUtils框架中
ViewUtils.inject(this, view);
..........................
//設(shè)置監(jiān)聽下拉刷新
mListView.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onPullDownRefresh() {
isPullDownRefreshing = true;
getDataFromNet();
}
@Override
public void onLoadingMore() {
if(TextUtils.isEmpty(moreUrl)){
Toast.makeText(mActivity, "沒有更多數(shù)據(jù)了", 1).show();
mListView.onRefreshFinish(false);
}else{
//有更多數(shù)據(jù),要加載更多數(shù)據(jù)了
getMoreDataFromNet();
}
}
});
return view;
}
/**
* 加載更多數(shù)據(jù)
*/
protected void getMoreDataFromNet() {
HttpUtils httpUtils = new HttpUtils();
httpUtils.send(HttpMethod.GET, moreUrl, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
System.out.println("加載更多數(shù)據(jù)成功:"+responseInfo.result);
mListView.onRefreshFinish(false);
isLoadingMore = true;
processData(responseInfo.result);
}
@Override
public void onFailure(HttpException error, String msg) {
mListView.onRefreshFinish(false);
System.out.println("加載更多數(shù)據(jù)失敗:"+ msg);
}
});
}
/**
* 處理和解析json數(shù)據(jù)
* @param json
*/
protected void processData(String json) {
TabDetailBean bean = parserJson(json);
if(!isLoadingMore){
System.out.println(bean.data.news.get(0).title);
topnews = bean.data.topnews;
//給ViewPager設(shè)置適配器
TabDetailAdapter adapter = new TabDetailAdapter();
mViewPager.setAdapter(adapter);
// 把所有的View清除
ll_point_group.removeAllViews();
for(int i=0;i<topnews.size();i++){
View point = new View(mActivity);
LayoutParams params = new LayoutParams(5, 5) ;
point.setBackgroundResource(R.drawable.tab_detail_point_bg);
if(i!=0){
params.leftMargin = 10;
}
point.setEnabled(false);
point.setLayoutParams(params);
ll_point_group.addView(point);
}
previousPointPosition = 0;
//設(shè)置默認(rèn)的圖片描述和指示點(diǎn)
mtv_title_description.setText(topnews.get(previousPointPosition).title);
ll_point_group.getChildAt(previousPointPosition).setEnabled(true);
//設(shè)置頁面改變的監(jiān)聽
mViewPager.setOnPageChangeListener(this);
//設(shè)置適配器和對應(yīng)的數(shù)據(jù)
newsLists = bean.data.news;
listViewAdapter = new ListViewAdapter();
mListView.setAdapter(listViewAdapter);
// mListView.addHeaderView(v) ;//把一個視圖一頭的方式添加到ListView中
}else{
//把列表新聞取出來,在加載到以前的集合中,在刷新數(shù)據(jù)
isLoadingMore = false;
List<News>moreDataNews = bean.data.news;
newsLists.addAll(moreDataNews);
listViewAdapter.notifyDataSetChanged();//刷新數(shù)據(jù)
}
}
................
/**
* 用Gson開源項(xiàng)目解析json
* @param json
*/
private TabDetailBean parserJson(String json) {
Gson gson = new Gson();
TabDetailBean bean = gson.fromJson(json, TabDetailBean.class);
moreUrl = bean.data.more;
if(TextUtils.isEmpty(moreUrl)){
moreUrl = null;
}else{
moreUrl = ConstantUtils.server_url+moreUrl;
}
return bean;
}
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub
}
...............
}
3.完整代碼
package com.atguigu.refreshlistview;
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.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 作用:自定義下拉刷新的ListView
*/
public class RefreshListview extends ListView {
/**
* 下拉刷新和頂部輪播圖
*/
private LinearLayout headerView;
/**
* 下拉刷新控件
*/
private View ll_pull_down_refresh;
private ImageView iv_arrow;
private ProgressBar pb_status;
private TextView tv_status;
private TextView tv_time;
/**
* 下拉刷新控件的高
*/
private int pullDownRefreshHeight;
/**
* 下拉刷新
*/
public static final int PULL_DOWN_REFRESH = 0;
/**
* 手松刷新
*/
public static final int RELEASE_REFRESH = 1;
/**
* 正在刷新
*/
public static final int REFRESHING = 2;
/**
* 當(dāng)前狀態(tài)
*/
private int currentStatus = PULL_DOWN_REFRESH;
private Animation upAnimation;
private Animation downAnimation;
/**
* 加載更多的控件
*/
private View footerView;
/**
* 加載更多控件高
*/
private int footerViewHeight;
/**
* 是否已經(jīng)加載更多
*/
private boolean isLoadMore = false;
/**
* 頂部輪播圖部分
*/
private View topNewsView;
/**
* ListView在Y軸上的坐標(biāo)
*/
private int listViewOnScreenY = -1;
public RefreshListview(Context context) {
this(context, null);
}
public RefreshListview(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RefreshListview(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initHeaderView(context);
initAnimation();
initFooterView(context);
}
private void initFooterView(Context context) {
footerView = View.inflate(context, R.layout.refresh_footer, null);
footerView.measure(0, 0);
footerViewHeight = footerView.getMeasuredHeight();
footerView.setPadding(0, -footerViewHeight, 0, 0);
//ListView添加footer
addFooterView(footerView);
//監(jiān)聽ListView的滾動
setOnScrollListener(new MyOnScrollListener());
}
/**
* 添加頂部輪播圖
* @param topNewsView
*/
public void addTopNewsView(View topNewsView) {
if(topNewsView != null){
this.topNewsView =topNewsView;
headerView.addView(topNewsView);
}
}
class MyOnScrollListener implements OnScrollListener{
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
//當(dāng)靜止或者慣性滾動的時候
if(scrollState ==OnScrollListener.SCROLL_STATE_IDLE||scrollState ==OnScrollListener.SCROLL_STATE_FLING){
//并且是最后一條可見
if(getLastVisiblePosition()>=getCount()-1){
//1.顯示加載更多布局
footerView.setPadding(8,8,8,8);
//2.狀態(tài)改變
isLoadMore = true;
//3.回調(diào)接口
if(mOnRefreshListener != null){
mOnRefreshListener.onLoadMore();
}
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
}
private void initAnimation() {
upAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
upAnimation.setDuration(500);
upAnimation.setFillAfter(true);
downAnimation = new RotateAnimation(-180, -360, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
downAnimation.setDuration(500);
downAnimation.setFillAfter(true);
}
private void initHeaderView(Context context) {
headerView = (LinearLayout) View.inflate(context, R.layout.refresh_header, null);
//下拉刷新控件
ll_pull_down_refresh = headerView.findViewById(R.id.ll_pull_down_refresh);
iv_arrow = (ImageView) headerView.findViewById(R.id.iv_arrow);
pb_status = (ProgressBar) headerView.findViewById(R.id.pb_status);
tv_status = (TextView) headerView.findViewById(R.id.tv_status);
tv_time = (TextView) headerView.findViewById(R.id.tv_time);
//測量
ll_pull_down_refresh.measure(0, 0);
pullDownRefreshHeight = ll_pull_down_refresh.getMeasuredHeight();
//默認(rèn)隱藏下拉刷新控件
// View.setPadding(0,-控件高,0,0);//完全隱藏
//View.setPadding(0, 0,0,0);//完全顯示
ll_pull_down_refresh.setPadding(0, -pullDownRefreshHeight, 0, 0);
//添加ListView的頭
addHeaderView(headerView);
}
private float startY = -1;
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
//1.記錄起始坐標(biāo)
startY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
if (startY == -1) {
startY = ev.getY();
}
//判斷頂部輪播圖是否完全顯示,只有完全顯示才會有下拉刷新
boolean isDisplayTopNews = isDisplayTopNews();
if(!isDisplayTopNews){
//加載更多
break;
}
//如果是正在刷新,就不讓再刷新了
if (currentStatus == REFRESHING) {
break;
}
//2.來到新的坐標(biāo)
float endY = ev.getY();
//3.記錄滑動的距離
float distanceY = endY - startY;
if (distanceY > 0) {//下拉
//int paddingTop = -控件高 + distanceY;
int paddingTop = (int) (-pullDownRefreshHeight + distanceY);
if (paddingTop < 0 && currentStatus != PULL_DOWN_REFRESH) {
//下拉刷新狀態(tài)
currentStatus = PULL_DOWN_REFRESH;
//更新狀態(tài)
refreshViewState();
} else if (paddingTop > 0 && currentStatus != RELEASE_REFRESH) {
//手松刷新狀態(tài)
currentStatus = RELEASE_REFRESH;
//更新狀態(tài)
refreshViewState();
}
ll_pull_down_refresh.setPadding(0, paddingTop, 0, 0);
//View.setPadding(0,paddingTop,0,0);//動態(tài)的顯示下拉刷新控件
}
break;
case MotionEvent.ACTION_UP:
startY = -1;
if (currentStatus == PULL_DOWN_REFRESH) {
// View.setPadding(0,-控件高,0,0);//完全隱藏
ll_pull_down_refresh.setPadding(0, -pullDownRefreshHeight, 0, 0);
} else if (currentStatus == RELEASE_REFRESH) {
//設(shè)置狀態(tài)為正在刷新
currentStatus = REFRESHING;
refreshViewState();
// View.setPadding(0,0,0,0);//完全顯示
ll_pull_down_refresh.setPadding(0, 0, 0, 0);
//回調(diào)接口
if (mOnRefreshListener != null) {
mOnRefreshListener.onPullDownRefresh();
}
}
break;
}
return super.onTouchEvent(ev);
}
/**
* 判斷是否完全顯示頂部輪播圖
* 當(dāng)ListView在屏幕上的Y軸坐標(biāo)小于或者等于頂部輪播圖在Y軸的坐標(biāo)的時候,頂部輪播圖完全顯示
* @return
*/
private boolean isDisplayTopNews() {
if(topNewsView != null){
//1.得到ListView在屏幕上的坐標(biāo)
int[] location = new int[2];
if(listViewOnScreenY == -1){
getLocationOnScreen(location);
listViewOnScreenY = location[1];
}
//2.得到頂部輪播圖在屏幕上的坐標(biāo)
topNewsView.getLocationOnScreen(location);
int topNewsViewOnScreenY = location[1];
// if(listViewOnScreenY <= topNewsViewOnScreenY){
// return true;
// }else{
// return false;
// }
return listViewOnScreenY <= topNewsViewOnScreenY;
}else{
return true;
}
}
private void refreshViewState() {
switch (currentStatus) {
case PULL_DOWN_REFRESH://下拉刷新狀態(tài)
iv_arrow.startAnimation(downAnimation);
tv_status.setText("下拉刷新...");
break;
case RELEASE_REFRESH://手松刷新狀態(tài)
iv_arrow.startAnimation(upAnimation);
tv_status.setText("手松刷新...");
break;
case REFRESHING://正在刷新狀態(tài)
tv_status.setText("正在刷新...");
pb_status.setVisibility(VISIBLE);
iv_arrow.clearAnimation();
iv_arrow.setVisibility(GONE);
break;
}
}
/**
* 當(dāng)聯(lián)網(wǎng)成功和失敗的時候回調(diào)該方法
* 用戶刷新狀態(tài)的還原
*
* @param sucess
*/
public void onRefreshFinish(boolean sucess) {
if(isLoadMore){
//加載更多
isLoadMore = false;
//隱藏加載更多布局
footerView.setPadding(0,-footerViewHeight,0,0);
}else{
//下拉刷新
tv_status.setText("下拉刷新...");
currentStatus = PULL_DOWN_REFRESH;
iv_arrow.clearAnimation();
pb_status.setVisibility(GONE);
iv_arrow.setVisibility(VISIBLE);
//隱藏下拉刷新控件
ll_pull_down_refresh.setPadding(0, -pullDownRefreshHeight, 0, 0);
if (sucess) {
//設(shè)置最新更新時間
tv_time.setText("上次更新時間:" + getSystemTime());
}
}
}
/**
* 得到當(dāng)前Android系統(tǒng)的時間
*
* @return
*/
private String getSystemTime() {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return format.format(new Date());
}
/**
* 監(jiān)聽控件的刷新
*/
public interface OnRefreshListener {
/**
* 當(dāng)下拉刷新的時候回調(diào)這個方法
*/
public void onPullDownRefresh();
/**
當(dāng)加載更多的時候回調(diào)這個方法
*/
public void onLoadMore();
}
private OnRefreshListener mOnRefreshListener;
/**
* 設(shè)置監(jiān)聽刷新,由外界設(shè)置
*/
public void setOnRefreshListener(OnRefreshListener l) {
this.mOnRefreshListener = l;
}
}
以上所述是小編給大家介紹的Android 仿硅谷新聞下拉刷新/上拉加載更多,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
- Android實(shí)現(xiàn)上拉加載更多以及下拉刷新功能(ListView)
- Android RecyclerView 上拉加載更多及下拉刷新功能的實(shí)現(xiàn)方法
- Android ListView實(shí)現(xiàn)上拉加載更多和下拉刷新功能
- Android下拉刷新上拉加載更多左滑動刪除
- Android XListView下拉刷新和上拉加載更多
- Android RecyclerView實(shí)現(xiàn)下拉刷新和上拉加載更多
- Android RecyclerView下拉刷新和上拉加載更多
- Android中Listview下拉刷新和上拉加載更多的多種實(shí)現(xiàn)方案
- android使用PullToRefresh框架實(shí)現(xiàn)ListView下拉刷新上拉加載更多
- Android實(shí)踐之帶加載效果的下拉刷新上拉加載更多
相關(guān)文章
Android實(shí)現(xiàn)圖片循環(huán)播放的實(shí)例方法
2013-05-05
5個Android開發(fā)中比較常見的內(nèi)存泄漏問題及解決辦法
本文主要介紹了5個Android開發(fā)中比較常見的內(nèi)存泄漏問題及解決辦法,具有很好的參考價值,下面跟著小編一起來看下吧2017-02-02
Android實(shí)現(xiàn)圓形漸變加載進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)圓形漸變加載進(jìn)度條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-09-09
Android自定義View實(shí)現(xiàn)隨機(jī)數(shù)驗(yàn)證碼
這篇文章主要為大家詳細(xì)介紹了Android如何利用自定義View實(shí)現(xiàn)隨機(jī)數(shù)驗(yàn)證碼效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-06-06
Flutter 滾動監(jiān)聽及實(shí)戰(zhàn)appBar滾動漸變的實(shí)現(xiàn)
這篇文章主要介紹了Flutter 滾動監(jiān)聽及實(shí)戰(zhàn)appBar滾動漸變,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
Android ndk獲取手機(jī)內(nèi)部存儲卡的根目錄方法
今天小編就為大家分享一篇Android ndk獲取手機(jī)內(nèi)部存儲卡的根目錄方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08
Android?雙屏異顯自適應(yīng)Dialog的實(shí)現(xiàn)
Android 多屏互聯(lián)的時代,必然會出現(xiàn)多屏連接的問題,本文主要介紹了Android?雙屏異顯自適應(yīng)Dialog的實(shí)現(xiàn),具有一定的參考價值,感興趣的可以了解一下2023-12-12
自定義ListView實(shí)現(xiàn)拖拽ListItem項(xiàng)交換位置(附源碼)
本文要實(shí)現(xiàn)的是拖拽ListView的Item項(xiàng),在布局方面還是用基于布局泵LayoutInflater來從不同的Layout模板拿到不同的布局然后將view返回,感興趣的朋友可以了解下哈2013-06-06
Android編程開發(fā)之EditText中inputType屬性小結(jié)
這篇文章主要介紹了Android編程開發(fā)之EditText中inputType屬性用法,分析說明了Android中EditText的inputType屬性具體含義與使用技巧,需要的朋友可以參考下2016-01-01

