自定义ListView实现下拉刷新

本文介绍了一种自定义实现带有下拉刷新功能的ListView组件的方法。通过重写ListView并添加头部视图来实现下拉刷新效果,同时详细展示了如何处理触摸事件、状态变化以及与界面元素的交互。

第一次刷新:


第二次刷新:


ListView上面的header文件布局:

<?xml version="1.0" encoding="utf-8"?>
<!-- ListView的头部 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="#00000000" >


    <!-- 内容 -->


    <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/iv_arrow"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:src="@drawable/arrow" />


            <!-- 进度条 -->


            <ProgressBar
                android:id="@+id/progressBar"
                style="?android:attr/progressBarStyleSmall"
                android:layout_width="50dp"
                android:layout_height="50dp"
                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/tv_state"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="下拉刷新"
                android:textColor="#FF000000"
                android:textSize="20sp" />


            <!-- 最近更新 -->


            <TextView
                android:id="@+id/tv_updateTime"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text=""
                android:textColor="#FFFF0000"
                android:textSize="10sp" />
        </LinearLayout>
    </RelativeLayout>


</LinearLayout>


自定义ListView:

package com.example.customlistview;


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


import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;


public class CustomListView extends ListView{
View header;
TextView tvState;
TextView upDateTime;
ProgressBar progressBar;
int viewHeight;
ImageView ivArror;
int downY;
byte currentState;
public static final byte STATE_DONE=0;
public static final byte STATE_PULL=1;
public static final byte STATE_RELEASE=2;
public static final byte STATE_REFRESHING=3;
    String time="";
OnRefreshListener onRefreshListener;

public void setOnRefershListener(OnRefreshListener onRefreshListener){
this.onRefreshListener=onRefreshListener;
}
public CustomListView(Context context, AttributeSet attrs) {
super(context, attrs);
currentState=STATE_DONE;
header=View.inflate(context, R.layout.list_header,null);
tvState=(TextView) header.findViewById(R.id.tv_state);
progressBar=(ProgressBar) header.findViewById(R.id.progressBar);
ivArror=(ImageView) header.findViewById(R.id.iv_arrow);
upDateTime=(TextView) header.findViewById(R.id.tv_updateTime);
this.addHeaderView(header);
header.measure(0, 0);
viewHeight=header.getMeasuredHeight();
//header.setPadding(left, top, right, bottom);
header.setPadding(0, -viewHeight, 0, 0);
}


@Override
public boolean onTouchEvent(MotionEvent ev) {
int action=ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
             if(this.currentState==STATE_DONE){
            this.currentState=STATE_PULL;
            this.downY=(int) ev.getY();
             }
break;


case MotionEvent.ACTION_MOVE:
             if(currentState==STATE_PULL){
            int moveY=(int) ev.getY();
            int top=-viewHeight+moveY-downY;
            header.setPadding(0, top, 0, 0);
            if(moveY-downY>viewHeight){
            this.currentState=STATE_RELEASE;
            tvState.setText("松开刷新");
            if("".equals(time)){
            upDateTime.setText(time); 
            }else{
            upDateTime.setText("上次刷新:"+time);
            }
            }
             }
break;
case MotionEvent.ACTION_UP:
            if(currentState==STATE_RELEASE){
            currentState=STATE_REFRESHING;
            tvState.setText("刷新中");
            ivArror.setVisibility(View.GONE);
            progressBar.setVisibility(View.VISIBLE);
            if (onRefreshListener != null) {
onRefreshListener.onRefresh(this);
}
            }
break;
}
return super.onTouchEvent(ev);
}
   public String getDate(){
  SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm");
  String date=sdf.format(new Date());
  return date;
   }
   public void refreshComplete(){
  progressBar.setVisibility(View.GONE);
  ivArror.setVisibility(View.VISIBLE);
  tvState.setText("下拉刷新");
  time=getDate();
  upDateTime.setText("本次刷新:"+time);
  header.setPadding(0 , -viewHeight, 0, 0);
       currentState=STATE_DONE;
       
   }
   interface OnRefreshListener{
  public void onRefresh(CustomListView customListView);
   }
}


MainActivity:

public class MainActivity extends Activity {
CustomListView customListView;
ArrayList<String> list=new ArrayList<String>();
MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setUpView();
}
private void setUpView() {
customListView=(CustomListView) findViewById(R.id.customView);
list.add("dadwa");list.add("dadfewwa");
list.add("dfwadwa");list.add("dafewedwa");
list.add("datrdwa");list.add("da4t3dwa");
adapter=new MyAdapter(this, list);
customListView.setAdapter(adapter);
customListView.setOnRefershListener(new OnRefreshListener() {
@Override
public void onRefresh(final CustomListView customListView) {
//模拟联网刷新
new Thread(){
public void run() {
try {
this.currentThread().sleep(5000);
for(int i=0;i<10;i++){
list.add(""+i);
}
runOnUiThread(new Runnable() {
public void run() {
adapter.notifyDataSetChanged();
customListView.refreshComplete();
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
};
}.start();
}
});
}

内容概要:本文介绍了一个基于多传感器融合的定位系统设计方案,采用GPS、里程计和电子罗盘作为定位传感器,利用扩展卡尔曼滤波(EKF)算法对多源传感器数据进行融合处理,最终输出目标的滤波后位置信息,并提供了完整的Matlab代码实现。该方法有效提升了定位精度与稳定性,尤其适用于存在单一传感器误差或信号丢失的复杂环境,如自动驾驶、移动采用GPS、里程计和电子罗盘作为定位传感器,EKF作为多传感器的融合算法,最终输出目标的滤波位置(Matlab代码实现)机器人导航等领域。文中详细阐述了各传感器的数据建模方式、状态转移与观测方程构建,以及EKF算法的具体实现步骤,具有较强的工程实践价值。; 适合人群:具备一定Matlab编程基础,熟悉传感器原理和滤波算法的高校研究生、科研人员及从事自动驾驶、机器人导航等相关领域的工程技术人员。; 使用场景及目标:①学习和掌握多传感器融合的基本理论与实现方法;②应用于移动机器人、无人车、无人机等系统的高精度定位与导航开发;③作为EKF算法在实际工程中应用的教学案例或项目参考; 阅读建议:建议读者结合Matlab代码逐行理解算法实现过程,重点关注状态预测与观测更新模块的设计逻辑,可尝试引入真实传感器数据或仿真噪声环境以验证算法鲁棒性,并进一步拓展至UKF、PF等更高级滤波算法的研究与对比。
内容概要:文章围绕智能汽车新一代传感器的发展趋势,重点阐述了BEV(鸟瞰图视角)端到端感知融合架构如何成为智能驾驶感知系统的新范式。传统后融合与前融合方案因信息丢失或算力需求过高难以满足高阶智驾需求,而基于Transformer的BEV融合方案通过统一坐标系下的多源传感器特征融合,在保证感知精度的同时兼顾算力可行性,显著提升复杂场景下的鲁棒性与系统可靠性。此外,文章指出BEV模型落地面临大算力依赖与高数据成本的挑战,提出“数据采集-模型训练-算法迭代-数据反哺”的高效数据闭环体系,通过自动化标注与长尾数据反馈实现算法持续进化,降低对人工标注的依赖,提升数据利用效率。典型企业案例进一步验证了该路径的技术可行性与经济价值。; 适合人群:从事汽车电子、智能驾驶感知算法研发的工程师,以及关注自动驾驶技术趋势的产品经理和技术管理者;具备一定自动驾驶基础知识,希望深入了解BEV架构与数据闭环机制的专业人士。; 使用场景及目标:①理解BEV+Transformer为何成为当前感知融合的主流技术路线;②掌握数据闭环在BEV模型迭代中的关键作用及其工程实现逻辑;③为智能驾驶系统架构设计、传感器选型与算法优化提供决策参考; 阅读建议:本文侧重技术趋势分析与系统级思考,建议结合实际项目背景阅读,重点关注BEV融合逻辑与数据闭环构建方法,并可延伸研究相关企业在舱泊一体等场景的应用实践。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值