<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Rentyard</title>
    <description>The latest articles on Forem by Rentyard (@rentyard).</description>
    <link>https://forem.com/rentyard</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3551541%2Ff8e230ef-b499-4967-aa90-7ce26f9bb347.jpg</url>
      <title>Forem: Rentyard</title>
      <link>https://forem.com/rentyard</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/rentyard"/>
    <language>en</language>
    <item>
      <title>Building a Small but Powerful Rental Listing App with Flutter + Riverpod</title>
      <dc:creator>Rentyard</dc:creator>
      <pubDate>Tue, 07 Oct 2025 14:08:52 +0000</pubDate>
      <link>https://forem.com/rentyard/building-a-small-but-powerful-rental-listing-app-with-flutter-riverpod-14g7</link>
      <guid>https://forem.com/rentyard/building-a-small-but-powerful-rental-listing-app-with-flutter-riverpod-14g7</guid>
      <description>&lt;p&gt;When you start building a real-world rental listing app, things like filtering, asset management (photos/videos), and clean state handling can quickly get complicated.&lt;br&gt;
In this post, I’ll show a practical example of how to build a simple yet scalable architecture using Flutter and Riverpod — clean, testable, and easy to extend.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We’ll Build
&lt;/h2&gt;

&lt;p&gt;Display a list of rental properties (title, location, price, thumbnail).&lt;/p&gt;

&lt;p&gt;Add basic city-based filtering.&lt;/p&gt;

&lt;p&gt;Toggle favorites using local state.&lt;/p&gt;

&lt;p&gt;Keep the architecture clean with Riverpod instead of Redux-style complexity.&lt;/p&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Riverpod?
&lt;/h2&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;p&gt;Simple and predictable.&lt;/p&gt;

&lt;p&gt;Test-friendly and easy to compose.&lt;/p&gt;

&lt;p&gt;Context-free access (no need for BuildContext).&lt;/p&gt;

&lt;p&gt;Works great for both small and large apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Example
&lt;/h2&gt;

&lt;p&gt;Model:&lt;/p&gt;

&lt;p&gt;// models/property.dart&lt;br&gt;
class Property {&lt;br&gt;
  final String id;&lt;br&gt;
  final String title;&lt;br&gt;
  final String city;&lt;br&gt;
  final int price;&lt;br&gt;
  final String thumbnail;&lt;/p&gt;

&lt;p&gt;Property({required this.id, required this.title, required this.city, required this.price, required this.thumbnail});&lt;br&gt;
}&lt;/p&gt;

&lt;h2&gt;
  
  
  Providers:
&lt;/h2&gt;

&lt;p&gt;// providers/property_provider.dart&lt;br&gt;
import 'package:flutter_riverpod/flutter_riverpod.dart';&lt;br&gt;
import '../models/property.dart';&lt;/p&gt;

&lt;p&gt;// sample data provider&lt;br&gt;
final propertyListProvider = Provider&amp;gt;((ref) {&lt;br&gt;
  return [&lt;br&gt;
    Property(id: 'p1', title: 'Cozy 2BR near downtown', city: 'Dhaka', price: 1200, thumbnail: 'https://...'),&lt;br&gt;
    Property(id: 'p2', title: 'Sunny studio', city: 'Chittagong', price: 800, thumbnail: 'https://...'),&lt;br&gt;
  ];&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;final cityFilterProvider = StateProvider((ref) =&amp;gt; null);&lt;/p&gt;

&lt;p&gt;final filteredPropertyProvider = Provider&amp;gt;((ref) {&lt;br&gt;
  final all = ref.watch(propertyListProvider);&lt;br&gt;
  final city = ref.watch(cityFilterProvider);&lt;br&gt;
  if (city == null || city.isEmpty) return all;&lt;br&gt;
  return all.where((p) =&amp;gt; p.city.toLowerCase().contains(city.toLowerCase())).toList();&lt;br&gt;
});&lt;/p&gt;

&lt;h2&gt;
  
  
  UI Widget:
&lt;/h2&gt;

&lt;p&gt;// ui/property_list.dart&lt;br&gt;
import 'package:flutter/material.dart';&lt;br&gt;
import 'package:flutter_riverpod/flutter_riverpod.dart';&lt;br&gt;
import '../providers/property_provider.dart';&lt;/p&gt;

&lt;p&gt;class PropertyListView extends ConsumerWidget {&lt;br&gt;
    Widget build(BuildContext context, WidgetRef ref) {&lt;br&gt;
    final properties = ref.watch(filteredPropertyProvider);&lt;br&gt;
    return ListView.builder(&lt;br&gt;
      itemCount: properties.length,&lt;br&gt;
      itemBuilder: (ctx, i) {&lt;br&gt;
        final p = properties[i];&lt;br&gt;
        return ListTile(&lt;br&gt;
          leading: Image.network(p.thumbnail, width: 56, height: 56, fit: BoxFit.cover),&lt;br&gt;
          title: Text(p.title),&lt;br&gt;
          subtitle: Text('${p.city} • \$${p.price}'),&lt;br&gt;
          onTap: () {},&lt;br&gt;
        );&lt;br&gt;
      },&lt;br&gt;
    );&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Production Tips&lt;/p&gt;

&lt;p&gt;Use FutureProvider for API calls with loading/error states.&lt;/p&gt;

&lt;p&gt;Implement pagination with ListView.builder.&lt;/p&gt;

&lt;p&gt;Store favorites in local storage (Hive or SharedPreferences).&lt;/p&gt;

&lt;p&gt;Optimize image loading with caching or CDN.&lt;/p&gt;

&lt;p&gt;Keep accessibility in mind — proper contrast, alt-text, and semantics.&lt;br&gt;
For more practical examples and rental app case studies, check out &lt;a href="https://rentyard.com/" rel="noopener noreferrer"&gt;Rentyard&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>flutter</category>
      <category>tutorial</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Building a Small but Powerful Rental Listing App with Flutter + Riverpod</title>
      <dc:creator>Rentyard</dc:creator>
      <pubDate>Tue, 07 Oct 2025 14:08:52 +0000</pubDate>
      <link>https://forem.com/rentyard/building-a-small-but-powerful-rental-listing-app-with-flutter-riverpod-51a</link>
      <guid>https://forem.com/rentyard/building-a-small-but-powerful-rental-listing-app-with-flutter-riverpod-51a</guid>
      <description>&lt;p&gt;When you start building a real-world rental listing app, things like filtering, asset management (photos/videos), and clean state handling can quickly get complicated.&lt;br&gt;
In this post, I’ll show a practical example of how to build a simple yet scalable architecture using Flutter and Riverpod — clean, testable, and easy to extend.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We’ll Build
&lt;/h2&gt;

&lt;p&gt;Display a list of rental properties (title, location, price, thumbnail).&lt;/p&gt;

&lt;p&gt;Add basic city-based filtering.&lt;/p&gt;

&lt;p&gt;Toggle favorites using local state.&lt;/p&gt;

&lt;p&gt;Keep the architecture clean with Riverpod instead of Redux-style complexity.&lt;/p&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Riverpod?
&lt;/h2&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;p&gt;Simple and predictable.&lt;/p&gt;

&lt;p&gt;Test-friendly and easy to compose.&lt;/p&gt;

&lt;p&gt;Context-free access (no need for BuildContext).&lt;/p&gt;

&lt;p&gt;Works great for both small and large apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Example
&lt;/h2&gt;

&lt;p&gt;Model:&lt;/p&gt;

&lt;p&gt;// models/property.dart&lt;br&gt;
class Property {&lt;br&gt;
  final String id;&lt;br&gt;
  final String title;&lt;br&gt;
  final String city;&lt;br&gt;
  final int price;&lt;br&gt;
  final String thumbnail;&lt;/p&gt;

&lt;p&gt;Property({required this.id, required this.title, required this.city, required this.price, required this.thumbnail});&lt;br&gt;
}&lt;/p&gt;

&lt;h2&gt;
  
  
  Providers:
&lt;/h2&gt;

&lt;p&gt;// providers/property_provider.dart&lt;br&gt;
import 'package:flutter_riverpod/flutter_riverpod.dart';&lt;br&gt;
import '../models/property.dart';&lt;/p&gt;

&lt;p&gt;// sample data provider&lt;br&gt;
final propertyListProvider = Provider&amp;gt;((ref) {&lt;br&gt;
  return [&lt;br&gt;
    Property(id: 'p1', title: 'Cozy 2BR near downtown', city: 'Dhaka', price: 1200, thumbnail: 'https://...'),&lt;br&gt;
    Property(id: 'p2', title: 'Sunny studio', city: 'Chittagong', price: 800, thumbnail: 'https://...'),&lt;br&gt;
  ];&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;final cityFilterProvider = StateProvider((ref) =&amp;gt; null);&lt;/p&gt;

&lt;p&gt;final filteredPropertyProvider = Provider&amp;gt;((ref) {&lt;br&gt;
  final all = ref.watch(propertyListProvider);&lt;br&gt;
  final city = ref.watch(cityFilterProvider);&lt;br&gt;
  if (city == null || city.isEmpty) return all;&lt;br&gt;
  return all.where((p) =&amp;gt; p.city.toLowerCase().contains(city.toLowerCase())).toList();&lt;br&gt;
});&lt;/p&gt;

&lt;h2&gt;
  
  
  UI Widget:
&lt;/h2&gt;

&lt;p&gt;// ui/property_list.dart&lt;br&gt;
import 'package:flutter/material.dart';&lt;br&gt;
import 'package:flutter_riverpod/flutter_riverpod.dart';&lt;br&gt;
import '../providers/property_provider.dart';&lt;/p&gt;

&lt;p&gt;class PropertyListView extends ConsumerWidget {&lt;br&gt;
    Widget build(BuildContext context, WidgetRef ref) {&lt;br&gt;
    final properties = ref.watch(filteredPropertyProvider);&lt;br&gt;
    return ListView.builder(&lt;br&gt;
      itemCount: properties.length,&lt;br&gt;
      itemBuilder: (ctx, i) {&lt;br&gt;
        final p = properties[i];&lt;br&gt;
        return ListTile(&lt;br&gt;
          leading: Image.network(p.thumbnail, width: 56, height: 56, fit: BoxFit.cover),&lt;br&gt;
          title: Text(p.title),&lt;br&gt;
          subtitle: Text('${p.city} • \$${p.price}'),&lt;br&gt;
          onTap: () {},&lt;br&gt;
        );&lt;br&gt;
      },&lt;br&gt;
    );&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Production Tips&lt;/p&gt;

&lt;p&gt;Use FutureProvider for API calls with loading/error states.&lt;/p&gt;

&lt;p&gt;Implement pagination with ListView.builder.&lt;/p&gt;

&lt;p&gt;Store favorites in local storage (Hive or SharedPreferences).&lt;/p&gt;

&lt;p&gt;Optimize image loading with caching or CDN.&lt;/p&gt;

&lt;p&gt;Keep accessibility in mind — proper contrast, alt-text, and semantics.&lt;br&gt;
For more practical examples and rental app case studies, check out &lt;a href="https://rentyard.com/" rel="noopener noreferrer"&gt;Rentyard&lt;/a&gt;&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>flutter</category>
      <category>tutorial</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
