Skip to main content

Layouts

The TechSales Android app uses ConstraintLayout as the foundation for building flexible, performant user interfaces. This page documents the activity_main.xml layout file.

activity_main.xml

Location: ~/workspace/source/TechSales/app/src/main/res/layout/activity_main.xml

Full XML Source

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Layout Structure

Root Element: ConstraintLayout

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android: - Standard Android attributes (layout_width, id, text, etc.)app: - Custom attributes, particularly ConstraintLayout constraintstools: - Design-time attributes (not compiled into APK)

Why ConstraintLayout?

ConstraintLayout uses a flat view hierarchy, reducing the number of nested layouts. This improves rendering performance compared to nested LinearLayouts or RelativeLayouts.Traditional Approach (Nested Layouts):
LinearLayout
└── LinearLayout
    └── RelativeLayout
        └── View
ConstraintLayout Approach:
ConstraintLayout
└── View (directly constrained)
Allows complex layouts without deep view hierarchies. Each view can be positioned relative to:
  • Parent container
  • Other views
  • Guidelines
  • Barriers
  • Chains
Built-in support for:
  • Aspect ratios
  • Percentage-based sizing
  • Circular positioning
  • Dynamic constraints

Child Views

TextView Component

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

Basic Attributes

This TextView is perfectly centered in the screen using ConstraintLayout’s constraint system.
AttributeValueDescription
android:layout_widthwrap_contentWidth adjusts to content size
android:layout_heightwrap_contentHeight adjusts to content size
android:text"Hello World!"Displayed text content

Constraint Attributes

The TextView uses four constraints to achieve perfect centering:
                Parent Top

                [TextView]

Parent Start ←  Centered  → Parent End

                [TextView]

               Parent Bottom
All four constraints create equal pull in all directions, centering the view.

Centering Logic

When a view has opposing constraints (top + bottom, start + end) with no bias, ConstraintLayout automatically centers the view:
Top Constraint + Bottom Constraint = Vertical Centering
Start Constraint + End Constraint = Horizontal Centering
You can adjust the position using bias attributes:
<TextView
    ...
    app:layout_constraintHorizontal_bias="0.3"
    app:layout_constraintVertical_bias="0.7"
    ... />
  • 0.0 = Start/Top
  • 0.5 = Center (default)
  • 1.0 = End/Bottom

ConstraintLayout Patterns

Common Constraint Types

app:layout_constraintTop_toTopOf="@id/other_view"
app:layout_constraintBottom_toBottomOf="@id/other_view"
Aligns edges of two views together.

Material Design Components

While the current layout uses a basic TextView, the app is configured to support Material Design 3 components:
  • MaterialButton: Enhanced buttons with elevation and ripple effects
  • MaterialCardView: Cards with rounded corners and elevation
  • TextInputLayout: Text fields with floating labels
  • MaterialToolbar: App bars with Material Design styling
  • BottomNavigationView: Bottom navigation bars
  • FloatingActionButton: FAB with elevation and animations
  • Chip: Compact elements representing attributes, text, entities, or actions

Example: Adding Material Components

<com.google.android.material.button.MaterialButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Click Me"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

Layout Best Practices

1. Use Appropriate Sizing

<!-- Good: wrap_content for text -->
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

<!-- Good: 0dp for constraint-based sizing -->
<TextView
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent" />

<!-- Avoid: Fixed dp values for variable content -->
<TextView
    android:layout_width="200dp"
    android:layout_height="50dp" />

2. Provide Sufficient Constraints

Every view in ConstraintLayout needs constraints for both horizontal and vertical positioning. Missing constraints will cause views to jump to (0, 0) at runtime.
<!-- Minimum required constraints -->
<View
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toTopOf="parent"    <!-- Vertical -->
    app:layout_constraintStart_toStartOf="parent" <!-- Horizontal -->
    />

3. Use RTL-Aware Attributes

<!-- Good: RTL-aware -->
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"

<!-- Avoid: LTR-only -->
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"

4. Leverage 0dp for Match Constraint

<!-- Fill remaining space between constraints -->
<TextView
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent" />

EdgeToEdge Considerations

Since the app uses EdgeToEdge, this layout receives window insets padding from MainActivity:
// From MainActivity.java:18-21
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
    Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
    v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
    return insets;
});
The ConstraintLayout’s android:id="@+id/main" connects it to this insets handling code.

Visual Effect

[Status Bar Area]
  ↓ Padding applied
┌─────────────────┐
│                 │
│  Hello World!   │  ← Content with safe padding
│                 │
└─────────────────┘
  ↑ Padding applied
[Navigation Bar Area]

Expanding the Layout

When adding more views, maintain the ConstraintLayout structure:
<androidx.constraintlayout.widget.ConstraintLayout ...>
    
    <!-- Header -->
    <TextView
        android:id="@+id/header"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="TechSales"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
    
    <!-- Content -->
    <TextView
        android:id="@+id/content"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="Hello World!"
        app:layout_constraintTop_toBottomOf="@id/header"
        app:layout_constraintBottom_toTopOf="@id/footer"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
    
    <!-- Footer -->
    <TextView
        android:id="@+id/footer"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Footer"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
        
</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity

See how this layout is inflated and used

Overview

Component architecture overview

Build docs developers (and LLMs) love