Synchronizing DatePicker and TimePicker with Live Text Feedback
A concise pattern for wiring Android’s native date and time selectors to a single TextView that always reflects the user’s latest choice.
Layout (res/layout/activity_datetime.xml)
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<LinearLayout
android:orientation="vertical"
android:padding="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/lblDateTime"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<DatePicker
android:id="@+id/pickerDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:startYear="1970"
android:endYear="2030" />
<TimePicker
android:id="@+id/pickerTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
Activity (DateTimeActivity.java)
public class DateTimeActivity extends AppCompatActivity {
private TextView lblDateTime;
private DatePicker pickerDate;
private TimePicker pickerTime;
@Override protected void onCreate(Bundle b) {
super.onCreate(b);
setContentView(R.layout.activity_datetime);
lblDateTime = findViewById(R.id.lblDateTime);
pickerDate = findViewById(R.id.pickerDate);
pickerTime = findViewById(R.id.pickerTime);
Calendar now = Calendar.getInstance();
pickerDate.init(now.get(Calendar.YEAR),
now.get(Calendar.MONTH),
now.get(Calendar.DAY_OF_MONTH),
(v, y, m, d) -> refreshLabel());
pickerTime.setIs24HourView(false);
pickerTime.setHour(now.get(Calendar.HOUR_OF_DAY));
pickerTime.setMinute(now.get(Calendar.MINUTE));
pickerTime.setOnTimeChangedListener((v, h, m) -> refreshLabel());
refreshLabel();
}
private void refreshLabel() {
int y = pickerDate.getYear();
int m = pickerDate.getMonth() + 1;
int d = pickerDate.getDayOfMonth();
int h = pickerTime.getHour();
int mm = pickerTime.getMinute();
String amPm = h >= 12 ? "PM" : "AM";
h = h % 12 == 0 ? 12 : h % 12;
lblDateTime.setText(String.format(Locale.getDefault(),
"%04d-%02d-%02d %02d:%02d %s",
y, m, d, h, mm, amPm));
}
}
Choosing the Right Layout Container
ConstraintLayout
Ideal when you need flat, flexible positionign without nesting.
<androidx.constraintlayout.widget.ConstraintLayout ...>
<TextView
android:id="@+id/title"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/action"
app:layout_constraintTop_toBottomOf="@id/title"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
RelativeLayout
Useful for aligning siblings to each other or to parent edges.
<RelativeLayout ...>
<TextView
android:id="@+id/label"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true" />
<EditText
android:layout_below="@id/label"
android:layout_alignStart="@id/label" />
<Button
android:id="@+id/ok"
android:layout_below="@id/label"
android:layout_alignParentEnd="true" />
<Button
android:id="@+id/cancel"
android:layout_toStartOf="@id/ok"
android:layout_alignTop="@id/ok" />
</RelativeLayout>
LinearLayout
Perfect for simple horizontal or vertical stacks.
<LinearLayout
android:orientation="vertical"
android:="match_parent"
android:layout_height="wrap_content">
<Button ... />
<Button ... />
</LinearLayout>
ScrollView
Wrap any single child—often a LinearLayout—to keep content scrollable.
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:padding="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView ... />
<Button ... />
<CalendarView ... />
<Button ... />
</LinearLayout>
</ScrollView>
Each container serves a distinct purpose; combine them as needed to craft responsive, maintainable interafces.