温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Android中怎么利用ListView实现下拉加载功能

发布时间:2021-06-26 17:05:05 来源:亿速云 阅读:444 作者:Leah 栏目:移动开发

Android中怎么利用ListView实现下拉加载功能,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

1、MyListView.Java

public class MyListView extends ListView implements OnScrollListener {     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;     // ListView头部下拉刷新的布局   private LinearLayout headerView;   private TextView lvHeaderTipsTv;   private TextView lvHeaderLastUpdatedTv;   private ImageView lvHeaderArrowIv;   private ProgressBar lvHeaderProgressBar;     // 定义头部下拉刷新的布局的高度   private int headerContentHeight;     private RotateAnimation animation;   private RotateAnimation reverseAnimation;     private int startY;   private int state;   private boolean isBack;     // 用于保证startY的值在一个完整的touch事件中只被记录一次   private boolean isRecored;     private OnRefreshListener refreshListener;     private boolean isRefreshable;     public MyListView(Context context) {    super(context);    init(context);   }     public MyListView(Context context, AttributeSet attrs) {    super(context, attrs);    init(context);   }     private void init(Context context) {    inflater = LayoutInflater.from(context);    headerView = (LinearLayout) inflater.inflate(R.layout.lv_header, null);    lvHeaderTipsTv = (TextView) headerView      .findViewById(R.id.lvHeaderTipsTv);    lvHeaderLastUpdatedTv = (TextView) headerView      .findViewById(R.id.lvHeaderLastUpdatedTv);      lvHeaderArrowIv = (ImageView) headerView      .findViewById(R.id.lvHeaderArrowIv);    // 设置下拉刷新图标的最小高度和宽度    lvHeaderArrowIv.setMinimumWidth(70);    lvHeaderArrowIv.setMinimumHeight(50);      lvHeaderProgressBar = (ProgressBar) headerView      .findViewById(R.id.lvHeaderProgressBar);    measureView(headerView);    headerContentHeight = headerView.getMeasuredHeight();    // 设置内边距,正好距离顶部为一个负的整个布局的高度,正好把头部隐藏    headerView.setPadding(0, -1 * headerContentHeight, 0, 0);    // 重绘一下    headerView.invalidate();    // 将下拉刷新的布局加入ListView的顶部    addHeaderView(headerView, null, false);    // 设置滚动监听事件    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);      // 一开始的状态就是下拉刷新完的状态,所以为DONE    state = DONE;    // 是否正在刷新    isRefreshable = false;   }     @Override   public void onScrollStateChanged(AbsListView view, int scrollState) {     }     @Override   public void onScroll(AbsListView view, int firstVisibleItem,     int visibleItemCount, int totalItemCount) {    if (firstVisibleItem == 0) {     isRefreshable = true;    } else {     isRefreshable = false;    }   }     @Override   public boolean onTouchEvent(MotionEvent ev) {    if (isRefreshable) {     switch (ev.getAction()) {     case MotionEvent.ACTION_DOWN:      if (!isRecored) {       isRecored = true;       startY = (int) ev.getY();// 手指按下时记录当前位置      }      break;     case MotionEvent.ACTION_UP:      if (state != REFRESHING && state != LOADING) {       if (state == PULL_To_REFRESH) {        state = DONE;        changeHeaderViewByState();       }       if (state == RELEASE_To_REFRESH) {        state = REFRESHING;        changeHeaderViewByState();        onLvRefresh();       }      }      isRecored = false;      isBack = false;        break;       case MotionEvent.ACTION_MOVE:      int tempY = (int) ev.getY();      if (!isRecored) {       isRecored = true;       startY = tempY;      }      if (state != REFRESHING && isRecored && state != LOADING) {       // 保证在设置padding的过程中,当前的位置一直是在head,否则如果当列表超出屏幕的话,当在上推的时候,列表会同时进行滚动       // 可以松手去刷新了       if (state == RELEASE_To_REFRESH) {        setSelection(0);        // 往上推了,推到了屏幕足够掩盖head的程度,但是还没有推到全部掩盖的地步        if (((tempY - startY) / RATIO < headerContentHeight)// 由松开刷新状态转变到下拉刷新状态          && (tempY - startY) > 0) {         state = PULL_To_REFRESH;         changeHeaderViewByState();        }        // 一下子推到顶了        else if (tempY - startY <= 0) {// 由松开刷新状态转变到done状态         state = DONE;         changeHeaderViewByState();        }       }       // 还没有到达显示松开刷新的时候,DONE或者是PULL_To_REFRESH状态       if (state == PULL_To_REFRESH) {        setSelection(0);        // 下拉到可以进入RELEASE_TO_REFRESH的状态        if ((tempY - startY) / RATIO >= headerContentHeight) {// 由done或者下拉刷新状态转变到松开刷新         state = RELEASE_To_REFRESH;         isBack = true;         changeHeaderViewByState();        }        // 上推到顶了        else if (tempY - startY <= 0) {// 由DOne或者下拉刷新状态转变到done状态         state = DONE;         changeHeaderViewByState();        }       }       // done状态下       if (state == DONE) {        if (tempY - startY > 0) {         state = PULL_To_REFRESH;         changeHeaderViewByState();        }       }       // 更新headView的size       if (state == PULL_To_REFRESH) {        headerView.setPadding(0, -1 * headerContentHeight          + (tempY - startY) / RATIO, 0, 0);         }       // 更新headView的paddingTop       if (state == RELEASE_To_REFRESH) {        headerView.setPadding(0, (tempY - startY) / RATIO          - headerContentHeight, 0, 0);       }        }      break;       default:      break;     }    }    return super.onTouchEvent(ev);   }     // 当状态改变时候,调用该方法,以更新界面   private void changeHeaderViewByState() {    switch (state) {    case RELEASE_To_REFRESH:     lvHeaderArrowIv.setVisibility(View.VISIBLE);     lvHeaderProgressBar.setVisibility(View.GONE);     lvHeaderTipsTv.setVisibility(View.VISIBLE);     lvHeaderLastUpdatedTv.setVisibility(View.VISIBLE);       lvHeaderArrowIv.clearAnimation();// 清除动画     lvHeaderArrowIv.startAnimation(animation);// 开始动画效果       lvHeaderTipsTv.setText("松开刷新");     break;    case PULL_To_REFRESH:     lvHeaderProgressBar.setVisibility(View.GONE);     lvHeaderTipsTv.setVisibility(View.VISIBLE);     lvHeaderLastUpdatedTv.setVisibility(View.VISIBLE);     lvHeaderArrowIv.clearAnimation();     lvHeaderArrowIv.setVisibility(View.VISIBLE);     // 是由RELEASE_To_REFRESH状态转变来的     if (isBack) {      isBack = false;      lvHeaderArrowIv.clearAnimation();      lvHeaderArrowIv.startAnimation(reverseAnimation);        lvHeaderTipsTv.setText("下拉刷新");     } else {      lvHeaderTipsTv.setText("下拉刷新");     }     break;      case REFRESHING:       headerView.setPadding(0, 0, 0, 0);       lvHeaderProgressBar.setVisibility(View.VISIBLE);     lvHeaderArrowIv.clearAnimation();     lvHeaderArrowIv.setVisibility(View.GONE);     lvHeaderTipsTv.setText("正在刷新...");     lvHeaderLastUpdatedTv.setVisibility(View.VISIBLE);     break;    case DONE:     headerView.setPadding(0, -1 * headerContentHeight, 0, 0);       lvHeaderProgressBar.setVisibility(View.GONE);     lvHeaderArrowIv.clearAnimation();     lvHeaderArrowIv.setImageResource(R.drawable.arrow);     lvHeaderTipsTv.setText("下拉刷新");     lvHeaderLastUpdatedTv.setVisibility(View.VISIBLE);     break;    }   }     // 此方法直接照搬自网络上的一个下拉刷新的demo,此处是“估计”headView的width以及height   private void measureView(View child) {    ViewGroup.LayoutParams params = child.getLayoutParams();    if (params == null) {     params = new ViewGroup.LayoutParams(       ViewGroup.LayoutParams.FILL_PARENT,       ViewGroup.LayoutParams.WRAP_CONTENT);    }    int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0,      params.width);    int lpHeight = params.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 setonRefreshListener(OnRefreshListener refreshListener) {    this.refreshListener = refreshListener;    isRefreshable = true;   }     public interface OnRefreshListener {    public void onRefresh();   }     public void onRefreshComplete() {    state = DONE;    lvHeaderLastUpdatedTv.setText("最近更新:" + new Date().toLocaleString());    changeHeaderViewByState();   }     private void onLvRefresh() {    if (refreshListener != null) {     refreshListener.onRefresh();    }   }     public void setAdapter(LvAdapter adapter) {    lvHeaderLastUpdatedTv.setText("最近更新:" + new Date().toLocaleString());    super.setAdapter(adapter);   }    }

2、MainActivity.java

public class MainActivity extends Activity {   private List<String> list;   private MyListView lv;   private LvAdapter adapter;     @Override   protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.main);    lv = (MyListView) findViewById(R.id.lv);    list = new ArrayList<String>();    list.add("loonggg");    list.add("我们都是开发者");    list.add("我们都是开发者");    list.add("我们都是开发者");    list.add("我们都是开发者");    list.add("我们都是开发者");    list.add("我们都是开发者");    list.add("我们都是开发者");    list.add("我们都是开发者");    list.add("我们都是开发者");    list.add("我们都是开发者");    list.add("我们都是开发者");    list.add("我们都是开发者");    list.add("我们都是开发者");    list.add("我们都是开发者");    list.add("我们都是开发者");    list.add("我们都是开发者");    adapter = new LvAdapter(list, this);    lv.setAdapter(adapter);      lv.setonRefreshListener(new OnRefreshListener() {       @Override     public void onRefresh() {      new AsyncTask<Void, Void, Void>() {       protected Void doInBackground(Void... params) {        try {         Thread.sleep(1000);        } catch (Exception e) {         e.printStackTrace();        }        list.add("刷新后添加的内容");        return null;       }         @Override       protected void onPostExecute(Void result) {        adapter.notifyDataSetChanged();        lv.onRefreshComplete();       }      }.execute(null, null, null);     }    });   }  }

3、LvAdapter
public class LvAdapter extends BaseAdapter { 
    private List<String> list; 
    private Context context; 
 
    public LvAdapter(List<String> list, Context context) { 
        this.list = list; 
        this.context = context; 
    } 
 
    @Override 
    public int getCount() { 
        return list.size(); 
    } 
 
    @Override 
    public Object getItem(int position) { 
        return list.get(position); 
    } 
 
    @Override 
    public long getItemId(int position) { 
        return position; 
    } 
 
    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
        TextView tv = new TextView(context.getApplicationContext()); 
        tv.setText(list.get(position)); 
        return tv; 
    } 
 

4、lv_header.xml
[html] view plain copy
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:background="#000000" > 
 
    <!-- 内容 --> 
 
    <RelativeLayout 
        android:id="@+id/head_contentLayout" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:paddingLeft="30dp" > 
 
        <!-- 箭头图像、进度条 --> 
 
        <FrameLayout 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_alignParentLeft="true" 
            android:layout_centerVertical="true" > 
 
            <!-- 箭头 --> 
 
            <ImageView 
                android:id="@+id/lvHeaderArrowIv" 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content" 
                android:layout_gravity="center" 
                android:src="@drawable/arrow" /> 
 
            <!-- 进度条 --> 
 
            <ProgressBar 
                android:id="@+id/lvHeaderProgressBar" 
                 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content" 
                android:layout_gravity="center" 
                android:visibility="gone" /> 
        </FrameLayout> 
 
        <!-- 提示、最近更新 --> 
 
        <LinearLayout 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_centerHorizontal="true" 
            android:gravity="center_horizontal" 
            android:orientation="vertical" > 
 
            <!-- 提示 --> 
 
            <TextView 
                android:id="@+id/lvHeaderTipsTv" 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content" 
                android:text="下拉刷新" 
                android:textColor="#fff" 
                android:textSize="20sp" /> 
 
            <!-- 最近更新 --> 
 
            <TextView 
                android:id="@+id/lvHeaderLastUpdatedTv" 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content" 
                android:text="上次更新" 
                android:textColor="#333" 
                android:textSize="10sp" /> 
        </LinearLayout> 
    </RelativeLayout> 
 
</LinearLayout> 

5、main.xml
[html] view plain copy
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="#000000" 
    android:orientation="vertical" > 
 
    <net.loonggg.listview.MyListView 
        android:id="@+id/lv" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" /> 
 
</LinearLayout> 

关于Android中怎么利用ListView实现下拉加载功能问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI