Initial: BusSchedule127 Android app (Kotlin, dark theme, bus icon)
- Расписание автобуса №127 Полярные Зори — Зашеек - Вкладки Будни/Суббота/Воскресенье - Ближайшие рейсы с подсчётом 'через N мин' (МСК) - Тёмная тема, Material-карточки, чипы расписания - Адаптивная иконка-автобус
This commit is contained in:
42
.gitignore
vendored
Normal file
42
.gitignore
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
# Built application files
|
||||
*.apk
|
||||
*.aar
|
||||
*.ap_
|
||||
*.aab
|
||||
|
||||
# Files for the ART/Dalvik VM
|
||||
*.dex
|
||||
|
||||
# Java class files
|
||||
*.class
|
||||
|
||||
# Generated files
|
||||
bin/
|
||||
gen/
|
||||
out/
|
||||
release/
|
||||
|
||||
# Gradle files
|
||||
.gradle/
|
||||
build/
|
||||
gradle-8.6/
|
||||
gradle-8.6-bin.zip
|
||||
!gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Local configuration file (sdk path, etc)
|
||||
local.properties
|
||||
|
||||
# Signing keys
|
||||
*.keystore
|
||||
*.jks
|
||||
|
||||
# Log/OS Files
|
||||
*.log
|
||||
|
||||
# Android Studio / IntelliJ
|
||||
*.iml
|
||||
.idea/
|
||||
.DS_Store
|
||||
captures/
|
||||
.externalNativeBuild/
|
||||
.cxx/
|
||||
78
README.md
Normal file
78
README.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Автобус №127 — Расписание (Android)
|
||||
|
||||
[](#лицензия)
|
||||
|
||||
Приложение для Android с расписанием автобуса **№127** по маршруту
|
||||
**Полярные Зори ⇄ Зашеек** (Мурманская область, Кандалакшский район).
|
||||
Написано на **Kotlin** с использованием **Android SDK** и Material Components.
|
||||
Тёмная тема, аккуратные карточки и «чипы» расписания.
|
||||
|
||||
## Возможности
|
||||
|
||||
- Расписание на **будни**, **субботу** и **воскресенье** (переключатель вкладок).
|
||||
- Блок **«Ближайшие рейсы»** — три ближайших отправления с подсчётом
|
||||
«через N минут» (время по **МСК**, обновляется каждые 30 сек).
|
||||
- Полные списки рейсов **туда** (ПЗ → Зашеек) и **обратно** (Зашеек → ПЗ),
|
||||
аккуратно переносящиеся по 5 в строке.
|
||||
- Тёмная тема (#121212) с оранжево-красным акцентом.
|
||||
- Адаптивная иконка-автобус (Adaptive Icon).
|
||||
- Живые часы местного времени (МСК) в шапке.
|
||||
|
||||
## Скриншот
|
||||
|
||||
<sub>Иконка приложения — стилизованный автобус на градиентном фоне.</sub>
|
||||
|
||||
## Технические данные
|
||||
|
||||
| Параметр | Значение |
|
||||
|-----------------|-----------------------------------|
|
||||
| Язык | Kotlin 1.9.22 |
|
||||
| Минимальный SDK | 26 (Android 8.0) |
|
||||
| Целевой SDK | 34 (Android 14) |
|
||||
| Сборка | Gradle 8.6 + Android Gradle Plugin 8.2.2 |
|
||||
| UI | Material Components, ConstraintLayout |
|
||||
|
||||
## Сборка
|
||||
|
||||
Проект собирается системным Gradle (на хосте `192.168.1.46` gradle распакован
|
||||
в `~/BusSchedule127/gradle-8.6`):
|
||||
|
||||
```bash
|
||||
export ANDROID_HOME=~/Android/Sdk
|
||||
export JAVA_HOME=/usr
|
||||
export PATH=$PATH:~/BusSchedule127/gradle-8.6/bin
|
||||
|
||||
cd BusSchedule127
|
||||
gradle clean assembleRelease --no-daemon
|
||||
```
|
||||
|
||||
Подписанный APK появится в:
|
||||
`app/build/outputs/apk/release/app-release.apk`
|
||||
|
||||
> Для подписи используется keystore `~/bus127.keystore` (alias `bus127`).
|
||||
> Секретные ключи в репозиторий не включены — генерируйте свои
|
||||
> через `keytool` перед релизной сборкой.
|
||||
|
||||
## Структура
|
||||
|
||||
```
|
||||
BusSchedule127/
|
||||
├── app/
|
||||
│ ├── build.gradle
|
||||
│ └── src/main/
|
||||
│ ├── AndroidManifest.xml
|
||||
│ ├── java/ru/ua1zbe/bus127/MainActivity.kt
|
||||
│ └── res/
|
||||
│ ├── drawable/ # фоны, чипы, иконка-автобус
|
||||
│ ├── layout/ # activity_main.xml
|
||||
│ ├── mipmap-anydpi-v26/ # адаптивная иконка
|
||||
│ └── values/ # colors, strings, themes
|
||||
├── build.gradle
|
||||
├── settings.gradle
|
||||
├── gradle.properties
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Лицензия
|
||||
|
||||
MIT — свободное использование и модификация.
|
||||
46
app/build.gradle
Normal file
46
app/build.gradle
Normal file
@@ -0,0 +1,46 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'org.jetbrains.kotlin.android'
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'ru.ua1zbe.bus127'
|
||||
compileSdk 34
|
||||
|
||||
defaultConfig {
|
||||
applicationId "ru.ua1zbe.bus127"
|
||||
minSdk 26
|
||||
targetSdk 34
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
storeFile file(System.getProperty("user.home") + "/bus127.keystore")
|
||||
storePassword "ktdbycrbq1980"
|
||||
keyAlias "bus127"
|
||||
keyPassword "ktdbycrbq1980"
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '17'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.core:core-ktx:1.12.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'com.google.android.material:material:1.11.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
}
|
||||
23
app/src/main/AndroidManifest.xml
Normal file
23
app/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:label="№127 Расписание"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:theme="@style/Theme.Bus127"
|
||||
android:supportsRtl="true">
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:screenOrientation="portrait">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
191
app/src/main/java/ru/ua1zbe/bus127/MainActivity.kt
Normal file
191
app/src/main/java/ru/ua1zbe/bus127/MainActivity.kt
Normal file
@@ -0,0 +1,191 @@
|
||||
package ru.ua1zbe.bus127
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.widget.Button
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import java.time.Duration
|
||||
import java.time.LocalTime
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
private val mskZone = ZoneId.of("Europe/Moscow")
|
||||
|
||||
private val schedule = mapOf(
|
||||
"weekday" to Pair(
|
||||
listOf("06:20","07:00","08:30","10:35","11:50","12:20","13:20","14:20","14:50","16:20","17:40","19:10","21:10"),
|
||||
listOf("06:30","07:25","09:00","11:05","12:20","12:50","13:50","14:50","15:25","17:00","18:10","19:40","21:40")
|
||||
),
|
||||
"saturday" to Pair(
|
||||
listOf("07:00","08:20","09:35","11:00","13:20","14:50","16:20","17:50","19:00","21:10"),
|
||||
listOf("07:25","08:45","10:05","11:30","13:50","15:45","16:45","18:20","19:30","21:40")
|
||||
),
|
||||
"sunday" to Pair(
|
||||
listOf("07:00","09:35","13:20","14:50","17:40","21:10"),
|
||||
listOf("07:25","10:05","13:50","15:25","18:10","21:40")
|
||||
)
|
||||
)
|
||||
|
||||
private val dayKeys = listOf("weekday", "saturday", "sunday")
|
||||
private var selectedDay = 0
|
||||
|
||||
private lateinit var nearContainer: LinearLayout
|
||||
private lateinit var toContainer: LinearLayout
|
||||
private lateinit var backContainer: LinearLayout
|
||||
private lateinit var dayButtons: List<Button>
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
nearContainer = findViewById(R.id.nearContainer)
|
||||
toContainer = findViewById(R.id.toContainer)
|
||||
backContainer = findViewById(R.id.backContainer)
|
||||
|
||||
val btnWeekday = findViewById<Button>(R.id.btnWeekday)
|
||||
val btnSaturday = findViewById<Button>(R.id.btnSaturday)
|
||||
val btnSunday = findViewById<Button>(R.id.btnSunday)
|
||||
dayButtons = listOf(btnWeekday, btnSaturday, btnSunday)
|
||||
|
||||
dayButtons.forEachIndexed { i, btn ->
|
||||
btn.setOnClickListener {
|
||||
selectedDay = i
|
||||
render()
|
||||
}
|
||||
}
|
||||
|
||||
render()
|
||||
startClock()
|
||||
}
|
||||
|
||||
private fun startClock() {
|
||||
val clock = findViewById<TextView>(R.id.clock)
|
||||
val fmt = DateTimeFormatter.ofPattern("HH:mm")
|
||||
val tick = object : Runnable {
|
||||
override fun run() {
|
||||
clock.text = "Местное время: ${LocalTime.now(mskZone).format(fmt)} (МСК)"
|
||||
handler.postDelayed(this, 30000)
|
||||
}
|
||||
}
|
||||
tick.run()
|
||||
}
|
||||
|
||||
private fun render() {
|
||||
dayButtons.forEachIndexed { i, btn ->
|
||||
if (i == selectedDay) {
|
||||
btn.setBackgroundColor(Color.parseColor("#FF8A65"))
|
||||
btn.setTextColor(Color.parseColor("#000000"))
|
||||
} else {
|
||||
btn.setBackgroundColor(Color.parseColor("#1E1E1E"))
|
||||
btn.setTextColor(Color.parseColor("#E0E0E0"))
|
||||
}
|
||||
}
|
||||
|
||||
val (toList, backList) = schedule[dayKeys[selectedDay]]!!
|
||||
|
||||
nearContainer.removeAllViews()
|
||||
val now = LocalTime.now(mskZone)
|
||||
val all = mutableListOf<Triple<String, String, Long>>()
|
||||
toList.forEach { t -> diffMins(now, t)?.let { all.add(Triple(t, "→", it)) } }
|
||||
backList.forEach { t -> diffMins(now, t)?.let { all.add(Triple(t, "←", it)) } }
|
||||
all.sortBy { it.third }
|
||||
val nearest = all.take(3)
|
||||
|
||||
if (nearest.isEmpty()) {
|
||||
val tv = TextView(this)
|
||||
tv.text = "На сегодня рейсов больше нет"
|
||||
tv.setTextColor(Color.parseColor("#9E9E9E"))
|
||||
tv.textSize = 15f
|
||||
nearContainer.addView(tv)
|
||||
} else {
|
||||
nearest.forEach { (t, dir, mins) ->
|
||||
addNearRow(dir, t, mins)
|
||||
}
|
||||
}
|
||||
|
||||
toContainer.removeAllViews()
|
||||
addChips(toContainer, toList)
|
||||
backContainer.removeAllViews()
|
||||
addChips(backContainer, backList)
|
||||
}
|
||||
|
||||
private fun addNearRow(dir: String, t: String, mins: Long) {
|
||||
val row = LinearLayout(this)
|
||||
row.layoutParams = LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||
row.orientation = LinearLayout.HORIZONTAL
|
||||
row.gravity = android.view.Gravity.CENTER_VERTICAL
|
||||
row.setPadding(0, 6, 0, 6)
|
||||
|
||||
val dot = android.view.View(this)
|
||||
dot.background = resources.getDrawable(R.drawable.bg_dot, null)
|
||||
val dp = (10 * resources.displayMetrics.density).toInt()
|
||||
val dotParams = LinearLayout.LayoutParams(dp, dp)
|
||||
dotParams.setMargins(0, 0, 14, 0)
|
||||
dot.layoutParams = dotParams
|
||||
row.addView(dot)
|
||||
|
||||
val tv = TextView(this)
|
||||
tv.text = "$dir $t (через ${formatMins(mins)})"
|
||||
tv.setTextColor(Color.parseColor("#E0E0E0"))
|
||||
tv.textSize = 17f
|
||||
tv.setTypeface(null, if (mins < 30) android.graphics.Typeface.BOLD else android.graphics.Typeface.NORMAL)
|
||||
row.addView(tv)
|
||||
|
||||
nearContainer.addView(row)
|
||||
}
|
||||
|
||||
private fun addChips(parent: LinearLayout, times: List<String>) {
|
||||
val perRow = 5
|
||||
times.chunked(perRow).forEach { rowTimes ->
|
||||
val row = LinearLayout(this)
|
||||
row.layoutParams = LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||
row.orientation = LinearLayout.HORIZONTAL
|
||||
row.gravity = android.view.Gravity.START
|
||||
row.setPadding(0, 0, 0, 4)
|
||||
rowTimes.forEach { t ->
|
||||
val tv = TextView(this)
|
||||
tv.text = t
|
||||
tv.setTextColor(Color.parseColor("#E0E0E0"))
|
||||
tv.textSize = 15f
|
||||
tv.gravity = android.view.Gravity.CENTER
|
||||
tv.setBackgroundResource(R.drawable.bg_chip)
|
||||
val pad = (10 * resources.displayMetrics.density).toInt()
|
||||
tv.setPadding(pad, pad / 2, pad, pad / 2)
|
||||
val lp = LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||
lp.setMargins(0, 0, 8, 0)
|
||||
tv.layoutParams = lp
|
||||
row.addView(tv)
|
||||
}
|
||||
parent.addView(row)
|
||||
}
|
||||
}
|
||||
|
||||
private fun diffMins(now: LocalTime, t: String): Long? {
|
||||
val p = t.split(":")
|
||||
val lt = LocalTime.of(p[0].toInt(), p[1].toInt())
|
||||
val mins = Duration.between(now, lt).toMinutes()
|
||||
return if (mins >= 0) mins else null
|
||||
}
|
||||
|
||||
private fun formatMins(mins: Long): String {
|
||||
return if (mins < 60) "$mins мин"
|
||||
else {
|
||||
val h = mins / 60
|
||||
val m = mins % 60
|
||||
"$h ч" + if (m > 0) " $m мин" else ""
|
||||
}
|
||||
}
|
||||
}
|
||||
7
app/src/main/res/drawable/bg_chip.xml
Normal file
7
app/src/main/res/drawable/bg_chip.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#2A2A2A" />
|
||||
<corners android:radius="16dp" />
|
||||
<stroke android:width="1dp" android:color="#3A3A3A" />
|
||||
</shape>
|
||||
5
app/src/main/res/drawable/bg_dot.xml
Normal file
5
app/src/main/res/drawable/bg_dot.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<solid android:color="#FF8A65" />
|
||||
</shape>
|
||||
9
app/src/main/res/drawable/bg_header.xml
Normal file
9
app/src/main/res/drawable/bg_header.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<gradient
|
||||
android:startColor="#FF8A65"
|
||||
android:endColor="#F4511E"
|
||||
android:angle="135" />
|
||||
<corners android:radius="14dp" />
|
||||
</shape>
|
||||
5
app/src/main/res/drawable/ic_launcher_background.xml
Normal file
5
app/src/main/res/drawable/ic_launcher_background.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="#1E1E1E" />
|
||||
</shape>
|
||||
40
app/src/main/res/drawable/ic_launcher_foreground.xml
Normal file
40
app/src/main/res/drawable/ic_launcher_foreground.xml
Normal file
@@ -0,0 +1,40 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<!-- bus body -->
|
||||
<path
|
||||
android:fillColor="#FF8A65"
|
||||
android:pathData="M22,44 L82,44 a8,8 0 0 1 8,8 L90,80 a6,6 0 0 1 -6,6 L24,86 a6,6 0 0 1 -6,-6 L18,52 a8,8 0 0 1 8,-8 Z" />
|
||||
<!-- windshield -->
|
||||
<path
|
||||
android:fillColor="#1E1E1E"
|
||||
android:pathData="M74,48 L84,48 a4,4 0 0 1 4,4 L88,62 L74,62 Z" />
|
||||
<!-- side windows -->
|
||||
<path
|
||||
android:fillColor="#1E1E1E"
|
||||
android:pathData="M24,48 L70,48 L70,62 L24,62 Z" />
|
||||
<!-- window dividers -->
|
||||
<path
|
||||
android:fillColor="#FF8A65"
|
||||
android:pathData="M38,48 L38,62 M52,48 L52,62 M62,48 L62,62" />
|
||||
<!-- headlight -->
|
||||
<path
|
||||
android:fillColor="#FFE0D6"
|
||||
android:pathData="M84,70 L88,70 L88,76 L84,76 Z" />
|
||||
<!-- wheels -->
|
||||
<path
|
||||
android:fillColor="#1E1E1E"
|
||||
android:pathData="M34,86 m-8,0 a8,8 0 1,0 16,0 a8,8 0 1,0 -16,0" />
|
||||
<path
|
||||
android:fillColor="#1E1E1E"
|
||||
android:pathData="M72,86 m-8,0 a8,8 0 1,0 16,0 a8,8 0 1,0 -16,0" />
|
||||
<!-- wheel hubs -->
|
||||
<path
|
||||
android:fillColor="#FF8A65"
|
||||
android:pathData="M34,86 m-3,0 a3,3 0 1,0 6,0 a3,3 0 1,0 -6,0" />
|
||||
<path
|
||||
android:fillColor="#FF8A65"
|
||||
android:pathData="M72,86 m-3,0 a3,3 0 1,0 6,0 a3,3 0 1,0 -6,0" />
|
||||
</vector>
|
||||
153
app/src/main/res/layout/activity_main.xml
Normal file
153
app/src/main/res/layout/activity_main.xml
Normal file
@@ -0,0 +1,153 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#121212">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="14dp">
|
||||
|
||||
<!-- Header -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp"
|
||||
android:background="@drawable/bg_header">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="🚌 Автобус №127"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Полярные Зори ⇄ Зашеек"
|
||||
android:textColor="#FFE0D6"
|
||||
android:textSize="15sp"
|
||||
android:layout_marginTop="4dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/clock"
|
||||
android:text="--:--"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="15sp"
|
||||
android:layout_marginTop="8dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Day tabs -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="3"
|
||||
android:layout_marginTop="14dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnWeekday"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Будни"
|
||||
android:layout_margin="3dp"
|
||||
android:textSize="13sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnSaturday"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Суббота"
|
||||
android:layout_margin="3dp"
|
||||
android:textSize="13sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnSunday"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Воскр."
|
||||
android:layout_margin="3dp"
|
||||
android:textSize="13sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Nearest card -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:background="@drawable/bg_chip"
|
||||
android:padding="16dp"
|
||||
android:layout_marginTop="14dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="БЛИЖАЙШИЕ РЕЙСЫ"
|
||||
android:textColor="#F4511E"
|
||||
android:textSize="13sp"
|
||||
android:textStyle="bold"
|
||||
android:letterSpacing="0.05" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/nearContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginTop="8dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- To card -->
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="ТУДА ПЗ → Зашеек"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="15sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginTop="18dp"
|
||||
android:layout_marginBottom="8dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/toContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" />
|
||||
|
||||
<!-- Back card -->
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="ОБРАТНО Зашеек → ПЗ"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="15sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginTop="18dp"
|
||||
android:layout_marginBottom="8dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/backContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Время местное (МСК). Расписание может меняться."
|
||||
android:textColor="#616161"
|
||||
android:textSize="11sp"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="20dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Normal file
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
Normal file
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
11
app/src/main/res/values/colors.xml
Normal file
11
app/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="bg">#121212</color>
|
||||
<color name="surface">#1E1E1E</color>
|
||||
<color name="surface2">#2A2A2A</color>
|
||||
<color name="text">#E0E0E0</color>
|
||||
<color name="muted">#9E9E9E</color>
|
||||
<color name="accent">#FF8A65</color>
|
||||
<color name="accentDark">#F4511E</color>
|
||||
<color name="accentSoft">#FFE0D6</color>
|
||||
</resources>
|
||||
3
app/src/main/res/values/strings.xml
Normal file
3
app/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">№127 Расписание</string>
|
||||
</resources>
|
||||
11
app/src/main/res/values/themes.xml
Normal file
11
app/src/main/res/values/themes.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<style name="Theme.Bus127" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||
<item name="android:colorBackground">#121212</item>
|
||||
<item name="colorPrimary">#FF8A65</item>
|
||||
<item name="colorOnPrimary">#000000</item>
|
||||
<item name="android:textColor">#E0E0E0</item>
|
||||
<item name="colorSurface">#1E1E1E</item>
|
||||
<item name="android:windowBackground">#121212</item>
|
||||
</style>
|
||||
</resources>
|
||||
4
build.gradle
Normal file
4
build.gradle
Normal file
@@ -0,0 +1,4 @@
|
||||
plugins {
|
||||
id 'com.android.application' version '8.2.2' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.9.22' apply false
|
||||
}
|
||||
3
gradle.properties
Normal file
3
gradle.properties
Normal file
@@ -0,0 +1,3 @@
|
||||
org.gradle.jvmargs=-Xmx1536m -Dfile.encoding=UTF-8
|
||||
android.useAndroidX=true
|
||||
kotlin.code.style=official
|
||||
16
settings.gradle
Normal file
16
settings.gradle
Normal file
@@ -0,0 +1,16 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
dependencyResolutionManagement {
|
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
rootProject.name = 'BusSchedule127'
|
||||
include ':app'
|
||||
Reference in New Issue
Block a user