Lv_obj_clean() ends in a crash

Sorry, I’m just reading this now. Unfortunately you have to wait longer than tabview_animation_ready_cb

This is the code I am using:

both lvgl 8 and 9

void your_function_to_delete_tab(int oldTabID, int newTabID) {
   ...
}

static bool waitBeforeActionAfterSlidingAnimationEnded = false;
static unsigned long waitBeforeActionAfterSlidingAnimationEnded_timerStart;
// This is the callback when the animation of the tab sliding ended
static void tabview_animation_ready_cb(lv_anim_t* a) {
  // Unfortunately, the animation has not completely ended here. We cannot do the recreation of the tabs here.
  // We have to wait some more milliseconds or at least one cycle of lv_timer_handler();
  // calling lv_timer_handler(); here does not help
  // lv_timer_handler();
  // your_function_to_delete_tab(oldTabID, currentTabID);

  waitBeforeActionAfterSlidingAnimationEnded = true;
  waitBeforeActionAfterSlidingAnimationEnded_timerStart = millis();
}


static bool waitOneLoop = false;
void gui_loop(void) {
  // after the sliding animation ended, we have to wait one cycle of gui_loop() before we can do the recreation of the tabs
  if (waitBeforeActionAfterSlidingAnimationEnded) {
    waitOneLoop = true;
    waitBeforeActionAfterSlidingAnimationEnded = false;
  } else if (waitOneLoop) {
    waitOneLoop = false;
    your_function_to_delete_tab(oldTabID, currentTabID);
  };
  // // as alternative, we could wait some milliseconds. But one cycle of gui_loop() works well.
  // if (waitBeforeActionAfterSlidingAnimationEnded) {
  //   if (millis() - waitBeforeActionAfterSlidingAnimationEnded_timerStart >= 5) {
  //     your_function_to_delete_tab(oldTabID, currentTabID);
  //     waitBeforeActionAfterSlidingAnimationEnded = false;
  //   }
  // }

  lv_timer_handler();
}

only lvgl 8

// Update currentTabID when a new tab is selected
// this is a callback if the tabview is changed (LV_EVENT_VALUE_CHANGED)
// Sent when a new tab is selected by sliding or clicking the tab button. lv_tabview_get_tab_act(tabview) returns the zero based index of the current tab.
void tabview_tab_changed_event_cb(lv_event_t* e) {
  if (lv_event_get_code(e) == LV_EVENT_VALUE_CHANGED) {
    
    oldTabID = currentTabID;
    currentTabID = lv_tabview_get_tab_act(lv_event_get_target(e));

    // Wait until the animation ended, then call "your_function_to_delete_tab(oldTabID, currentTabID);"
    // https://forum.lvgl.io/t/delete-a-tab-after-the-tabview-scroll-animation-is-complete/3155/4
    lv_obj_t* myTabview = lv_event_get_target(e);
    lv_obj_t* tabContainer = lv_tabview_get_content(myTabview);
    lv_anim_t* anim = lv_anim_get(tabContainer, NULL); // (lv_anim_exec_xcb_t) lv_obj_set_x);
    if(anim) {
      // Swipe is not yet complete. User released the touch screen, an animation will bring it to the end.
      // That's the normal (and only?) case for the tft touchscreen
      lv_anim_set_ready_cb(anim, tabview_animation_ready_cb);
    } else {
      // Swipe is complete, no additional animation is needed. Most likely only possible in simulator
      Serial.println("Change of tab detected, without animation at the end. Will directly do my job after sliding.");
      your_function_to_delete_tab(oldTabID, currentTabID);
    }
  }
}

lvgl 9

// Update currentTabID when a new tab is selected
// this is a callback if the tabview is changed (LV_EVENT_VALUE_CHANGED)
// Sent when a new tab is selected by sliding or clicking the tab button. lv_tabview_get_tab_act(tabview) returns the zero based index of the current tab.
void tabview_tab_changed_event_cb(lv_event_t* e) {
  if (lv_event_get_code(e) == LV_EVENT_VALUE_CHANGED) {
    
    oldTabID = currentTabID;
    currentTabID = lv_tabview_get_tab_active((lv_obj_t*)lv_event_get_target(e));

    // Wait until the animation ended, then call "your_function_to_delete_tab(oldTabID, currentTabID);"
    // https://forum.lvgl.io/t/delete-a-tab-after-the-tabview-scroll-animation-is-complete/3155/4
    lv_obj_t* myTabview = (lv_obj_t*)lv_event_get_target(e);
    lv_obj_t* tabContainer = lv_tabview_get_content(myTabview);
    lv_anim_t* anim = lv_anim_get(tabContainer, NULL); // (lv_anim_exec_xcb_t) lv_obj_set_x);
    if(anim) {
      // Swipe is not yet complete. User released the touch screen, an animation will bring it to the end.
      // That's the normal (and only?) case for the tft touchscreen
      lv_anim_set_completed_cb(anim, tabview_animation_ready_cb);
    } else {
      // Swipe is complete, no additional animation is needed. Most likely only possible in simulator
      Serial.println("Change of tab detected, without animation at the end. Will directly do my job after sliding.");
      your_function_to_delete_tab(oldTabID, currentTabID);
    }
  }
}