栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

Android自定义listview布局实现上拉加载下拉刷新功能

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android自定义listview布局实现上拉加载下拉刷新功能

listview实现上拉加载以及下拉刷新的方式有很多。下面是我写的一种自定义的布局,复用性也比较的强。首先就是继承的listview的自定义view。

     AutoListView.Java:

package com.example.mic.testdemo.view; 
import android.annotation.TargetApi; 
import android.content.Context; 
import android.os.Build; 
import android.os.Bundle; 
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.Animation; 
import android.view.animation.LinearInterpolator; 
import android.view.animation.RotateAnimation; 
import android.widget.AbsListView; 
import android.widget.ImageView; 
import android.widget.ListView; 
import android.widget.ProgressBar; 
import android.widget.TextView; 
import com.example.mic.testdemo.R; 
import java.text.SimpleDateFormat; 
 
public class AutoListView extends ListView implements AbsListView.onScrollListener { 
  public static final String FOOTER = "FOOTER"; 
  public static final String HEADER = "HEADER"; 
  private static final int PULL = 1; 
  private static final int NONE = 0; 
  //  private static final int RELEASE = 2; 
  private static final int REFRESHING = 2; 
  private static final int SPACE = 20; 
  private static final String TAG = "AutoListView"; 
  private RotateAnimation downAnimation; 
  private RotateAnimation upAnimation; 
  private Context context; 
  private LayoutInflater inflater; 
  private View footer; 
  private View header; 
  private int headerContentInitialHeight; 
  private int headerContentHeight; 
  private onRefreshListener onRefreshListener; 
  private boolean loadEnable; 
  private onLoadListener onLoadListener; 
  private int firstVisibleItem; 
  private boolean isLoadingMore = false; 
  private int startY; 
  private int state; 
  private ImageView iv_pull; 
  private int footerViewHeight; 
  private ProgressBar mProgressBar; 
  private TextView tvState; 
  private TextView tvLastUpdateTime; 
  private boolean isScrollToBottom; 
  public AutoListView(Context context) { 
    super(context); 
    initView(context); 
  } 
  public AutoListView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    initView(context); 
  } 
  public AutoListView(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
    initView(context); 
  } 
  @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
  public AutoListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
    super(context, attrs, defStyleAttr, defStyleRes); 
    initView(context); 
  } 
  private void initView(Context context) { 
    initHeaderView(); 
    initFooterView(); 
    this.setonScrollListener(this); 
// 
  } 
  private void initHeaderView() { 
    header = View.inflate(getContext(), R.layout.pull_to_refresh_header, null); 
    iv_pull = (ImageView) header 
 .findViewById(R.id.iv_pull); 
    mProgressBar = (ProgressBar) header 
 .findViewById(R.id.pb_listview_header); 
    tvState = (TextView) header 
 .findViewById(R.id.tv_listview_header_state); 
    tvLastUpdateTime = (TextView) header 
 .findViewById(R.id.tv_listview_header_last_update_time); 
    // 设置最后刷新时间 
    tvLastUpdateTime.setText("最后刷新时间: " + getLastUpdateTime()); 
    header.measure(0, 0); // 系统会帮我们测量出headerView的高度 
    headerContentHeight = header.getMeasuredHeight(); 
    header.setPadding(0, -headerContentHeight, 0, 0); 
    this.addHeaderView(header,HEADER,true); // 向ListView的顶部添加一个view对象 
    initAnimation(); 
  } 
  private void initAnimation() { 
    upAnimation = new RotateAnimation(0f, -180f, 
 Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 
 0.5f); 
    upAnimation.setDuration(500); 
    upAnimation.setFillAfter(true); // 动画结束后, 停留在结束的位置上 
    downAnimation = new RotateAnimation(-180f, -360f, 
 Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 
 0.5f); 
    downAnimation.setDuration(500); 
    downAnimation.setFillAfter(true); // 动画结束后, 停留在结束的位置上 
  } 
  private String getLastUpdateTime() { 
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
    return sdf.format(System.currentTimeMillis()); 
  } 
  private void initFooterView() { 
    footer = View.inflate(getContext(), R.layout.foot_view, null); 
    footer.measure(0, 0); 
    footerViewHeight = footer.getMeasuredHeight(); 
    footer.setPadding(0, -footerViewHeight, 0, 0); 
    this.addFooterView(footer,FOOTER,true); 
  } 
  private void measureView(View child) { 
    ViewGroup.LayoutParams p = child.getLayoutParams(); 
    if (p == null) { 
      p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_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);//得到的是size。 
    } else { 
      childHeightSpec = MeasureSpec.makeMeasureSpec(0, 
   MeasureSpec.UNSPECIFIED);//得到的是子布局的实际大小。 
    } 
    child.measure(childWidthSpec, childHeightSpec); 
  } 
  private void topPadding(int topPadding) { 
    header.setPadding(header.getPaddingLeft(), topPadding, 
 header.getPaddingRight(), header.getPaddingBottom()); 
    header.invalidate(); 
  } 
  @Override 
  public void onScrollStateChanged(AbsListView absListView, int i) { 
    if (i == SCROLL_STATE_IDLE 
 || i == SCROLL_STATE_FLING) { 
      // 判断当前是否已经到了底部 
      if (isScrollToBottom && !isLoadingMore) { 
 isLoadingMore = true; 
 // 当前到底部 
 Log.i(TAG, "加载更多数据"); 
 footer.setPadding(0, 0, 0, 0); 
 this.setSelection(this.getCount()); 
 if (onLoadListener != null) { 
   onLoadListener.onLoad(); 
 } 
      } 
    } 
  } 
  @Override 
  public void onScroll(AbsListView absListView, int i, int i1, int i2) { 
    this.firstVisibleItem = i; 
    if (getLastVisiblePosition() == (i2 - 1)) { 
      isScrollToBottom = true; 
    } else { 
      isScrollToBottom = false; 
    } 
  } 
  @Override 
  public boolean onTouchEvent(MotionEvent ev) { 
    switch (ev.getAction()) { 
// 
      case MotionEvent.ACTION_DOWN: 
 startY = (int) ev.getY(); 
 break; 
      case MotionEvent.ACTION_MOVE: 
 int moveY = (int) ev.getY(); 
 // 移动中的y - 按下的y = 间距. 
 int diff = (moveY - startY) / 2; 
 // -头布局的高度 + 间距 = paddingTop 
 int paddingTop = -headerContentHeight + diff; 
 // 如果: -头布局的高度 > paddingTop的值 执行super.onTouchEvent(ev); 
 if (firstVisibleItem == 0 
     && -headerContentHeight < paddingTop) { 
   if (paddingTop > 0 && state == NONE) { // 完全显示了. 
     Log.i(TAG, "松开刷新"); 
     state = PULL; 
     refreshHeaderViewByState(); 
   } else if (paddingTop < 0 
&& state == PULL) { // 没有显示完全 
     Log.i(TAG, "下拉刷新"); 
     state = NONE; 
     refreshHeaderViewByState(); 
   } 
   // 下拉头布局 
   header.setPadding(0, paddingTop, 0, 0); 
 } 
 break; 
      case MotionEvent.ACTION_UP: 
 // 判断当前的状态是松开刷新还是下拉刷新 
 if (state == PULL) { 
   Log.i(TAG, "刷新数据."); 
   // 把头布局设置为完全显示状态 
   header.setPadding(0, 0, 0, 0); 
   // 进入到正在刷新中状态 
   state = REFRESHING; 
   refreshHeaderViewByState(); 
   if (onRefreshListener != null) { 
     onRefreshListener.onRefresh(); // 调用使用者的监听方法 
   } 
 } else if (state == NONE) { 
   // 隐藏头布局 
   header.setPadding(0, -headerContentHeight, 0, 0); 
 } 
 break; 
      default: 
 break; 
    } 
    return super.onTouchEvent(ev); 
  } 
// 
  private void refreshHeaderViewByState() { 
    switch (state) { 
// 
      case NONE: // 下拉刷新状态 
 tvState.setText("下拉刷新"); 
 iv_pull.startAnimation(downAnimation); // 执行向下旋转 
 break; 
      case PULL: // 松开刷新状态 
 tvState.setText("松开刷新"); 
 iv_pull.startAnimation(upAnimation); // 执行向上旋转 
 break; 
      case REFRESHING: // 正在刷新中状态 
 iv_pull.clearAnimation(); 
 iv_pull.setVisibility(View.GONE); 
 mProgressBar.setVisibility(View.VISIBLE); 
 tvState.setText("正在刷新中..."); 
 break; 
      default: 
 break; 
    } 
  } 
  public void hideHeaderView() { 
    header.setPadding(0, -headerContentHeight, 0, 0); 
    iv_pull.setVisibility(View.VISIBLE); 
    mProgressBar.setVisibility(View.GONE); 
    tvState.setText("下拉刷新"); 
    tvLastUpdateTime.setText("最后刷新时间: " + getLastUpdateTime()); 
    state = NONE; 
  } 
  public void hideFooterView() { 
    footer.setPadding(0, -footerViewHeight, 0, 0); 
    isLoadingMore = false; 
  } 
  public void setonRefreshListener(onRefreshListener onRefreshListener) { 
    this.onRefreshListener = onRefreshListener; 
  } 
  public void setonLoadListener(onLoadListener onLoadListener) { 
    this.onLoadListener = onLoadListener; 
  } 
  public void onRefresh() { 
    if (onRefreshListener != null) { 
      onRefreshListener.onRefresh(); 
    } 
  } 
  public void onLoad() { 
    if (onLoadListener != null) { 
      onLoadListener.onLoad(); 
    } 
  } 
  public interface onRefreshListener {//定义下拉刷新接口 
    public void onRefresh(); 
  } 
  public interface onLoadListener {//定义上拉加载更多 
    public void onLoad(); 
  } 
} 

        上面的代码就是实现的关键.下面是头布局以及脚布局:

foot_view.xml:

 
 
   
 

pull_to_refresh_header.xml:

 
 
   
     
     
   
   
     
     
   
 

activity_main.xml:

 
 
       
 

      上面所完成的步骤就是在listview上下加载不同的布局,上面也是要复用的代码,下面的代码就是怎么使用的代码了.

MainActivity.java:

public class MainActivity extends AppCompatActivity implements AutoListView.OnLoadListener,AutoListView.onRefreshListener { 
  private TextView textView; 
  private String result; 
  private AutoListView listView; 
  private MyAdater adater; 
  @Override 
  protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    listView = (AutoListView) findViewById(R.id.lv);} 
listView.setonRefreshListener(MainActivity.this); 
listView.setonLoadListener(MainActivity.this); 
@Override 
  public void onLoad() { 
  } 
  @Override 
  public void onRefresh() {} 

下面就是实现,就是在你需要的地方设置监听,以及上面加载以及刷新需要的操作就可以了!

以上所述是小编给大家介绍的Android自定义listview布局实现上拉加载下拉刷新功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对考高分网网站的支持!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/160340.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号