Bird
Raised Fist0
Fluttermobile~20 mins

Pull-to-refresh in Flutter - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Pull-to-refresh Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ ui_behavior
intermediate
2:00remaining
What happens when you pull down on a ListView wrapped with RefreshIndicator?

Consider a Flutter app with a RefreshIndicator wrapping a ListView. What is the expected behavior when the user pulls down on the list?

Flutter
RefreshIndicator(
  onRefresh: () async {},
  child: ListView.builder(
    itemCount: 10,
    itemBuilder: (context, index) => ListTile(title: Text('Item $index')),
  ),
)
AA loading spinner appears at the top and the onRefresh callback is triggered.
BThe list scrolls up without any visual feedback or callback.
CThe app crashes because RefreshIndicator cannot wrap ListView.
DNothing happens because onRefresh is empty.
Attempts:
2 left
💡 Hint

Think about what RefreshIndicator is designed to do when the user pulls down.

❓ lifecycle
intermediate
1:30remaining
What is the correct return type of the onRefresh callback in RefreshIndicator?

In Flutter's RefreshIndicator, what must the onRefresh callback return?

AFuture<void>
Bvoid
Cbool
Dint
Attempts:
2 left
💡 Hint

Consider that the refresh action is asynchronous and the indicator waits for it to complete.

📝 Syntax
advanced
2:30remaining
Which code snippet correctly implements pull-to-refresh with RefreshIndicator?

Choose the Flutter code snippet that correctly implements a pull-to-refresh feature using RefreshIndicator and updates the list items.

Flutter
class MyList extends StatefulWidget {
  @override
  State<MyList> createState() => _MyListState();
}

class _MyListState extends State<MyList> {
  List<String> items = ['A', 'B', 'C'];

  Future<void> _refresh() async {
    await Future.delayed(Duration(seconds: 1));
    setState(() {
      items.add('D');
    });
  }

  @override
  Widget build(BuildContext context) {
    return RefreshIndicator(
      onRefresh: _refresh,
      child: ListView.builder(
        itemCount: items.length,
        itemBuilder: (context, index) => ListTile(title: Text(items[index])),
      ),
    );
  }
}
AChange onRefresh to: onRefresh: () { _refresh(); }
BThe code above as is.
CChange _refresh to return void instead of Future<void>.
DRemove setState call inside _refresh.
Attempts:
2 left
💡 Hint

Remember that onRefresh expects a Future and setState updates UI.

🔧 Debug
advanced
2:00remaining
Why does the RefreshIndicator spinner never disappear?

A developer uses RefreshIndicator but the spinner stays visible forever after pulling down. What is the most likely cause?

Flutter
RefreshIndicator(
  onRefresh: () async {
    // Forgot to complete the future
  },
  child: ListView(...),
)
AThe RefreshIndicator must be inside a Scaffold.
BThe ListView is not scrollable, so RefreshIndicator doesn't work.
CThe onRefresh callback must return void, not Future.
DThe onRefresh future never completes, so spinner stays visible.
Attempts:
2 left
💡 Hint

Think about what controls the spinner visibility.

🧠 Conceptual
expert
2:30remaining
How to enable pull-to-refresh only when the list is scrolled to the top?

In Flutter, how does RefreshIndicator ensure that pull-to-refresh activates only when the scrollable is at the top?

AIt requires a manual check in onRefresh to verify scroll position.
BIt triggers pull-to-refresh regardless of scroll position.
CIt listens to the scroll position and triggers only if offset is zero or less.
DIt disables pull-to-refresh if the list has more than 10 items.
Attempts:
2 left
💡 Hint

Think about how scroll position affects user gestures.

Practice

(1/5)
1. What is the main purpose of using RefreshIndicator in a Flutter app?
easy
A. To navigate between different screens
B. To create a button for submitting forms
C. To enable pull-to-refresh functionality on a scrollable widget
D. To display a loading spinner on app startup

Solution

  1. Step 1: Understand the role of RefreshIndicator

    The RefreshIndicator widget provides a pull-to-refresh feature that triggers an update when the user drags down on a scrollable list.
  2. Step 2: Identify the correct use case

    It is specifically designed to wrap scrollable widgets like ListView to refresh their content.
  3. Final Answer:

    To enable pull-to-refresh functionality on a scrollable widget -> Option C
  4. Quick Check:

    Pull-to-refresh = RefreshIndicator usage [OK]
Hint: RefreshIndicator is for pull-to-refresh on scrollable lists [OK]
Common Mistakes:
  • Confusing RefreshIndicator with navigation widgets
  • Using RefreshIndicator on non-scrollable widgets
  • Thinking it creates buttons or spinners
2. Which of the following is the correct syntax to add a pull-to-refresh feature using RefreshIndicator in Flutter?
easy
A. RefreshIndicator(child: ListView(), refresh: _refresh)
B. RefreshIndicator(onRefresh: _refresh, child: ListView())
C. RefreshIndicator(refreshCallback: _refresh, child: ListView())
D. RefreshIndicator(onRefresh: _refresh())

Solution

  1. Step 1: Recall RefreshIndicator parameters

    The RefreshIndicator requires an onRefresh callback and a child widget that is scrollable.
  2. Step 2: Check correct parameter names and usage

    RefreshIndicator(onRefresh: _refresh, child: ListView()) correctly uses onRefresh: _refresh and child: ListView(). RefreshIndicator(child: ListView(), refresh: _refresh) uses wrong parameter name refresh. RefreshIndicator(refreshCallback: _refresh, child: ListView()) uses refreshCallback which is incorrect. RefreshIndicator(onRefresh: _refresh()) calls _refresh() instead of passing the function.
  3. Final Answer:

    RefreshIndicator(onRefresh: _refresh, child: ListView()) -> Option B
  4. Quick Check:

    Correct parameters = RefreshIndicator(onRefresh: _refresh, child: ListView()) [OK]
Hint: Use onRefresh and child parameters exactly [OK]
Common Mistakes:
  • Using wrong parameter names like refresh or refreshCallback
  • Calling the refresh function instead of passing it
  • Not providing a scrollable child widget
3. Given the code snippet below, what will happen when the user pulls down on the list?
RefreshIndicator(
  onRefresh: () async {
    await Future.delayed(Duration(seconds: 2));
  },
  child: ListView(
    children: [Text('Item 1'), Text('Item 2')],
  ),
)
medium
A. A loading spinner appears for 2 seconds, then stops
B. The list will refresh immediately without delay
C. The app will crash due to missing return value
D. Nothing happens because onRefresh is empty

Solution

  1. Step 1: Analyze the onRefresh callback

    The onRefresh callback returns a Future that completes after a 2-second delay using Future.delayed.
  2. Step 2: Understand RefreshIndicator behavior

    When the user pulls down, the RefreshIndicator shows a loading spinner until the Future completes, so it will show for 2 seconds then stop.
  3. Final Answer:

    A loading spinner appears for 2 seconds, then stops -> Option A
  4. Quick Check:

    Async delay = spinner visible 2 seconds [OK]
Hint: Async onRefresh delays spinner duration [OK]
Common Mistakes:
  • Assuming immediate refresh without delay
  • Thinking the app crashes without explicit return
  • Believing nothing happens if no data changes
4. Identify the error in this Flutter code snippet that uses RefreshIndicator:
RefreshIndicator(
  onRefresh: () async {
    // refresh logic
  },
  child: Column(
    children: [Text('Item 1'), Text('Item 2')],
  ),
)
medium
A. The child widget must be scrollable, Column is not scrollable
B. The onRefresh callback must return a boolean
C. RefreshIndicator cannot have children widgets
D. The async keyword is not allowed in onRefresh

Solution

  1. Step 1: Check the child widget type

    The child of RefreshIndicator must be a scrollable widget like ListView or CustomScrollView. Column is not scrollable.
  2. Step 2: Understand the impact of non-scrollable child

    Using Column will cause the pull-to-refresh gesture not to work because the widget does not scroll.
  3. Final Answer:

    The child widget must be scrollable, Column is not scrollable -> Option A
  4. Quick Check:

    Scrollable child required = The child widget must be scrollable, Column is not scrollable [OK]
Hint: RefreshIndicator child must scroll (ListView, not Column) [OK]
Common Mistakes:
  • Thinking async is disallowed in onRefresh
  • Expecting onRefresh to return boolean
  • Believing any widget can be child
5. You want to implement pull-to-refresh on a list that fetches data from the internet. Which approach correctly updates the UI after refreshing?
class MyList extends StatefulWidget {
  @override
  State<MyList> createState() => _MyListState();
}

class _MyListState extends State<MyList> {
  List<String> items = ['Old item'];

  Future<void> _refresh() async {
    final newData = await fetchDataFromInternet();
    // What should you do here?
  }

  @override
  Widget build(BuildContext context) {
    return RefreshIndicator(
      onRefresh: _refresh,
      child: ListView(
        children: items.map((e) => Text(e)).toList(),
      ),
    );
  }
}
hard
A. Return newData from _refresh without updating items
B. Just assign items = newData without setState
C. Call Navigator.pop(context) after fetching data
D. Call setState(() { items = newData; }) inside _refresh to update UI

Solution

  1. Step 1: Understand state update in StatefulWidget

    To update the UI after fetching new data, you must call setState with the new data assigned to the state variable.
  2. Step 2: Apply setState in _refresh method

    Inside _refresh, wrap the assignment of items = newData in setState to notify Flutter to rebuild the widget with updated data.
  3. Final Answer:

    Call setState(() { items = newData; }) inside _refresh to update UI -> Option D
  4. Quick Check:

    State update requires setState call [OK]
Hint: Use setState to update UI after async data fetch [OK]
Common Mistakes:
  • Updating state variables without setState
  • Returning data without updating state
  • Using navigation calls instead of state update
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard