Mobile ProgrammingUnit 612 min read
Lists, Adapters, RecyclerView: Dynamic UI & Efficient Data Display
Unit 6 of Mobile Programming: Covers how to display dynamic lists in Android using ListView, RecyclerView, and custom Adapters, with a focus on performance optimization, layout types (Linear, Grid, Staggered), and real-world use cases like e-commerce product grids or chat message threads.
Core Concepts: Lists, Adapters, and RecyclerView
1. Why Lists?
Mobile apps often need to display dynamic data (e.g., chat messages, news feeds, shopping cart items). Static layouts (like LinearLayout) are inefficient for large datasets. Instead, we use lists to render items dynamically.
Key Idea:
- A list is a scrollable container that displays a collection of items (e.g.,
ListView,RecyclerView). - Each item is typically a view (e.g., a
TextView+ImageViewcombo for a chat bubble).
2. ListView vs. RecyclerView: A Performance Showdown
| Feature | ListView | RecyclerView |
|---|---|---|
| Recycling Views | ❌ No (creates new views on scroll) | ✅ Yes (reuses views to save memory) |
| Flexible Layouts | ❌ Only LinearLayout (vertical/horizontal) |
✅ Supports LinearLayoutManager, GridLayoutManager, StaggeredGridLayoutManager |
| Custom Animations | ❌ Limited | ✅ Full control (e.g., item swipe-to-delete) |
| Complex Data | ❌ Struggles with large datasets | ✅ Optimized for 1000+ items |
| Learning Curve | ⚠️ Simpler (but outdated) | 🚀 Steeper (but modern) |
Visual: ListView vs. RecyclerView View Recycling
flowchart TD
subgraph ListView["ListView (No Recycling)"]
A["Item 1"] --> B["Item 2"] --> C["Item 3"]
A -->|"Scroll Down"| D["New Item 1 (Created Fresh)"]
end
subgraph RecyclerView["RecyclerView (Recycling)"]
A["Item 1"] --> B["Item 2"] --> C["Item 3"]
A -->|"Scroll Down"| D["Item 1 Reused (Reassigned to New Data)"]
endWhy RecyclerView is Better:
- Memory Efficiency: Reuses views instead of creating new ones.
- Smooth Scrolling: Critical for apps like WhatsApp (chat threads) or Daraz (product grids).
- Future-Proof: Used in modern Android apps (e.g., Google Maps for dynamic markers).
3. Adapters: The Bridge Between Data and Views
An Adapter connects your data (e.g., an ArrayList) to a list (e.g., RecyclerView). It defines:
- How many items to display (
getItemCount()). - What each item looks like (
getView()oronBindViewHolder()). - How to populate each item (e.g., set text/image).
Example: Adapter for Programming Languages
public class LanguageAdapter extends RecyclerView.Adapter<LanguageAdapter.LanguageViewHolder> {
private List<String> languages;
public LanguageAdapter(List<String> languages) {
this.languages = languages;
}
@NonNull
@Override
public LanguageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_language, parent, false);
return new LanguageViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull LanguageViewHolder holder, int position) {
String lang = languages.get(position);
holder.textView.setText(lang);
// Set image based on position (e.g., icon for Python, Java, etc.)
}
@Override
public int getItemCount() {
return languages.size();
}
static class LanguageViewHolder extends RecyclerView.ViewHolder {
TextView textView;
public LanguageViewHolder(@NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.lang_name);
iconView = itemView.findViewById(R.id.lang_icon);
}
}
}
Visual: Adapter Binding Process
sequenceDiagram
participant App as App
participant Adapter as Adapter
participant RV as RecyclerView
participant VH as ViewHolder
App->>Adapter: onCreateViewHolder()
Adapter->>RV: Inflates layout (item_language.xml)
RV-->>Adapter: Returns ViewHolder
Adapter->>VH: Calls onBindViewHolder()
VH->>VH: Sets text/image (e.g., "Python")
VH-->>Adapter: View bound4. RecyclerView Layout Managers
RecyclerView doesn’t define how items are laid out—it uses LayoutManagers for that. Common types:
| Layout Manager | Use Case | Visualization |
|---|---|---|
| LinearLayoutManager | Vertical/horizontal scroll | ![]() |
| GridLayoutManager | Grid (e.g., Daraz product cards) | ![]() |
| StaggeredGridLayoutManager | Pinch-zoom grids (e.g., Pinterest) | ![]() |
Example: Setting a GridLayoutManager
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new GridLayoutManager(this, 3)); // 3 columns
recyclerView.setAdapter(new LanguageAdapter(languages));
Visual: GridLayoutManager (3 Columns)
| [Python] | [Java] | [C++] |
|----------|---------|---------|
| [Kotlin] | [Swift] | [Go] |
| [Rust] | [PHP] | [Ruby] |
5. Item Decorators and Dividers
Add visual enhancements like:
- Dividers (e.g., gray lines between items in WhatsApp).
- Spacing (e.g., margins between grid items in Daraz).
- Headers/Footers (e.g., "Top Picks" section in a list).
Example: Adding a Divider
recyclerView.addItemDecoration(
new DividerItemDecoration(this, DividerItemDecoration.VERTICAL)
);
Visual: RecyclerView with Dividers
graph TD
A["Item 1"] --> B["Item 2"]
B -->|"Divider"| C["Item 3"]
C --> D["Item 4"]
Divider -->|"Style"| "background: #ddd; height: 1px"6. DiffUtil for Efficient Updates
When data changes (e.g., new messages in WhatsApp), RecyclerView reuses views but needs to know which items changed. DiffUtil compares old and new data to minimize unnecessary view updates.
Example: Using DiffUtil
public class LanguageDiffUtil extends DiffUtil.Callback {
private final List<String> oldLanguages;
private final List<String> newLanguages;
public LanguageDiffUtil(List<String> oldLanguages, List<String> newLanguages) {
this.oldLanguages = oldLanguages;
this.newLanguages = newLanguages;
}
@Override
public int getOldListSize() { return oldLanguages.size(); }
@Override
public int getNewListSize() { return newLanguages.size(); }
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return oldLanguages.get(oldItemPosition).equals(newLanguages.get(newItemPosition));
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return oldLanguages.get(oldItemPosition) == newLanguages.get(newItemPosition);
}
}
Visual: DiffUtil in Action
7. Worked Example: GridView vs. RecyclerView for Languages
Task: Display 5 programming languages in a grid (like Daraz’s product cards).
Option 1: GridView (Legacy)
List<String> languages = Arrays.asList("Python", "Java", "C++", "Kotlin", "Swift");
ArrayAdapter<String> adapter = new ArrayAdapter<>(
this, android.R.layout.simple_list_item_1, languages
);
GridView gridView = findViewById(R.id.grid_view);
gridView.setAdapter(adapter);
gridView.setNumColumns(2); // 2 columns
Problem: No view recycling → poor performance for >50 items.
Option 2: RecyclerView (Modern)
- Layout:
GridLayoutManager(2). - Adapter: Custom
LanguageAdapter(as shown above). - Item Layout (
item_language.xml):<LinearLayout xmlns:android="..." android:orientation="vertical"> <ImageView android:id="@+id/lang_icon" android:layout_width="50dp"/> <TextView android:id="@+id/lang_name" android:layout_width="wrap_content"/> </LinearLayout>
Visual: Final Grid (RecyclerView)
| [Python] | [Java] |
|----------|---------|
| [C++] | [Kotlin]|
| [Swift] | |
Performance Comparison:
| Metric | GridView | RecyclerView |
|---|---|---|
| Memory Usage | High (creates new views) | Low (recycles views) |
| Scroll Speed | Slow (>20 items) | Smooth (1000+ items) |
| Customization | Limited | Full control (animations, etc.) |
8. Real-World Applications
In the Real World
Daraz (Nepal):
- Idea: Uses
RecyclerViewwithGridLayoutManagerto display product cards efficiently. - Why? Smooth scrolling for 1000+ products; view recycling saves memory.
- Worked Example: If Daraz shows 12 products per row, the
GridLayoutManager(3)is set withspanSizeLookupto handle varying item heights (e.g., some items have images + text, others have banners).
- Idea: Uses
WhatsApp (Global):
- Idea: Uses
RecyclerViewwithLinearLayoutManagerfor chat messages. - Why? Supports:
- Left/right alignment (sender/receiver).
- Media previews (images/videos).
- Typing indicators (real-time updates via
DiffUtil).
- Idea: Uses
Pathao (Nepal):
- Idea: Uses
RecyclerViewwithStaggeredGridLayoutManagerfor driver cards. - Why? Pinch-zoom effect for driver photos (staggered rows).
- Idea: Uses
Visual: Pathao’s Driver Grid (StaggeredGridLayoutManager)
graph TD
subgraph Row1
A["Driver 1"] --> B["Driver 2"] --> C["Driver 3"]
end
subgraph Row2
D["Driver 4"] --> E["Driver 5"]
end
subgraph Row3
F["Driver 6"]
end9. Common Pitfalls and Fixes
| Issue | Cause | Solution |
|---|---|---|
| Empty RecyclerView | Adapter not set or data empty |
Check adapter.notifyDataSetChanged() |
| Slow Scrolling | No view recycling | Use RecyclerView + DiffUtil |
| Incorrect Grid Spacing | Missing itemDecoration |
Add GridSpacingItemDecoration |
| Memory Leaks | Holder retains context | Use WeakReference in ViewHolder |
Example: Fixing Slow Scrolling
// Before (slow):
RecyclerView recyclerView = new RecyclerView(this);
recyclerView.setAdapter(new MyAdapter(data));
// After (fast):
RecyclerView recyclerView = new RecyclerView(this);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(new MyAdapter(data));
recyclerView.setHasFixedSize(true); // Optimize for static size
Exam Tip
- Focus on:
- Difference between
ListViewandRecyclerView(always mention view recycling). - LayoutManagers (know when to use
Grid,Linear, orStaggered). - Adapter implementation (show
onCreateViewHolderandonBindViewHolder). - Performance optimizations (e.g.,
DiffUtil,setHasFixedSize).
- Difference between
- Past Exam Question:
"List three features of RecyclerView and develop an app to display 5 languages in GridView."
- Features:
- View recycling (memory efficiency).
- Supports multiple layout managers (
Linear,Grid,Staggered). - Custom animations and item decorators.
- App Code: Use
GridLayoutManager(2)+ customAdapter(as shown above).
- Features:
- Common Marks Lost:
- Forgetting to call
notifyDataSetChanged()after updating data. - Incorrectly setting the number of columns in
GridLayoutManager. - Not using
ViewHolderpattern (leads to performance issues).
- Forgetting to call
Final Note: Always prefer RecyclerView over ListView in modern apps. For grids, use GridLayoutManager; for dynamic lists, use LinearLayoutManager. Optimize with DiffUtil for large datasets!
Based on the TU BCA syllabus for Mobile Programming (CACS351), unit 6.
Discussion
Loading…


