如何实现在任意位置拖动slider改变它的值?同时去掉旋钮的点击事件,像手机调节音量的ui一样?


我创建了一个slider控件,我想实现像手机调节音量一样的ui控件,一摸一样的效果,就是去掉旋钮的点击事件,在滑块的任意位置都可以拖动,并且滑块的值也是根据拖动的距离变化的,而不是直接跳到触摸点上,我尝试过获取按下时的坐标,并根据手势滑动的水平距离更新它的值,我尝试写了好几次,都没能实现,这对于我来说确实有点难,加上在网上找不到相应的资料,浪费了很多时间。各位走过路过的大佬,麻烦指点几句,不胜感激。。。
>.<

像这样根据按下拖动的距离而变化

参考实现:

static void my_slider_event(lv_event_t *e)
{
    lv_obj_t *slider = lv_event_get_current_target(e);

    lv_indev_t *indev = lv_indev_get_act();
    if (indev == NULL)
        return;

    int16_t sensitive = 3;  // // TODO: You can adjust the sensitivity
    lv_point_t vect;
    lv_indev_get_vect(indev, &vect);
    LV_LOG_USER("vect.x: %d, vect.y: %d\n", vect.x, vect.y);
    if (vect.y < -sensitive)
        lv_slider_set_value(slider, (lv_slider_get_value(slider) + 5), LV_ANIM_ON);
    else if (vect.y > sensitive)
        lv_slider_set_value(slider, (lv_slider_get_value(slider) - 5), LV_ANIM_ON);
}

void my_lv_example_slider(void)
{
    /*Create a slider in the center of the display*/
    lv_obj_t *slider = lv_slider_create(lv_scr_act());
    lv_obj_set_size(slider, 40, 300);
    lv_obj_center(slider);
    lv_obj_add_flag(slider, LV_OBJ_FLAG_ADV_HITTEST);

    lv_obj_add_event_cb(slider, my_slider_event, LV_EVENT_HIT_TEST, NULL);
}

1 个赞

感谢您的解答! 我会尝试您提出的解决办法,稍后回复您。

太棒了,完美解决! :grin: :+1: :+1: :+1:

您好,我想请问一下那个滑块的动画加载,拖动很快的时候它加载的很慢,慢慢拖动的时候他反而更精准,这个问题怎么避免呢?实际开发中拖动中滑块动画加载的速度都是一致的,怎么拖拉都没事儿 :hear_no_evil:

这里就是需要优化的地方,参考修改:

#include <math.h>
static void my_slider_event(lv_event_t *e)
{
    lv_obj_t *slider = lv_event_get_current_target(e);

    lv_indev_t *indev = lv_indev_get_act();
    if (indev == NULL)
        return;

    int16_t sensitive = 0;  // // TODO: You can adjust the sensitivity
    lv_point_t vect;
    lv_indev_get_vect(indev, &vect);
    LV_LOG_USER("vect.x: %d, vect.y: %d\n", vect.x, vect.y);
    if (vect.y < -sensitive)
        lv_slider_set_value(slider, (lv_slider_get_value(slider) + abs(vect.y)), LV_ANIM_ON);//lv_slider_set_value(slider, (lv_slider_get_value(slider) + 5), LV_ANIM_ON);
    else if (vect.y > sensitive)
        lv_slider_set_value(slider, (lv_slider_get_value(slider) - abs(vect.y)), LV_ANIM_ON);//lv_slider_set_value(slider, (lv_slider_get_value(slider) - 5), LV_ANIM_ON);
}

void my_lv_example_slider(void)
{
    /*Create a slider in the center of the display*/
    lv_obj_t *slider = lv_slider_create(lv_scr_act());
    lv_obj_set_size(slider, 40, 300);
    lv_obj_center(slider);
    lv_obj_add_flag(slider, LV_OBJ_FLAG_ADV_HITTEST);

    lv_obj_add_event_cb(slider, my_slider_event, LV_EVENT_HIT_TEST, NULL);
}

原来取绝对值就好了啊,我只能说无敌!!!