自定义可拖拽GridView控件

1、概述

项目要求一个可拖拽的gridview功能,主要是可以长按图标,然后手指移动到对应位置,松开后图标移动到对应手指松开的位置,后面的图标依次挪移一个position。

2、效果图

第一张图片是拖拽之前的效果图,第二张图片是拖拽后的效果图

3、重写dispatchTouchEvent方法

/**
 * 长按的Runnable
 */
private Runnable mLongClickRunable = new Runnable() {
    @Override
    public void run() {
        isDrag = true;
        //mVibrator.vibrate(200);
        //隐藏该item
        mDragView.setVisibility(INVISIBLE);
        //在点击的地方创建并显示item镜像
        createDragView(mDragBitmap, mDownX, mDownY);
    }
};
/**
 * 当moveY的值大于向上滚动的边界值,触发GridView自动向上滚动
 * 当moveY的值小于向下滚动的边界值,触犯GridView自动向下滚动
 * 否则不进行滚动
 */
private Runnable mScrollRunbale = new Runnable() {
    @Override
    public void run() {
        int scrollY = 0;
        if (mMoveY > mUpScrollBorder){
            scrollY = mSpeed;
            mHandler.postDelayed(mScrollRunbale,25);
        }else if (mMoveY < mDownScrollBorder){
            scrollY = -mSpeed;
            mHandler.postDelayed(mScrollRunbale,25);
        }else {
            scrollY = 0;
            mHandler.removeCallbacks(mScrollRunbale);
        }
        smoothScrollBy(scrollY,10);
    }
};

5、对外暴露的方法

/************************对外提供的接口***************************************/
public boolean isDrag() {
    return isDrag;
}
//设置是否可拖拽
public void setDrag(boolean drag) {
    isDrag = drag;
}
public long getDragResponseMs() {
    return mDragResponseMs;
}
//设置长按响应时长
public void setDragResponseMs(long mDragResponseMs) {
    this.mDragResponseMs = mDragResponseMs;
}
public void setOnItemChangeListener(OnItemChangeListener changeListener) {
    this.changeListener = changeListener;
}
/******************************************************************************/

6、如何在页面中调用

DragGridView dragGridView = findViewById(R.id.dgv);
dragGridView.setNumColumns(NUM_COLUMNS);
initData();
mMoreColorTypeAdapter = new MoreColorTypeAdapter(this, true, data, NUM_COLUMNS);
dragGridView.setAdapter(mMoreColorTypeAdapter);
dragGridView.setOnItemClickListener(this);
dragGridView.setOnItemChangeListener(new DragGridView.OnItemChangeListener() {
    @Override
    public void onChange(int from, int to) {
        Data dataBean = data.get(from);
        //直接交互
        //Collections.swap(dataSourceList,from,to);
        //非直接交互 这里的处理需要注意下 排序交换
        if(from < to){
            for(int i = from; i < to; i++){
                Collections.swap(data, i, i + 1);
            }
        }else if(from > to){
            for(int i = from; i > to; i--){
                Collections.swap(data, i, i - 1);
            }
        }
        data.set(to, dataBean);
        mMoreColorTypeAdapter.notifyDataSetChanged();
    }
    @Override
    public void onStop() {
        //拖动停止
    }
});


源码点击下载



<think>好的,用户之前问过如何使用C语言定制触控屏UI界面,我介绍了LVGL作为其中一个工具。现在用户要求详细说明LVGL,我需要深入解释它的功能、架构、使用步骤和优势。 首先,用户可能是一个嵌入式开发者,正在寻找适合他们项目的图形库。他们可能需要一个轻量级、跨平台且功能强大的解决方案。之前的回答中提到了LVGL,所以现在他们想深入了解是否适合他们的需求。 接下来,我需要确认用户对LVGL的了解程度。他们可能已经知道基本概念,但需要更详细的信息,比如架构、核心功能、如何集成到项目中,以及实际应用案例。需要详细但不过于技术化的解释,保持易懂。 考虑到用户可能使用STM32或ESP32等常见硬件,我应该涵盖这些平台的适配情况。同时,用户可能关心开发工具和资源,比如可视化设计工具SquareLine Studio,以及如何优化性能。 需要结构清晰,分点说明LVGL的特点、架构、开发流程、工具支持、优化技巧和应用场景。还要提供示例代码,帮助用户快速上手。最后,强调LVGL的开源性和社区支持,这对开发者来说很重要。 另外,用户之前的回复中提到了LVGL的事件处理和触控支持,可能需要详细说明这部分内容,比如事件回调机制。同时,确保涵盖资源管理,因为嵌入式设备通常资源有限。 最后,检查是否有遗漏的重要信息,比如多语言支持、硬件加速、文档和社区资源,这些都是开发者选择库时的重要考量因素。确保回答全面,帮助用户做出决策。</think>好的!LVGL(Light and Versatile Graphics Library)是一个开源的嵌入式图形库,专为资源受限的微控制器(MCU)设计,但也能运行在Linux等高级系统上。它提供了丰富的UI组件和动画效果,同时保持低内存占用和高性能,是嵌入式触控屏UI开发的流行选择。 --- ### **一、LVGL 核心特点** 1. **轻量高效** - 最低要求:仅需 **64KB Flash** 和 **16KB RAM**(依赖配置)。 - 支持 **单/双缓冲区** 渲染,减少屏幕撕裂。 2. **跨平台兼容** - 适配主流MCU(STM32、ESP32、NXP等)和操作系统(FreeRTOS、Linux)。 - 通过硬件抽象层(HAL)分离显示驱动与核心逻辑。 3. **丰富的UI组件** - 内置 **40+控件**:按钮、滑块、图表、列表、键盘等。 - 支持 **自定义样式**(颜色、字体、透明度)。 - 示例代码: ```c lv_obj_t *btn = lv_btn_create(lv_scr_act()); // 创建按钮 lv_obj_set_size(btn, 100, 50); // 设置尺寸 lv_obj_set_style_bg_color(btn, lv_palette_main(LV_PALETTE_BLUE), 0); // 设置颜色 ``` 4. **动态交互能力** - 支持 **触控事件**(点击、长按、滑动)、物理按键输入。 - 内置 **动画系统**(移动、缩放、渐变)。 ```c lv_anim_t anim; lv_anim_init(&anim); lv_anim_set_exec_cb(&anim, (lv_anim_exec_xcb_t)lv_obj_set_x); lv_anim_set_values(&anim, 0, 200); // 从x=0移动到x=200 lv_anim_set_time(&anim, 500); // 动画时长500ms lv_anim_set_var(&anim, btn); // 绑定到按钮 lv_anim_start(&anim); ``` --- ### **二、LVGL 架构解析** 1. **核心层(Core)** - 管理对象系统(所有UI元素均为`lv_obj_t`的派生)。 - 提供定时器、任务调度、内存管理。 2. **驱动层(Drivers)** - **显示驱动**:实现屏幕刷新函数(如SPI发送帧缓冲数据)。 - **输入驱动**:触控坐标读取或物理按键事件传递。 - 典型初始化代码: ```c // 注册显示驱动 static lv_disp_drv_t disp_drv; lv_disp_drv_init(&disp_drv); disp_drv.flush_cb = my_flush_callback; // 实现刷屏函数 lv_disp_drv_register(&disp_drv); // 注册触控驱动 static lv_indev_drv_t indev_drv; lv_indev_drv_init(&indev_drv); indev_drv.type = LV_INDEV_TYPE_POINTER; indev_drv.read_cb = my_touch_read; // 实现触控坐标读取 lv_indev_drv_register(&indev_drv); ``` 3. **组件库(Widgets)** - 预定义控件(按钮、标签、图表等)通过继承`lv_obj_t`实现。 - 支持用户自定义控件(如圆形菜单、3D效果)。 --- ### **三、开发流程详解** 1. **硬件准备** - 屏幕模块(如ILI9341 TFT-LCD)+ 触控芯片(如XPT2046)。 - MCU需满足:主频 > 48MHz,RAM > 64KB(推荐)。 2. **移植LVGL** - 步骤: 1. 克隆LVGL仓库:`git clone https://github.com/lvgl/lvgl.git` 2. 实现`lv_conf.h`(配置内存、功能开关)。 3. 编写显示/触控驱动回调函数。 - 关键配置项(`lv_conf.h`): ```c #define LV_MEM_SIZE (32U * 1024) // 内存池大小 #define LV_USE_LOG 1 // 启用日志 #define LV_USE_BTN 1 // 启用按钮控件 ``` 3. **UI设计与编码** - **手动编码模式**: ```c // 创建滑动条并绑定事件 lv_obj_t *slider = lv_slider_create(lv_scr_act()); lv_obj_center(slider); lv_slider_set_range(slider, 0, 100); lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL); ``` - **可视化工具**(SquareLine Studio): - 拖拽设计界面 → 导出C代码 → 集成到项目。 --- ### **四、关键优化技巧** 1. **降低内存占用** - 启用 **LVGL的文件系统**,动态加载图片(而非嵌入C数组)。 - 启用 **双缓冲** 并合理设置缓冲区大小: ```c static lv_color_t buf1[LV_HOR_RES_MAX * 10]; // 横向分辨率x10行 static lv_color_t buf2[LV_HOR_RES_MAX * 10]; lv_disp_draw_buf_init(&draw_buf, buf1, buf2, LV_HOR_RES_MAX * 10); ``` - 使用 **DMA传输** 减少CPU占用(需硬件支持)。 3. **触控响应优化** - 添加 **坐标滤波算法**(如中值滤波): ```c #define SAMPLE_COUNT 5 int32_t x_buf[SAMPLE_COUNT], y_buf[SAMPLE_COUNT]; // 采样5次后排序取中间值 ``` --- ### **五、典型应用场景** | 场景 | 实现方案 | |---------------------|-----------------------------------| | **智能家居面板** | LVGL + STM32 + 电容屏,支持滑动控制 | | **工业HMI** | LVGL + FreeRTOS,多级菜单+实时数据刷新 | | **穿戴设备** | LVGL + 低功耗MCU,优化动画帧率和功耗 | --- ### **六、资源推荐** 1. **官方文档**:[LVGL Documentation](https://docs.lvgl.io/) 2. **社区支持**:GitHub Issues、LVGL官方论坛 3. **快速入门示例**: ```c void lv_example_btn_1(void) { lv_obj_t *btn = lv_btn_create(lv_scr_act()); lv_obj_set_pos(btn, 10, 10); lv_obj_t *label = lv_label_create(btn); lv_label_set_text(label, "Click Me!"); lv_obj_add_event_cb(btn, btn_click_event, LV_EVENT_CLICKED, NULL); } ``` --- LVGL凭借其灵活性和低资源消耗,已成为嵌入式UI开发的首选库之一。若需进一步了解特定功能(如多语言切换或自定义主题),可提供更多细节!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值