English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
1.追加で読み込むレイアウトを追加
1_初期化および非表示コード
RefreshListViewのコンストラクタで呼び出し
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スクロールを下にドラッグして最下部に達したとき
/** * メニューページに対応するニュースページタグページ * 全てで12個 * @author Administrator * */ public class TabMenuDetailPager extends MenuDetailBasePager implements OnPageChangeListener { /** * ニュースセンター-ニュースメニューに対応するタグのデータ */ private NewCenterTag newCenterTag; ..................... /** * データを追加読み込みするURL */ private String moreUrl; /** * データの読み込みが進行中かどうか */ protected boolean isLoadingMore = false; ................... @Override public View initView() { View view = View.inflate(mActivity, R.layout.tab_detail, null); //ViewをXUtilsフレームワークに注入します ViewUtils.inject(this, view); .......................... //設定リフレッシュリスナーを設定 mListView.setOnRefreshListener(new OnRefreshListener() { @Override public void onPullDownRefresh() {}} isPullDownRefreshing = true; getDataFromNet(); } @Override public void onLoadingMore() { if(TextUtils.isEmpty(moreUrl)){ Toast.makeText(mActivity, "もうデータはありません", 1).show(); mListView.onRefreshFinish(false); }else{ //さらにデータがあります。さらにデータを読み込む必要があります getMoreDataFromNet(); } } }); return view; } /** * データの読み込み */ 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("データの読み込みに成功しました:"+responseInfo.result); mListView.onRefreshFinish(false); isLoadingMore = true; processData(responseInfo.result); } @Override public void onFailure(HttpException error, String msg) { mListView.onRefreshFinish(false); System.out.println("データの読み込みに失敗しました:"+ msg); } }); } /** * jsonデータの処理と解析を行います * @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にアダプターを設定します 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; //デフォルトの画像説明と指標点を設定します。 mtv_title_description.setText(topnews.get(previousPointPosition).title); ll_point_group.getChildAt(previousPointPosition).setEnabled(true); //ページ変更のリスナーを設定します。 mViewPager.setOnPageChangeListener(this); //アダプタと対応するデータを設定します。 newsLists = bean.data.news; listViewAdapter = new ListViewAdapter(); mListView.setAdapter(listViewAdapter); // mListView.addHeaderView(v) ;//ビューを一端から追加する方法でListViewに追加します。 }else{ //リストのニュースを取り出し、以前の集合に読み込んで、データを更新します。 isLoadingMore = false; List<News>moreDataNews = bean.data.news; newsLists.addAll(moreDataNews); listViewAdapter.notifyDataSetChanged();//データをリフレッシュ } } ................ /** * Gsonオープンソースプロジェクトで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 オート-生成されたメソッドスタブ } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { // TODO オート-生成されたメソッドスタブ } ............... }
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; /** * 現在の状態 */ private int currentStatus = PULL_DOWN_REFRESH; private Animation upAnimation; private Animation downAnimation; /** * 読み込むためのビュー */ private View footerView; /** * 読み込むためのビューの高さ */ private int footerViewHeight; /** * もう読み込まれたかどうか */ private boolean isLoadMore = false; /** * トップスライドショー部分 */ private View topNewsView; /** * ListViewがY軸上の座標 */ 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にフッターを追加 addFooterView(footerView); //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) { //静止またはインパルス的にスクロールしているとき scrollState == OnScrollListener.SCROLL_STATE_IDLE || scrollState == OnScrollListener.SCROLL_STATE_FLING //最後の表示された項目である場合 getLastVisiblePosition() >= getCount()-1{ //1.さらに読み込むレイアウトを表示 footerView.setPadding(8,8,8,8); //2.ステータス変更 isLoadMore = true; //3.回调インターフェース 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(); //デフォルトでドロップダウンリフレッシュコントロールを非表示 // 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.始点座標を記録 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.新しい座標に到達 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) { //下拉リフレッシュの状態 currentStatus = PULL_DOWN_REFRESH; //更新状态 refreshViewState(); else if (paddingTop > 0 && currentStatus != RELEASE_REFRESH) { //手を離すとリフレッシュの状態 currentStatus = RELEASE_REFRESH; //更新状态 refreshViewState(); } ll_pull_down_refresh.setPadding(0, paddingTop, 0, 0); //View.setPadding(0,paddingTop,0,0);//动态的显示下拉刷新控件 } 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) { //设置状态为正在刷新 currentStatus = REFRESHING; refreshViewState(); // View.setPadding(0,0,0,0);//完全显示 ll_pull_down_refresh.setPadding(0, 0, 0, 0); //回调接口 if (mOnRefreshListener != null) { mOnRefreshListener.onPullDownRefresh(); } } break; } return super.onTouchEvent(ev); } /** * 判断是否完全显示顶部轮播图 * 当ListView在屏幕上的Y轴坐标小于或者等于顶部轮播图在Y轴的坐标的时候,顶部轮播图完全显示 * @return */ private boolean isDisplayTopNews() { if(topNewsView != null){ //1.得到ListView在屏幕上的坐标 int[] location = new int[2]; if(listViewOnScreenY == -1{ getLocationOnScreen(location); listViewOnScreenY = location[1]; } //2.得到顶部轮播图在屏幕上的坐标 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://下拉リフレッシュの状態 iv_arrow.startAnimation(downAnimation); tv_status.setText("下拉リフレッシュ..."); break; case RELEASE_REFRESH://手を離すとリフレッシュの状態 iv_arrow.startAnimation(upAnimation); tv_status.setText("手を離すとリフレッシュ..."); break; case REFRESHING://リフレッシュ中の状態 tv_status.setText("リフレッシュ中..."); pb_status.setVisibility(VISIBLE); iv_arrow.clearAnimation(); iv_arrow.setVisibility(GONE); break; } } /** * ネットワーク接続が成功または失敗したときにこのメソッドがコールバックされます * ユーザーのリフレッシュ状態のリセット * * @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) { //最新更新時間を設定 tv_time.setText("前回更新時間:" + getSystemTime()); } } } /** * 現在のAndroidシステムの時間を取得 * * @return */ private String getSystemTime() { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return format.format(new Date()); } /** * コントロールのリフレッシュを監視する */ public interface OnRefreshListener { /** * 下に引っ張るリフレッシュのときにこのメソッドをコールバックする */ public void onPullDownRefresh(); /** もっと読むのときにこのメソッドをコールバックする */ public void onLoadMore(); } private OnRefreshListener mOnRefreshListener; /** * 外部からリフレッシュを設定する */ public void setOnRefreshListener(OnRefreshListener l) { this.mOnRefreshListener = l; } }
以上が編集者が皆さんに紹介したAndroid 仿硅谷新聞下拉刷新の内容です。/もっと読むを上に引っ張って、皆さんに役立つことを願っています。何かご不明な点がございましたら、コメントを残してください。編集者は皆さんに迅速に回答します。また、皆さんの呐喊教程サイトへのサポートに感謝しています。
声明:本文の内容はインターネットから取得しており、著作権者に帰属します。インターネットユーザーにより自発的に貢献し、自己でアップロードされています。本サイトは所有権を持ちません。また、人工的な編集は行われていません。著作権に関する問題がある場合は、notice#wまでメールをお送りください。3codebox.com(メールを送信する際、#を@に置き換えてください。報告を行い、関連する証拠を提供してください。一旦確認がとれましたら、本サイトは直ちに侵害される内容を削除します。)