`
龙哥IT
  • 浏览: 253905 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

GridView下拉刷新

 
阅读更多
package com.example.headpull;

import java.text.SimpleDateFormat;
import java.util.Date;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

public class PullToRefreshGridView extends GridView implements OnScrollListener {
	  private static final String TAG = "listview";
	    private final static int RELEASE_To_REFRESH = 0; // 释放
	    private final static int PULL_To_REFRESH = 1;// 下拉刷新
	    private final static int REFRESHING = 2; // 正在刷新
	    private final static int DONE = 3; // 按下
	    private final static int LOADING = 4;
	    // 实际的padding的距离与界面上偏移距离的比例
	    private final static int RATIO = 3;
	    private LayoutInflater inflater;
	    private LinearLayout headView;
	    private TextView tipsTextview;
	    private TextView lastUpdatedTextView;
	    private ImageView arrowImageView;
	    private ProgressBar progressBar;
	    private RotateAnimation animation;
	    private RotateAnimation reverseAnimation;
	    // 用于保证startY的值在一个完整的touch事件中只被记录一次
	    private boolean isRecored;
	    private int headContentWidth;
	    private int headContentHeight;
	    private int startY;
	    private int firstItemIndex;
	    private int state;
	    private boolean isBack;
	    private OnRefreshListener refreshListener;
	    private boolean isRefreshable;
	    public PullToRefreshGridViewActivity context;
	 
	 
	 public PullToRefreshGridView(Context context) { 
	     super(context);
	     this.context=(PullToRefreshGridViewActivity) context;
	     init(context); 
	       } 
	 
	    public PullToRefreshGridView(Context context, AttributeSet attrs) { 
	       super(context, attrs);
	       this.context=(PullToRefreshGridViewActivity) context;
	        init(context); 
	    }
	   
	    public View getView(){
	    return headView;
	    }
	   
	        private void init(Context context) { 
	 
	       // setCacheColorHint(context.getResources().getColor(R.color.transparent));
	 
	       inflater = LayoutInflater.from(context);
	       // head 布局文件
	       headView = (LinearLayout) inflater.inflate(R.layout.pulldown_header, null);
	       // 下拉箭头
	       arrowImageView = (ImageView) headView.findViewById(R.id.pulldown_header_arrow);
	       arrowImageView.setMinimumWidth(70);
	       arrowImageView.setMinimumHeight(50);
	       // 进度条
	       progressBar = (ProgressBar) headView.findViewById(R.id.pulldown_header_loading);
	       // 下拉提示 刷新
	       tipsTextview = (TextView) headView.findViewById(R.id.pulldown_header_text);
	       //最新一次刷新时间
	       lastUpdatedTextView = (TextView) headView.findViewById(R.id.pulldown_header_date);
	        //计算head的高宽
	       measureView(headView);
	       headContentHeight = headView.getMeasuredHeight();
	       headContentWidth = headView.getMeasuredWidth();
	       //初始状态是 隐藏掉head 布局
	       headView.setPadding(0, -1 * headContentHeight, 0, 0);
	       headView.invalidate();
	         Log.v("size", "width:" + headContentWidth + " height:" + headContentHeight);  
	          setOnScrollListener(this);
	          //下拉以及恢复动画
	          animation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f,RotateAnimation.RELATIVE_TO_SELF, 0.5f); 
	              animation.setInterpolator(new LinearInterpolator()); 
	              animation.setDuration(250); 
	              animation.setFillAfter(true); 
	             reverseAnimation = new RotateAnimation(-180, 0, 
	                      RotateAnimation.RELATIVE_TO_SELF, 0.5f, 
	                      RotateAnimation.RELATIVE_TO_SELF, 0.5f); 
	            reverseAnimation.setInterpolator(new LinearInterpolator()); 
	            reverseAnimation.setDuration(200); 
	            reverseAnimation.setFillAfter(true); 
	            state = DONE; 
	            isRefreshable = false; 
	     } 
	        public void onScroll(AbsListView arg0, int firstVisiableItem, int arg2, int arg3) { 
	           firstItemIndex = firstVisiableItem; 
	          } 
	        public void onScrollStateChanged(AbsListView arg0, int arg1) { 
	        } 
	 
	    public boolean onTouchEvent(MotionEvent event) {
	 
	       if (isRefreshable) {
	           switch (event.getAction()) {
	           // 在down时候记录当前Y的位置
	           case MotionEvent.ACTION_DOWN:
	              if (firstItemIndex == 0 && !isRecored) {
	                  isRecored = true;
	                  startY = (int) event.getY();
	                  Log.v(TAG, "在down时候记录当前位置‘");
	              }
	              break;
	           case MotionEvent.ACTION_UP:
	              if (state != REFRESHING && state != LOADING) {
	                  if (state == DONE) {
	                     // 什么都不做
	                  }
	                  //由下拉刷新状态,到done状态
	                  if (state == PULL_To_REFRESH) {
	                     state = DONE;
	                     changeHeaderViewByState();
	                     Log.v(TAG, "由下拉刷新状态,到done状态");
	                  }
	 
	                  if (state == RELEASE_To_REFRESH) {
	                     state = REFRESHING;
	                     changeHeaderViewByState();
	                     onRefresh();
	                     Log.v(TAG, "由松开刷新状态,到done状态");
	                  }
	              }
	              isRecored = false;
	              isBack = false;
	              break;
	 
	           case MotionEvent.ACTION_MOVE:
	              int tempY = (int) event.getY();
	              if (!isRecored && firstItemIndex == 0) {
	                  Log.v(TAG, "在move时候记录下位置");
	                  isRecored = true;
	                  startY = tempY;
	              }
	              if (state != REFRESHING && isRecored && state != LOADING) {
	                  // 保证在设置padding的过程中,当前的位置一直是在head,否则如果当列表超出屏幕的话,当在上推的时候,列表会同时进行滚动
	                  // 可以松手去刷新了
	                  if (state == RELEASE_To_REFRESH) {
	                     setSelection(0);
	                     // 往上推了,推到了屏幕足够掩盖head的程度,但是还没有推到全部掩盖的地步
	                     if (((tempY - startY) / RATIO < headContentHeight)
	                     && (tempY - startY) > 0) {
	                         state = PULL_To_REFRESH;
	                         changeHeaderViewByState();
	                         Log.v(TAG, "由松开刷新状态转变到下拉刷新状态");
	                     }
	                     // 一下子推到顶了
	                     else if (tempY - startY <= 0) {
	                         state = DONE;
	                         changeHeaderViewByState();
	                         Log.v(TAG, "由松开刷新状态转变到done状态");
	                     }
	                     // 往下拉了,或者还没有上推到屏幕顶部掩盖head的地步
	                     else {
	                         // 不用进行特别的操作,只用更新paddingTop的值就行了
	                     }
	                  }
	                  // 还没有到达显示松开刷新的时候,DONE或者是PULL_To_REFRESH状态
	                  if (state == PULL_To_REFRESH) {
	                     setSelection(0);
	                     // 下拉到可以进入RELEASE_TO_REFRESH的状态
	                     if ((tempY - startY) / RATIO >= headContentHeight) {
	                         state = RELEASE_To_REFRESH;
	                         isBack = true;
	                         changeHeaderViewByState();
	                         Log.v(TAG, "由done或者下拉刷新状态转变到松开刷新");
	                     }
	                     // 上推到顶了
	                     else if (tempY - startY <= 0) {
	                         state = DONE;
	                         changeHeaderViewByState();
	                         Log.v(TAG, "由DOne或者下拉刷新状态转变到done状态");
	                     }
	                  }
	                  // done状态下
	                  if (state == DONE) {
	                     if (tempY - startY > 0) {
	                         state = PULL_To_REFRESH;
	                         changeHeaderViewByState();
	                     }
	                  }
	                  // 更新headView的size
	 
	                  if (state == PULL_To_REFRESH) {
	                     headView.setPadding(0, -1 * headContentHeight
	                     + (tempY - startY) / RATIO, 0, 0);
	                  }
	                  // 更新headView的paddingTop
	                  if (state == RELEASE_To_REFRESH) {
	                     headView.setPadding(0, (tempY - startY) / RATIO
	                            - headContentHeight, 0, 0);
	                  }
	              }
	              break;
	           }
	       }
	       return super.onTouchEvent(event);
	    }
	   
	         private void changeHeaderViewByState() { 
	              switch (state) {
	              //松开刷新状态
	               case RELEASE_To_REFRESH: 
	                  arrowImageView.setVisibility(View.VISIBLE); 
	                 progressBar.setVisibility(View.GONE); 
	                 tipsTextview.setVisibility(View.VISIBLE); 
	                 lastUpdatedTextView.setVisibility(View.VISIBLE);      
	                 arrowImageView.clearAnimation(); 
	                 arrowImageView.startAnimation(animation);      
	                  tipsTextview.setText("松开刷新");     
	                  Log.v(TAG, "当前状态,松开刷新"); 
	                  break; 
	                  //下拉刷新
	              case PULL_To_REFRESH: 
	                  progressBar.setVisibility(View.GONE); 
	                  tipsTextview.setVisibility(View.VISIBLE); 
	                  lastUpdatedTextView.setVisibility(View.VISIBLE); 
	                  arrowImageView.clearAnimation(); 
	                   arrowImageView.setVisibility(View.VISIBLE); 
	                 // 是由RELEASE_To_REFRESH状态转变来的
	                   //箭头反转向上
	                if (isBack) { 
	                     isBack = false; 
	                     arrowImageView.clearAnimation(); 
	                      arrowImageView.startAnimation(reverseAnimation); 
	                      tipsTextview.setText("下拉刷新"); 
	                 } else { 
	                      tipsTextview.setText("下拉刷新"); 
	                  } 
	                Log.v(TAG, "当前状态,下拉刷新"); 
	                break; 
	                //刷新中 状态
	            case REFRESHING:      
	                  headView.setPadding(0, 0, 0, 0);        
	                 progressBar.setVisibility(View.VISIBLE); 
	                arrowImageView.clearAnimation(); 
	                arrowImageView.setVisibility(View.GONE); 
	                tipsTextview.setText("正在刷新..."); 
	                 lastUpdatedTextView.setVisibility(View.VISIBLE);     
	                 Log.v(TAG, "当前状态,正在刷新..."); 
	                 break;
	                 //刷新完毕
	             case DONE: 
	                headView.setPadding(0, -1 * headContentHeight, 0, 0); 
	                progressBar.setVisibility(View.GONE); 
	                 arrowImageView.clearAnimation();  
	             arrowImageView.setImageResource(R.drawable.z_arrow_up); 
	                  tipsTextview.setText("下拉刷新"); 
	                 lastUpdatedTextView.setVisibility(View.VISIBLE);      
	                  Log.v(TAG, "当前状态,done"); 
	                 break; 
	             } 
	         } 
	         public void setonRefreshListener(OnRefreshListener refreshListener) { 
	 
	              this.refreshListener = refreshListener; 
	 
	              isRefreshable = true; 
	 
	         }       
	          public interface OnRefreshListener { 
	              public void onRefresh(); 
	          }    
	        public void onRefreshComplete() { 
	             state = DONE; 
	              SimpleDateFormat format=new SimpleDateFormat("yyyy年MM月dd日  HH:mm"); 
	              String date=format.format(new Date()); 
	             lastUpdatedTextView.setText("最近更新:" + date); 
	             changeHeaderViewByState(); 
	          } 
	          private void onRefresh() { 
	            if (refreshListener != null) { 
	                 refreshListener.onRefresh(); 
	            } 
	          }  
	         // 此方法直接照搬自网络上的一个下拉刷新的demo,此处是“估计”headView的width以及height 
	          private void measureView(View child) { 
	             ViewGroup.LayoutParams p = child.getLayoutParams(); 
	                if (p == null) { 
	                     p = new ViewGroup.LayoutParams( 
	                            ViewGroup.LayoutParams.FILL_PARENT, 
	                             ViewGroup.LayoutParams.WRAP_CONTENT); 
	                 } 
	              int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width); 
	                int lpHeight = p.height; 
	                 int childHeightSpec; 
	                 if (lpHeight > 0) { 
	                     childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); 
	             } else { 
	               childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 
	                 } 
	                  child.measure(childWidthSpec, childHeightSpec); 
	        } 
	         public void setAdapter(BaseAdapter adapter) { 
	             SimpleDateFormat format=new SimpleDateFormat("yyyy年MM月dd日  HH:mm"); 
	            String date=format.format(new Date()); 
	             lastUpdatedTextView.setText("最近更新:" + date); 
	            super.setAdapter(adapter); 
	          } 
	}

 

 

package com.example.headpull;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Gravity;
import android.widget.FrameLayout.LayoutParams;
import android.widget.LinearLayout;
import android.widget.SimpleAdapter;

import com.example.headpull.PullToRefreshGridView.OnRefreshListener;

public class PullToRefreshGridViewActivity extends Activity {
    private SimpleAdapter citySimpleAdapter;
    public static LinearLayout head;
    String[] areaName = new String[] { "南京", "苏州", "无锡", "南通", "徐州", "常州",
           "扬州", "泰州", "盐城", "镇江", "淮安", "连云港", "宿迁" };
    // 存放13个城市
    private List<HashMap<String, String>> cityList = new ArrayList<HashMap<String, String>>();
    BadgeUtil badge;
    public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.head);
        BadgeUtil.setBadgeSamsung(this, 2);
       //数据模拟  城市初始化
       for (int i = 0; i < areaName.length * 6; i++) {
           HashMap<String, String> hashMap = new HashMap<String, String>();
           hashMap.put("id", String.valueOf(i));
           hashMap.put("name", areaName[i % 13].toString());
           cityList.add(hashMap);
       }
       final PullToRefreshGridView gridView = (PullToRefreshGridView) findViewById(R.id.order_form_grid);
       head = (LinearLayout) findViewById(R.id.head);
       LayoutParams p = new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT, Gravity.CENTER);
       //获取PullToRefreshGridView里面的head布局
       head.addView(gridView.getView(), p);
       
       
       citySimpleAdapter = new SimpleAdapter(this, cityList,
              R.layout.weather_textview, new String[] { "name" },
              new int[] { R.id.txtRepDlgCity });
       gridView.setAdapter(citySimpleAdapter);
       gridView.setonRefreshListener(new OnRefreshListener() {
           public void onRefresh() {
              new AsyncTask<Void, Void, Void>() {
                  protected Void doInBackground(Void... params) {
                     try {
                         Thread.sleep(1000);
                     } catch (Exception e) {
                         e.printStackTrace();
                     }
                     HashMap<String, String> hashMap = new HashMap<String, String>();
                     hashMap.put("id",String.valueOf(cityList.size()));
                     hashMap.put("name","刷新新增城市");
                     cityList.add(0,hashMap);
                     return null;
                  }
 
                  @Override
                  protected void onPostExecute(Void result) {
                     citySimpleAdapter.notifyDataSetChanged();
                     gridView.onRefreshComplete();
                  }
              }.execute();
           }
       });
    }
}

 

 

分享到:
评论

相关推荐

    android GridView下拉刷新

    在"android GridView下拉刷新"这一主题中,我们将深入探讨如何在GridView中实现这一功能。 首先,要实现GridView的下拉刷新,我们需要借助第三方库,如`SwipeRefreshLayout`。SwipeRefreshLayout是Android Support ...

    GridView下拉刷新完整代码

    本文将详细介绍如何在GridView中实现下拉刷新功能。 首先,我们需要引入一个支持下拉刷新的库。在Android开发中,SwipeRefreshLayout是一个常见的选择,它是Google提供的Android Support Library的一部分。...

    GridView下拉刷新 上拉加载

    "GridView下拉刷新 上拉加载"这个主题就是关于如何在GridView中实现这两种动态加载机制。 下拉刷新(Pull-to-Refresh)是当用户在顶部向下拉动列表时,显示刷新提示,并在完成更新内容后恢复到原始状态的功能。这一...

    gridview 下拉刷新

    "gridview 下拉刷新"这一主题就是关于如何为GridView实现类似瀑布流、列表等常见控件的下拉刷新效果。 在Android中,实现下拉刷新通常有两种方法:一种是自定义布局,另一种是使用第三方库。根据描述,这里采用的是...

    GridView上拉加载和下拉刷新

    问代码实现了Gridview上拉加载和下拉刷新。本代码主要依托第三的框架,上拉加载和下拉刷新,依托于pulltofresh,对于图片的展示和缓存,则依托于universualImageload.例子已经写好了,代码测试能运行。

    ListViewGridView下拉刷新,上拉加载更多

    ListViewGridView下拉刷新,上拉加载更多。很好用·

    gridview下拉刷新,懒加载

    本篇将深入探讨"gridview下拉刷新,懒加载"这一主题,以及如何在实际应用中实现这些功能。 1. 下拉刷新(Pull-to-Refresh) 下拉刷新是一种常见的UI交互设计,用户通过在列表顶部向下拉动以更新数据。在GridView或...

    listview gridview 上拉加载 下拉刷新 包含6个demo

    为了提升用户体验,"上拉加载"和"下拉刷新"功能应运而生。这些功能使得用户在接近列表顶部时可以刷新数据,在接近底部时可以加载更多内容,无需手动滚动到列表的起始或结束位置。 "上拉加载"通常称为"无限滚动"或...

    listView webView GridView 下拉刷新

    在Android开发中,下拉刷新(Pull-to-Refresh)是一种常见的功能,特别是在列表视图(ListView)、网格视图(GridView)以及Web视图(WebView)等需要展示大量数据的场景下。下拉刷新允许用户通过向下拉动界面来触发数据的...

    ScrollView ListView和GridView下拉刷新上拉加载更多

    至于文件"ScrollView_GridView_listViewRefresh_Demo",很可能是一个包含示例代码的项目,展示了如何在ScrollView、ListView和GridView中实现下拉刷新和上拉加载更多的功能。这个项目的源码可以作为学习和参考的资源...

    Android PullToRefresh (ListView GridView 下拉刷新) 程序源码使用详解

    本教程将详细讲解如何使用Android PullToRefresh库来实现ListView和GridView的下拉刷新功能。 首先,我们需要了解下拉刷新的基本原理。当用户在ListView或GridView顶部向下滑动时,视图会显示一个可拖动的头部,...

    Android 下拉刷新 上拉加载更过 GridView ListView ScorllView

    在Android应用开发中,"下拉刷新"和"上拉加载更多"是常见的用户体验功能,尤其是在数据列表展示中,如GridView、ListView和ScrollView等。这些功能使得用户在滚动到列表顶部时可以更新内容(下拉刷新),而在滚动到...

    Google play效果 listViewGridView下拉刷新上拉加载更多,图片加载OOm问题

    android 仿google play效果,ListView/GridView下拉刷新,上拉加载更多,自动加载异步请求数据以及分页数据 package net.xinhua.activity; import net.xinhuamm.widget.TouchViewPager; import android.os.Bundle; ...

    gridView下拉刷新、上拉加载

    总的来说,通过结合SwipeRefreshLayout实现下拉刷新,以及自定义OnScrollListener实现上拉加载,可以为GridView提供更加友好的用户交互体验。记得在处理数据加载时注意线程同步和UI更新的问题,以确保应用的稳定性和...

    listview和gridview下拉刷新,上拉加载更多

    与GridView类似,开发者可能在这里也使用了SwipeRefreshLayout来处理下拉刷新,通过监听滚动事件并在底部添加加载更多数据的逻辑。 在实际开发中,为了提高代码复用性和减少重复工作,开发者可能会创建一个通用的...

    ListView、gridView、scollView、WebView下拉刷新

    总的来说,下拉刷新是现代移动应用中不可或缺的功能,对于ListView、GridView、ScrollView和WebView,我们可以通过原生API、自定义实现或使用第三方库来实现这一功能,提升应用的用户体验。在具体实施过程中,需要...

    Android PullToRefresh (ListView GridView 下拉刷新) 使用详解

    在Android开发中,PullToRefresh(下拉刷新)是一个常见的功能,它允许用户通过在界面上下拉来更新内容,通常用于ListView和GridView等可滚动视图。本教程将详细介绍如何在Android应用中实现PullToRefresh功能,以及...

    android 自定义GridView 实现下拉刷新 底部加载更多

    5. **动画效果**:为了提供更好的用户体验,可以添加一些过渡动画,比如在下拉刷新时,GridView中的内容向上滑出,显示刷新动画;在加载更多时,Footer View可以显示加载进度条。 6. **错误处理**:在加载过程中,...

Global site tag (gtag.js) - Google Analytics