A clean, two-screen Android app for renting musical instruments. Users browse instruments, pick a color, select a rental duration, and confirm the borrow. The app follows Material Design, passes data between screens using Intents + Parcelable, returns results with onActivityResult, and surfaces feedback with Snackbar/Toast. Automated UI checks are written with Espresso.
- Features
- Screens
- Architecture
- Data Flow
- UI/UX Choices
- Validation & Error Handling
- Testing
- Project Structure
- Requirements
- Quick Start
- Usage
- Roadmap
- Credits
- License
- Browse instruments with image, name, description, rating, and credits per month.
- Select options: color via
RadioGroup+RadioButton; rating viaRatingBar. - Borrow flow: enter duration (months), validate inputs, and confirm.
- Credit tracking: show current credit; block actions when credits are insufficient.
- Responsive feedback:
- Snackbar for actionable errors near the source control.
- Toast for quick confirmations/cancellations.
- Data passing:
Parcelablemodel moves instrument data between activities. - Round-trip result: return updated credit to the browser screen with
onActivityResult. - Automated UI tests with Espresso: navigation, browsing, validation, and credit updates.
- Welcome / Get Started → CTA that launches browsing.
- Instrument Browser → Next/Prev browsing; shows details, rating, and color options; “Borrow”.
- Borrow Details → Selected instrument recap, duration input, Confirm / Cancel.
Add your screenshots here once you export them from the report:
images/welcome.pngimages/browse.pngimages/borrow.png
A simple two-activity flow with clear responsibilities.
| Layer | Responsibility | Key Pieces |
|---|---|---|
| UI | Material components, layout XML | ConstraintLayout, LinearLayout, ImageView, TextView, Button, RatingBar, RadioGroup |
| Data Model | Parcelable instrument payload | data class Instrument(...): Parcelable |
| Navigation | Screen-to-screen and result return | Intent, putExtra, startActivityForResult, onActivityResult |
| Feedback | User messages | Snackbar (errors, validation), Toast (confirm/info) |
| Tests | UI automation | Espresso test cases (navigation/browse/validate/credit) |
flowchart LR
A[Welcome<br/>Get Started] --> B[Browser<br/>Instrument details]
B -->|Borrow| C[Borrow Details<br/>Duration + Confirm]
C -->|Confirm OK| D{Enough credits?}
D -->|No| E[Snackbar: Not enough credit]
D -->|Yes| F[Update credit<br/>Toast confirm]
F --> G[Return result to Browser]
G --> B
C -->|Cancel| H[Toast cancel] --> B
@Parcelize
data class Instrument(
val name: String,
val description: String,
val price: Int, // credits per month
val rating: Float,
val colorOptions: List<String>,
val imageRes: Int
) : Parcelable// Browser → Borrow Details
val intent = Intent(this, BorrowDetailsActivity::class.java).apply {
putExtra("instrument", currentInstrument)
putExtra("currentCredit", currentCredit)
putExtra("selectedColor", selectedColor)
}
startActivityForResult(intent, REQUEST_BORROW)
// Borrow Details → Browser (after confirm)
val result = Intent().putExtra("updatedCredit", newCredit)
setResult(Activity.RESULT_OK, result)
finish()
// Browser receives result
override fun onActivityResult(req: Int, res: Int, data: Intent?) {
super.onActivityResult(req, res, data)
if (req == REQUEST_BORROW && res == Activity.RESULT_OK) {
currentCredit = data?.getIntExtra("updatedCredit", currentCredit) ?: currentCredit
creditView.text = "Credit: $currentCredit"
}
}- Material Design styling for buttons, text, spacing, and consistent theming.
- ConstraintLayout as the default for flexible responsive positioning.
- LinearLayout for simple vertical/horizontal sections where appropriate.
- Contextual messaging: use Snackbar for input/validation issues placed near the control; Toast for short success info.
- Duration checks: required, positive integer.
- Color required: block proceed if no color is chosen (Snackbar prompt).
- Credit guard: compare
duration * priceagainstcurrentCredit; show Snackbar when insufficient. - Success & cancel: confirm with Toast.
Automated UI tests with Espresso cover:
- Navigation: welcome → browser → borrow → back with result.
- Browsing: “Next” updates instrument name/description/image/price correctly.
- Validation: empty/invalid duration and missing color show Snackbar.
- Credit handling: confirming a borrow deducts credits and returns updated value.
Example navigation test (sketch):
@Test fun navigationWorks() {
onView(withId(R.id.getStarted)).perform(click())
onView(withId(R.id.instrumentDetailsLayout)).check(matches(isDisplayed()))
onView(withId(R.id.nextButton)).perform(click())
onView(withId(R.id.borrowButton)).perform(click())
onView(withId(R.id.borrowDetailsLayout)).check(matches(isDisplayed()))
}/app
src/main/java/...
ui/
MainActivity # Welcome / Get Started
BrowserActivity # Browse instruments (a.k.a. MainActivity2 in report)
BorrowDetailsActivity
model/
Instrument.kt # Parcelable data class
util/
Extensions.kt # (optional helpers)
src/androidTest/java/... # Espresso tests
src/main/res/
layout/ # XML layouts (ConstraintLayout/LinearLayout)
drawable/ # icons / images
values/ # colors, styles (Material theme), strings
- Android Studio (latest stable)
- Kotlin plugin (bundled)
- Android SDK + emulator/device
# Clone
git clone https://github.com/your-username/instrument-rental-android.git
cd instrument-rental-android
# Open with Android Studio
# Build → Run on emulator or device- Launch app and tap Get Started.
- Browse instruments with Next; pick a Color.
- Tap Borrow, enter Duration (months), Confirm.
- If credits are enough → success Toast; credit is deducted and shown back on the browser screen.
If not enough → Snackbar explains what’s missing.
- Login/profile to persist credit and history.
- Animated transitions and richer UI states.
- Instrument search/filter and favorites.
- Local persistence (Room) or remote backend (Firebase) for real data.
- Built with Kotlin, Android Studio, Material Design, and Espresso.
- Wireframes created in Figma.
- Report, sketches, and code screenshots informed this README.
MIT.