Scroll_to_y may unuseful sometimes,how to deal it?

Important: unclear posts may not receive useful answers.

Before posting

  • Get familiar with Markdown to format and structure your post
  • Be sure to update lvgl from the latest version from the master branch.
  • Be sure you have checked the FAQ and read the relevant part of the documentation.
  • If applicable use the Simulator to eliminate hardware related issues.

Delete this section if you read and applied the mentioned points.

Description

What MCU/Processor/Board and compiler are you using?

Linux

What LVGL version are you using?

lvglV8.3.0

What do you want to achieve?

scroll_to_y to set the custom roller be set to index 0

What have you tried so far?

I design a custom roller ,it can scroll to other index insted of 0 ,1,28,29…(there are the first、second One)

Code to reproduce

Add a code snippet which can run in the simulator. It should contain only the relevant code that compiles without errors when separated from your main code base.

The code block(s) should be formatted like:

//created by Sean on 2024.1.2
//实现基础的自定义roller样式,其他效果需自行实现

#include "view.h"

typedef struct scrollParam
{
    int step;
    int first_y;
    int selectindex;
}scrollParam_t;


static void scroll_event(lv_event_t * e)
{
    lv_obj_t * scroll_container = lv_event_get_target(e);                                               // 获取事件的初始对象
    scrollParam_t *param = (scrollParam_t*)e->user_data;

    lv_coord_t scroll_y = lv_obj_get_scroll_y(scroll_container);
    printf("scroll_y = %d \r\n",scroll_y);//看打印知道位置-100 -42 16 xxx(步进58)

    //这个是get_selected
    if ((scroll_y-(param->first_y))%param->step == 0) //选中项
    {
        param->selectindex = (scroll_y-(param->first_y))/param->step;//选中项
        printf("param->selectindex = %d \r\n",param->selectindex);
    }

    for (int i = 0; i < lv_obj_get_child_cnt(scroll_container); i++) {

        lv_obj_t * item = lv_obj_get_child(scroll_container, i);

        lv_obj_t* label = lv_obj_get_child(lv_obj_get_child(scroll_container, i),0);

        int child_scroll_y = i*param->step+(param->first_y);

        //选中的样式
        if ( scroll_y > child_scroll_y - param->step/2 && scroll_y < child_scroll_y + param->step/2) {
            lv_obj_set_style_text_font(label,biz_fonts.ft_regular_60.font,0);
            lv_obj_set_style_text_opa(label,255,0);
            // printf("1 = %d \r\n",lv_obj_get_y(label));//10
            // lv_obj_set_y(label,10);
            lv_obj_set_align(label,LV_ALIGN_CENTER);
        }
        else if ( scroll_y > child_scroll_y - param->step/2 - param->step && scroll_y < child_scroll_y + param->step/2 + param->step) {
            lv_obj_set_style_text_font(label,biz_fonts.ft_regular_36.font,0);
            lv_obj_set_style_text_opa(label,200,0);
            // printf("2 = %d \r\n",lv_obj_get_y(label));//24
            // lv_obj_set_y(label,24);
            lv_obj_set_align(label,LV_ALIGN_CENTER);
        }
        else //非选中样式
        {
            lv_obj_set_style_text_font(label,biz_fonts.ft_regular_18.font,0);
            lv_obj_set_style_text_opa(label,150,0);
            // printf("3 = %d \r\n",lv_obj_get_y(label));//35
            if (i < param->selectindex)
                lv_obj_set_align(label,LV_ALIGN_BOTTOM_MID);
            else
                lv_obj_set_align(label,LV_ALIGN_TOP_MID);
        }        
    }


}

lv_obj_t *view_custom_roller_create(lv_obj_t *parent,uint16_t width,uint16_t height,uint16_t num,uint16_t visable_sum)
{
    lv_obj_t *container = lv_obj_create(parent);

    lv_obj_style_clean(container);//clean后设置bg color等style属性就会无效了

    // lv_obj_set_style_border_width(container,0,0);
    // lv_obj_set_style_bg_color(container,lv_color_hex(0x000000), 0);
    lv_obj_add_flag(container,LV_OBJ_FLAG_SCROLLABLE);
    lv_obj_set_scrollbar_mode(container, LV_SCROLLBAR_MODE_OFF);

    lv_obj_set_flex_flow(container, LV_FLEX_FLOW_COLUMN);

    //改父对象和子对象的size来实现visable
    lv_obj_set_size(container,width,height);

    lv_obj_set_scroll_snap_y(container, LV_SCROLL_SNAP_CENTER);

    for (size_t i = 0; i < num; i++)
    {
        lv_obj_t *child = lv_obj_create(container); 
        lv_obj_style_clean(child);
        lv_obj_set_height(child,height/visable_sum);

        lv_obj_t *label = lv_label_create(child);
        lv_obj_center(label);
        lv_label_set_text_fmt(label, "%d",i);
        lv_obj_set_style_text_color(label,lv_color_hex(0xffffff),0);
        lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0);
        lv_obj_set_style_text_font(label,biz_fonts.ft_regular_18.font,0);

    }
    container->user_data = (scrollParam_t*)malloc(sizeof(scrollParam_t));
    ((scrollParam_t*)(container->user_data))->step = height/visable_sum+8;
    ((scrollParam_t*)(container->user_data))->first_y = 0 - (visable_sum/2)*(height/visable_sum);
    // printf(" ((scrollParam_t*)(container->user_data))->step = %d , ((scrollParam_t*)(container->user_data))->y = %d \r\n", ((scrollParam_t*)(container->user_data))->step, ((scrollParam_t*)(container->user_data))->first_y);
    lv_obj_add_event_cb(container,scroll_event, LV_EVENT_SCROLL, container->user_data);


    //手动snap初始化
    lv_obj_update_snap(container,LV_ANIM_OFF);
    
    return container;
}

int view_custom_roller_get_selected(lv_obj_t *des)
{
    return ((scrollParam_t*)(des->user_data))->selectindex;
}

void view_custom_roller_set_selected(lv_obj_t *des,uint16_t index,lv_anim_enable_t anim_en)
{
    int pos = index*(((scrollParam_t*)(des->user_data))->step)+((((scrollParam_t*)(des->user_data))->first_y));
    printf("pos = %d step=%d firsty=%d \r\n",pos,(((scrollParam_t*)(des->user_data))->step),(((scrollParam_t*)(des->user_data))->first_y));

    lv_obj_scroll_to_y(des,pos,anim_en);
    
    //sean 现在仍然有bug,没法滚到前2个/后2个,需定位什么原因
}

I use this in main(),view_custom_roller_set_selected(_holder->custom_roller,5,LV_ANIM_ON);is okay,
but when I view_custom_roller_set_selected(_holder->custom_roller,0/1/29/30,LV_ANIM_ON); 
scroll_to_y doesn't work,please tell me how to deal it~
{
    _holder->custom_roller = view_custom_roller_create(_layout,200,450,30,5);
    view_custom_roller_set_selected(_holder->custom_roller,0,LV_ANIM_ON);
}

Screenshot and/or video

If possible, add screenshots and/or videos about the current state.
image

I want to scroll to y ,index = 0/1/29/30,like this:

image

I can set this picture by drag a mouse , but the code lv_obj_scroll_to_y seems not effective

I mean your flex container cant scroll because alligned…
Simple way is add two dummy spaces instead 0…

hey gus,I solve my problem by change the set_selected function to this:
void view_custom_roller_set_selected(lv_obj_t des,uint16_t index,lv_anim_enable_t anim_en)
{
int pos = index
(((scrollParam_t*)(des->user_data))->step)+((((scrollParam_t*)(des->user_data))->first_y));
// printf(“pos = %d step=%d firsty=%d \r\n”,pos,(((scrollParam_t*)(des->user_data))->step),(((scrollParam_t*)(des->user_data))->first_y));

// lv_obj_scroll_to_y(des,pos,anim_en);

lv_obj_scroll_by(des,0,0-pos,anim_en);
lv_obj_update_snap(des,LV_ANIM_OFF);

}

Ok and FYI in roller you have two size font and more cool smooth opacity you can do with place image alpha gradient over roller object.
or fade mask Roller (lv_roller) — LVGL documentation

Thank you, brother. I will give it a try