[Java] Android系统上拉刷新功能的实现 →→→→→进入此内容的聊天室

来自 , 2020-08-16, 写在 Java, 查看 108 次.
URL http://www.code666.cn/view/21928905
  1. public class MyListView extends ListView implements OnScrollListener {
  2.  
  3.     public final int RATIO = 5;// 手拖动时,手指拖动距离与header下移的倍数
  4.     private final int LOADING = 0;// 正在加载
  5.     private final int RELEASE_To_REFRESH = 2;// 正在下拉状态,即将松手进行刷新
  6.     private final int DONE = 3;// 完成
  7.     private final int HIDE_To_REFRESH = 1;// 未下拉或已完成状态,设置padding为负值把header挡住
  8.  
  9.     private int refreshStatus;// 下拉刷新过程状态变量
  10.  
  11.     private LinearLayout hearderLayout;
  12.     private ImageView arrowImageView;
  13.     private ProgressBar progressBar;
  14.     private TextView tipsTextview;
  15.     private TextView lastUpdatedTime;
  16.     private int headContentHeight;
  17.     private int headContentWidth;
  18.     private RotateAnimation animation;
  19.     private RotateAnimation reverseAnimation;
  20.     private boolean isStartRefreshEvent = false;// 下拉刷新事件是否已经开始
  21.     private boolean isRefreshable = false;// 是否设置下拉刷新监听
  22.     private int firstItemIndex;
  23.  
  24.     private OnRefreshListener refreshListener;
  25.  
  26.     public MyListView (Context context) {
  27.         super(context);
  28.         init(context);
  29.     }
  30.  
  31.     public MyListView (Context context, AttributeSet attrs) {
  32.         super(context, attrs);
  33.         init(context);
  34.     }
  35.  
  36.     private void init(Context context) {
  37.  
  38.         LayoutInflater inflater = LayoutInflater.from(context);
  39.         hearderLayout = (LinearLayout) inflater.inflate(R.layout.list_view_header, null);
  40.         // 下拉箭头
  41.         arrowImageView = (ImageView) hearderLayout.findViewById(R.id.head_arrowImageView);
  42.         // 进度条
  43.         progressBar = (ProgressBar) hearderLayout.findViewById(R.id.head_progressBar);
  44.         // 下拉提示 刷新
  45.         tipsTextview = (TextView) hearderLayout.findViewById(R.id.head_tipsTextView);
  46.         // 最新一次刷新时间
  47.         lastUpdatedTime = (TextView) hearderLayout.findViewById(R.id.head_lastUpdatedTextView);
  48.         // 计算head的高宽
  49.         this.measureView(hearderLayout);
  50.         headContentHeight = hearderLayout.getMeasuredHeight();
  51.         headContentWidth = hearderLayout.getMeasuredWidth();
  52.  
  53.         // 初始状态是 隐藏掉head 布局
  54.         hearderLayout.setPadding(0, -1 * headContentHeight, 0, 0);
  55.         hearderLayout.invalidate();
  56.  
  57.         Log.e("sys", "width:" + headContentWidth + " height:" + headContentHeight);
  58.         // list添加头文件
  59.         addHeaderView(hearderLayout, null, false);
  60.         setOnScrollListener(this);// TODO
  61.         // 下拉以及恢复动画
  62.         animation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
  63.         animation.setInterpolator(new LinearInterpolator());
  64.         animation.setDuration(250);
  65.         animation.setFillAfter(true);
  66.         reverseAnimation = new RotateAnimation(-180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
  67.         reverseAnimation.setInterpolator(new LinearInterpolator());
  68.         reverseAnimation.setDuration(200);
  69.         reverseAnimation.setFillAfter(true);
  70.         refreshStatus = DONE;
  71.     }
  72.  
  73.     @Override
  74.     public void onScroll(AbsListView arg0, int firstVisiableItem, int arg2, int arg3) {
  75.         firstItemIndex = firstVisiableItem;
  76.     }
  77.  
  78.     @Override
  79.     public void onScrollStateChanged(AbsListView arg0, int arg1) {
  80.     }
  81.  
  82.     private int startY = 0;
  83.     @Override
  84.     public boolean onTouchEvent(MotionEvent event) {
  85.  
  86.         if (firstItemIndex == 0 && isRefreshable) {
  87.             switch (event.getAction()) {
  88.             // 在down时候记录当前Y的位置
  89.             case MotionEvent.ACTION_DOWN:
  90.                 if (!isStartRefreshEvent) {
  91.                     isStartRefreshEvent = true;
  92.                     startY = (int) event.getY();
  93.                 }
  94.                 break;
  95.  
  96.             case MotionEvent.ACTION_MOVE:
  97.  
  98.                 int tempY = (int) event.getY();
  99.                 int scrollY = (tempY - startY) / RATIO;
  100.  
  101.                 Log.i("sys", "拉开方向 " + scrollY);
  102.  
  103.                 if (!isStartRefreshEvent) {
  104.                     isStartRefreshEvent = true;
  105.                     startY = tempY;
  106.                 } else if (isStartRefreshEvent && refreshStatus != LOADING) {
  107.                     // 可以松手去刷新了
  108.                     if (refreshStatus == RELEASE_To_REFRESH) {
  109.                         setSelection(0);
  110.                         // header被用户拉下来后,又往上推了,推到了已经小于header高度时,则推回去,并取消刷新
  111.                         if (scrollY < headContentHeight && scrollY > 0) {
  112.                             refreshStatus = HIDE_To_REFRESH;
  113.                             this.changeHeaderView();
  114.                         }
  115.                         // 一下子推到顶了
  116.                         else if (scrollY <= 0) {
  117.                             refreshStatus = DONE;
  118.                             this.changeHeaderView();
  119.                         }
  120.                     }
  121.                     // 还没有到达显示松开刷新的时候,DONE或者是HIDE_To_REFRESH状态
  122.                     if (refreshStatus == HIDE_To_REFRESH) {
  123.                         setSelection(0);
  124.                         // 下拉至超过header本身高度后,可以进入RELEASE_TO_REFRESH的状态
  125.                         if (scrollY > headContentHeight) {
  126.                             refreshStatus = RELEASE_To_REFRESH;
  127.                             this.changeHeaderView();
  128.                         }
  129.                         // 上推到顶了
  130.                         else if (scrollY <= 0) {
  131.                             refreshStatus = DONE;
  132.                             this.changeHeaderView();
  133.                         }
  134.                     }
  135.                     // done状态下
  136.                     if (refreshStatus == DONE) {
  137.                         if (scrollY > 0) {
  138.                             refreshStatus = HIDE_To_REFRESH;
  139.                             this.changeHeaderView();
  140.                         }
  141.                     }
  142.                     // 更新headView的size
  143.                     if (refreshStatus == HIDE_To_REFRESH) {
  144.                         hearderLayout.setPadding(0, -1 * headContentHeight + scrollY, 0, 0);
  145.                     }
  146.                     // 更新headView的paddingTop
  147.                     if (refreshStatus == RELEASE_To_REFRESH) {
  148.                         hearderLayout.setPadding(0, scrollY - headContentHeight, 0, 0);
  149.                     }
  150.                 }
  151.                 break;
  152.  
  153.             case MotionEvent.ACTION_UP:
  154.                 if (refreshStatus != LOADING) {
  155.                     if (refreshStatus == DONE) {
  156.                         // 什么都不做
  157.                     }
  158.                     // 由下拉刷新状态,到done状态
  159.                     if (refreshStatus == HIDE_To_REFRESH) {
  160.                         refreshStatus = DONE;
  161.                         this.changeHeaderView();
  162.                     }
  163.  
  164.                     if (refreshStatus == RELEASE_To_REFRESH) {
  165.                         refreshStatus = LOADING;
  166.                         this.changeHeaderView();
  167.                         onRefresh();
  168.                     }
  169.                 }
  170.                 isStartRefreshEvent = false;
  171.                 break;
  172.  
  173.             }
  174.         }
  175.         return super.onTouchEvent(event);
  176.     }
  177.  
  178.     private void changeHeaderView() {
  179.         switch (refreshStatus) {
  180.         // 松开刷新状态
  181.         case RELEASE_To_REFRESH:
  182.             arrowImageView.setVisibility(View.VISIBLE);
  183.             progressBar.setVisibility(View.GONE);
  184.             tipsTextview.setVisibility(View.VISIBLE);
  185.             lastUpdatedTime.setVisibility(View.VISIBLE);
  186.             arrowImageView.clearAnimation();
  187.             arrowImageView.startAnimation(animation);
  188.             tipsTextview.setText("松开刷新");
  189.             break;
  190.         // 下拉刷新
  191.         case HIDE_To_REFRESH:
  192.             progressBar.setVisibility(View.GONE);
  193.             tipsTextview.setVisibility(View.VISIBLE);
  194.             lastUpdatedTime.setVisibility(View.VISIBLE);
  195.             arrowImageView.setVisibility(View.VISIBLE);
  196.             // 是由RELEASE_To_REFRESH状态转变来的
  197.             arrowImageView.clearAnimation();
  198.             arrowImageView.startAnimation(reverseAnimation);
  199.             tipsTextview.setText("下拉刷新");
  200.             break;
  201.         // 刷新中 状态
  202.         case LOADING:
  203.             hearderLayout.setPadding(0, 0, 0, 0);
  204.             progressBar.setVisibility(View.VISIBLE);
  205.             arrowImageView.clearAnimation();
  206.             arrowImageView.setVisibility(View.GONE);
  207.             tipsTextview.setText("正在刷新...");
  208.             lastUpdatedTime.setVisibility(View.VISIBLE);
  209.             break;
  210.         // 刷新完毕
  211.         case DONE:
  212.             hearderLayout.setPadding(0, -1 * headContentHeight, 0, 0);
  213.             progressBar.setVisibility(View.GONE);
  214.             arrowImageView.clearAnimation();
  215.             // arrowImageView.setImageResource(R.drawable.goicon);
  216.             tipsTextview.setText("下拉刷新");
  217.             lastUpdatedTime.setVisibility(View.VISIBLE);
  218.             break;
  219.         }
  220.     }
  221.  
  222.     public void setonRefreshListener(OnRefreshListener refreshListener) {
  223.         this.refreshListener = refreshListener;
  224.         isRefreshable = true;
  225.     }
  226.  
  227.     public interface OnRefreshListener {
  228.         public void onRefresh();
  229.     }
  230.  
  231.     public void onRefreshFinished() {
  232.         refreshStatus = DONE;
  233.         DateFormat format = new SimpleDateFormat("yyyy年MM月dd日  HH:mm");
  234.         String date = format.format(new Date());
  235.         lastUpdatedTime.setText("最近更新:" + date);
  236.         changeHeaderView();
  237.     }
  238.  
  239.     private void onRefresh() {
  240.         if (refreshListener != null) {
  241.             refreshListener.onRefresh();
  242.         }
  243.     }
  244.  
  245.     // 此方法计算高度
  246.     private void measureView(View child) {
  247.         ViewGroup.LayoutParams p = child.getLayoutParams();
  248.         if (p == null) {
  249.             p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
  250.         }
  251.         int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
  252.         int lpHeight = p.height;
  253.         int childHeightSpec;
  254.         if (lpHeight > 0) {
  255.             childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
  256.         } else {
  257.             childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
  258.         }
  259.         child.measure(childWidthSpec, childHeightSpec);
  260.     }
  261.  
  262.     public void setAdapter(BaseAdapter adapter) {
  263.         DateFormat format = new SimpleDateFormat("yyyy年MM月dd日  HH:mm");
  264.         String date = format.format(new Date());
  265.         lastUpdatedTime.setText("最近更新:" + date);
  266.         super.setAdapter(adapter);
  267.     }
  268. }
  269.  
  270.  
  271. //java/6813

回复 "Android系统上拉刷新功能的实现"

这儿你可以回复上面这条便签

captcha