A blue and white object hanging from a ceiling

Vision Week Day 18 – Server Driven UI in Flutter

Be part of a better internet. 🚀

Get 20% off membership for a limited time!


Hello Visionaries! 👋 Today, let’s explore an exciting topic: Server Driven UI in Flutter. Have you ever wondered how apps magically transform their UI during special events without needing an update?

What is Server Driven UI?

In a traditional mobile app, the UI is hard-coded. Developers need to release a new version for any visual changes, requiring users to update the app. Server-driven UI allows the server to dictate the app’s interface, enabling dynamic, instant updates without a full app release.

Benefits of Server Driven UI

  1. Dynamic Updates: Instantly update the UI without app store releases.
  2. Centralized Control: Manage UI centrally for consistency.
  3. Flexibility: Adapt UI for events and promotions with ease.

Limitations of Server Driven UI

  1. Debugging Complexity: Harder to trace errors due to server control.
  2. Limited Customization: Tough to personalize based on user preferences or device capabilities.
  3. Performance Concerns: Frequent network requests can impact app performance.

Practical Implementation in Vision Week

Let’s get our hands dirty with some code! 🌟 We’ll fetch UI configurations from the server and render them dynamically.

Step 1: Create a Model Class

First, we need a model class to represent the server’s response.

class WidgetConfig {
  final String type;
  final String? text;
  final String? color;

  WidgetConfig({required this.type, this.text, this.color});

  factory WidgetConfig.fromJson(Map<String, dynamic> json) {
    return WidgetConfig(
      type: json['type'],
      text: json['text'],
      color: json['color'],
    );
  }
}

Step 2: Make a Network Request

Fetch the data from the server.

Future<List<WidgetConfig>> fetchWidgetConfig() async {
  final response = await http.get(Uri.parse('http://192.168.1.***:4000/dynamic_ui')); // Enter your server URL

  if (response.statusCode == 200) {
    List<dynamic> jsonData = json.decode(response.body);
    return jsonData.map((json) => WidgetConfig.fromJson(json)).toList();
  } else {
    throw Exception('Failed to load widget config');
  }
}

Step 3: Parse the Response and Render the UI

FutureBuilder<List<WidgetConfig>>(
  future: fetchWidgetConfig(),
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return Center(child: CircularProgressIndicator());
    } else if (snapshot.hasError) {
      return Center(child: Text('Error: ${snapshot.error}'));
    } else {
      return Padding(
        padding: EdgeInsets.all(10),
        child: AnimationStyles.getAnimatedWidgetForTheme(theme, DynamicUIBuilder(widgetConfigs: snapshot.data!), _controller),
      );
    }
  },
)

Step 4: Create Dynamic UI Based on Server Response

class DynamicUIBuilder extends StatelessWidget {
  final List<WidgetConfig> widgetConfigs;

  DynamicUIBuilder({required this.widgetConfigs});

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: widgetConfigs.length,
      itemBuilder: (context, index) {
        final config = widgetConfigs[index];
        switch (config.type) {
          case 'text':
            return Text(config.text ?? '', style: TextStyle(color: Color(int.parse(config.color ?? '0xff000000'))));
          case 'button':
            return ElevatedButton(
              onPressed: () {},
              style: ElevatedButton.styleFrom(backgroundColor: Color(int.parse(config.color ?? '0xff000000'))),
              child: Text(config.text ?? ''),
            );
          case 'image':
            return Image.asset("assets/images/logo.png");
          case 'sizebox':
            return SizedBox(height: 5);
          case 'textfield':
            return TextField(
              decoration: InputDecoration(border: OutlineInputBorder(), hintText: config.text),
              style: TextStyle(),
            );
          default:
            return Container();
        }
      },
    );
  }
}

Latest Updates and Bug Fixes

We’ve been hard at work fixing issues in Vision Week to ensure a smooth user experience:

  1. Fixed URI Errors: Corrected URI references in Dart files.
  2. AppLocalizations Resolved: Addressed missing AppLocalizations imports.
  3. Implemented Firebase Auth: Integrated secure user authentication.
  4. Enhanced UI/UX: Improved the user interface for better engagement.

Join the Vision Week Journey

Thank you for being part of our Vision Week adventure!


GitHub Link: Vision Week Repository

Quote: “Learn something new every day. 😊 Keep coding! 😍”


More from Kvnbbg:

Recommended Reads:


Discover more from Kvnbbg.fr

Subscribe to get the latest posts sent to your email.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *