文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2023-05-30 21:58

关注

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

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);  }  }

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);    }   });  } }

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; 
    } 
 

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> 

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实现下拉加载功能问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯