just weather add

This commit is contained in:
JUNGGWAN KIM 2024-10-15 13:01:38 +09:00
parent bad03a7116
commit 0e72b9d3bc
10 changed files with 337 additions and 164 deletions

View File

@ -96,7 +96,7 @@ dependencies {
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.6.4")
implementation("com.squareup.retrofit2:converter-scalars:2.6.4")
implementation("androidx.viewpager2:viewpager2:1.0.0")
// implementation ("me.everything:providers-android:1.0.1")
// implementation ("me.everything:providers-core:1.0.1")
// implementation ("androidx.window:window:1.0.0")

View File

@ -39,7 +39,6 @@ import android.view.View
import android.view.ViewGroup
import android.widget.CheckBox
import android.widget.EditText
import android.widget.RadioButton
import android.widget.TableRow
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
@ -51,31 +50,18 @@ import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.work.OneTimeWorkRequest
import androidx.viewpager2.widget.ViewPager2
import androidx.work.WorkManager
import io.realm.kotlin.Realm
import io.realm.kotlin.ext.asFlow
import io.realm.kotlin.ext.query
import io.realm.kotlin.notifications.InitialObject
import io.realm.kotlin.notifications.InitialResults
import io.realm.kotlin.notifications.ObjectChange
import io.realm.kotlin.notifications.ResultsChange
import io.realm.kotlin.notifications.UpdatedObject
import io.realm.kotlin.notifications.UpdatedResults
import io.realm.kotlin.query.RealmQuery
import io.realm.kotlin.query.RealmResults
import io.realm.kotlin.query.Sort
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import okhttp3.ConnectionPool
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okhttp3.ResponseBody
import org.json.JSONArray
import org.json.JSONObject
import rasel.lunar.launcher.LauncherActivity.Companion.lActivity
@ -94,14 +80,16 @@ import rasel.lunar.launcher.home.adapters.RecentCallsAdapter
import rasel.lunar.launcher.home.adapters.RssItemAdapter
import rasel.lunar.launcher.home.adapters.SmsLogsAdapter
import rasel.lunar.launcher.home.adapters.WeatherAdapter
import rasel.lunar.launcher.home.adapters.WeatherDressAdatper
import rasel.lunar.launcher.home.adapters.WeatherHourlyAdapter
import rasel.lunar.launcher.model.CurrentPlayItem
import rasel.lunar.launcher.model.Hour
import rasel.lunar.launcher.model.Location
import rasel.lunar.launcher.model.NotificationItem
import rasel.lunar.launcher.model.RssData
import rasel.lunar.launcher.model.RssDataInterface
import rasel.lunar.launcher.model.RssDataType
import rasel.lunar.launcher.model.WeatherForcast
import rasel.lunar.launcher.model.WeatherInfoManager
import rasel.lunar.launcher.qaccess.QuickAccess
import rasel.lunar.launcher.settings.SettingsActivity
import rasel.lunar.launcher.utils.BLog
@ -111,10 +99,8 @@ import rasel.lunar.launcher.utils.SimpleFingerGestures
import rasel.lunar.launcher.utils.beforeDay
import rasel.lunar.launcher.view.TableRadioGroup
import rasel.lunar.launcher.workers.LocationGetter
import rasel.lunar.launcher.workers.OpenWeatherGetter
import rasel.lunar.launcher.workers.RecentCall
import rasel.lunar.launcher.workers.RecentSms
import rasel.lunar.launcher.workers.TelegramBotGetter
import rasel.lunar.launcher.workers.WorkersDb
import java.math.BigDecimal
import java.net.URLEncoder
@ -192,7 +178,23 @@ internal class LauncherHome : Fragment() {
mSmsLogsAdapter = SmsLogsAdapter(arrayListOf(), requireContext())
mNotiAdapter = NotificationItemAdapter(requireContext())
mRssAdapter = RssItemAdapter(requireContext())
mWeatherAdapter = WeatherAdapter(arrayListOf(),binding.noticeSummary)
weatherDressAdapter = WeatherDressAdatper(arrayListOf())
weatherHourlyAdapter = WeatherHourlyAdapter(arrayListOf())
mWeatherAdapter = WeatherAdapter(
listOf(
R.layout.hourly_weather,
R.layout.recommended_hourly_dress
),
listOf(
weatherDressAdapter,
weatherHourlyAdapter
),
binding.noticeSummary)
binding.noticeSummary.weatherViewPager.offscreenPageLimit = 2
// mWeatherAdapter = WeatherAdapter(arrayListOf(),binding.noticeSummary)
// WorkersDb.getRealm().query<WeatherForcast>().first().find()?.forecast?.let {
// mWeatherAdapter?.update(it.forecastday)
// BLog.LOGE("saved weatherForcast >>> ${it.forecastday}")
@ -210,13 +212,13 @@ internal class LauncherHome : Fragment() {
binding.mainList.layoutManager = GridLayoutManager(requireContext(),2)
binding.smsList.layoutManager = GridLayoutManager(requireContext(),2)
binding.infoList.layoutManager = LinearLayoutManager(requireContext())
binding.noticeSummary.weatherRecycller.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)
binding.noticeSummary.weatherViewPager.orientation = ViewPager2.ORIENTATION_VERTICAL
binding.mainList.adapter = mRecentCallsAdapter
binding.smsList.adapter = mSmsLogsAdapter
binding.infoList.adapter = mRssAdapter
binding.notiList.adapter = mNotiAdapter
binding.noticeSummary.weatherRecycller.adapter = mWeatherAdapter
binding.noticeSummary.weatherViewPager.adapter = mWeatherAdapter
binding.favAppsGroup.setOnClickListener { searchData() }
try{binding.mainList.removeOnScrollListener(onScrChanged)}catch (e : Exception){e.printStackTrace()}
@ -312,15 +314,34 @@ internal class LauncherHome : Fragment() {
BLog.LOGE("re >>> ${it.description()}")
}.find().let {hours ->
Handler(Looper.getMainLooper()).post {
mWeatherAdapter?.let {
weatherDressAdapter?.let {
it.update(
mutableListOf<Hour>().apply {
this.addAll(it.filter(hours))
this.addAll(
// it.filter(hours)
hours
)
}
)
it.notifyDataSetChanged()
}
weatherHourlyAdapter?.let {
it.update(
mutableListOf<Hour>().apply {
this.addAll(
// it.filter(hours)
hours
)
}
)
BLog.LOGE("hour ${hours}")
it.notifyDataSetChanged()
}
mWeatherAdapter?.let {
binding.noticeSummary.textLocation = if (hours.isNotEmpty()) WeatherInfoManager.getShowingInfo(hours.first()).textLocation else "도시 / 나라"
it.notifyDataSetChanged()
}
}
}
// .asFlow()
// .collect { changes ->
@ -574,6 +595,8 @@ internal class LauncherHome : Fragment() {
lateinit var mRssAdapter : RssItemAdapter
lateinit var mNotiAdapter : NotificationItemAdapter
var mWeatherAdapter: WeatherAdapter? =null
var weatherDressAdapter: WeatherDressAdatper? = null
var weatherHourlyAdapter: WeatherHourlyAdapter? = null
var mRssDataResult : RealmResults<RssData>? = null
var mNotificationResult : RealmResults<NotificationItem>? = null

View File

@ -1,99 +1,46 @@
package rasel.lunar.launcher.home.adapters
import android.annotation.SuppressLint
import android.graphics.Color
import android.os.Handler
import android.os.Looper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import io.realm.kotlin.ext.query
import rasel.lunar.launcher.R
import rasel.lunar.launcher.databinding.ItemRecHourlyDressBinding
import rasel.lunar.launcher.databinding.ListItemWithBinding
import rasel.lunar.launcher.databinding.RecommendedHourlyDressBinding
import rasel.lunar.launcher.home.adapters.WeatherAdapter.ViewHolder
import rasel.lunar.launcher.model.Day
import rasel.lunar.launcher.model.Hour
import rasel.lunar.launcher.model.Location
import rasel.lunar.launcher.model.WeatherForcast
import rasel.lunar.launcher.model.WeatherInfoManager
import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.workers.WorkersDb
import java.time.Instant
import java.time.ZoneId
import java.util.Calendar
import java.util.Date
import rasel.lunar.launcher.databinding.WeatherBookBinding
class WeatherAdapter(
private val dataSet: ArrayList<Hour>, private val total : RecommendedHourlyDressBinding): RecyclerView.Adapter<ViewHolder>(){
var isChangedAmOrPm: Boolean = true
private val pages: List<Int>,
private val adatpers: List<RecyclerView.Adapter<out RecyclerView.ViewHolder>?>,
private val weatherBook: WeatherBookBinding? = null)
: RecyclerView.Adapter<WeatherAdapter.PageViewHolder>() {
class ViewHolder(val viewItem: ItemRecHourlyDressBinding): RecyclerView.ViewHolder(viewItem.root)
class PageViewHolder(val view: View): RecyclerView.ViewHolder(view)
// @SuppressLint("NotifyDataSetChanged")
fun update(li: Collection<Hour>) {
li.toList()
this.dataSet.clear()
this.dataSet.addAll(li)
// notifyDataSetChanged()
@SuppressLint("ResourceType")
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PageViewHolder {
return PageViewHolder(LayoutInflater.from(parent.context).inflate(pages[viewType], parent, false))
}
fun filter(arr: Collection<Hour>) = mutableListOf<Hour>()
.apply {
arr.forEach {
if (it.time_epoch >= (System.currentTimeMillis() / 1000)) {
this.add(it)
override fun onBindViewHolder(holder: PageViewHolder, position: Int) {
if (adatpers[position] != null) {
when (position) {
0 -> holder.view.findViewById<RecyclerView>(R.id.recycler_hourly_weather).apply {
this.adapter = adatpers[position]
this.layoutManager =
LinearLayoutManager(this.context, LinearLayoutManager.HORIZONTAL, false)
}
else -> holder.view.findViewById<RecyclerView>(R.id.weather_dress_recycller).apply {
this.adapter = adatpers[position]
this.layoutManager =
LinearLayoutManager(this.context, LinearLayoutManager.HORIZONTAL, false)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
// val view = LayoutInflater.from(parent.context)
// .inflate(R.layout.item_rec_hourly_dress, parent, false)
// val itemBinding: ItemRecHourlyDressBinding = DataBindingUtil.
val binding = ItemRecHourlyDressBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
fun getToday() = Calendar.getInstance().get(Calendar.DAY_OF_YEAR)
override fun getItemCount(): Int = pages.size
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val data = dataSet[position] as? Hour
BLog.LOGE("saved weatherForcast >>> asFlow ${dataSet.size}")
// val today = Calendar.getInstance()
// today.time = Date(data?.time_epoch?.toLong()?.times(1000L) ?: 0L)
// val dayOfItem = today.get(Calendar.DAY_OF_YEAR)
data?.let {
// total.loc = WorkersDb.getRealm().query<Location>().also {
// BLog.LOGE("re >>> ${it.description()}") // 쿼리 로그
// }.find().first()
WeatherInfoManager.getShowingInfo(it).apply {
total.setInfo(this)
holder.viewItem.setInfo(this)
}
BLog.LOGE("reeeeeeeeeee >>> ${holder.viewItem.hour.text}")
holder.viewItem.amOrPm.visibility =
if (arrayListOf(12, 0).contains(WeatherInfoManager.toZonedDateTime(it.time_epoch).hour) || position == 0) {
View.VISIBLE
} else View.INVISIBLE
holder.viewItem.hour.apply {
if (WeatherInfoManager.toZonedDateTime(it.time_epoch).hour == 0) {
this@apply.setTextColor(Color.BLACK)
this@apply.isSelected = true
} else {
this@apply.setTextColor(Color.WHITE)
this@apply.isSelected = false
}
}
holder.viewItem.imgDress.setImageLevel(it.temp_c.toInt())
}
}
override fun getItemCount(): Int = dataSet.size
override fun getItemViewType(position: Int): Int = position
}

View File

@ -0,0 +1,73 @@
package rasel.lunar.launcher.home.adapters
import android.annotation.SuppressLint
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import rasel.lunar.launcher.databinding.ItemRecHourlyDressBinding
import rasel.lunar.launcher.databinding.RecommendedHourlyDressBinding
import rasel.lunar.launcher.model.Hour
import rasel.lunar.launcher.model.WeatherInfoManager
import rasel.lunar.launcher.utils.BLog
import java.util.Calendar
class WeatherDressAdatper (private val dataSet: ArrayList<Hour>) : RecyclerView.Adapter<WeatherDressAdatper.ViewHolder>(){
var isChangedAmOrPm: Boolean = true
class ViewHolder(val viewItem: ItemRecHourlyDressBinding): RecyclerView.ViewHolder(viewItem.root)
// @SuppressLint("NotifyDataSetChanged")
fun update(li: Collection<Hour>) {
li.toList()
this.dataSet.clear()
this.dataSet.addAll(li)
// notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WeatherDressAdatper.ViewHolder {
// val view = LayoutInflater.from(parent.context)
// .inflate(R.layout.item_rec_hourly_dress, parent, false)
// val itemBinding: ItemRecHourlyDressBinding = DataBindingUtil.
val binding = ItemRecHourlyDressBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return WeatherDressAdatper.ViewHolder(binding)
}
fun getToday() = Calendar.getInstance().get(Calendar.DAY_OF_YEAR)
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: WeatherDressAdatper.ViewHolder, position: Int) {
val data = dataSet[position] as? Hour
BLog.LOGE("saved weatherForcast >>> asFlow ${dataSet.size}")
// val today = Calendar.getInstance()
// today.time = Date(data?.time_epoch?.toLong()?.times(1000L) ?: 0L)
// val dayOfItem = today.get(Calendar.DAY_OF_YEAR)
data?.let {
// total.loc = WorkersDb.getRealm().query<Location>().also {
// BLog.LOGE("re >>> ${it.description()}") // 쿼리 로그
// }.find().first()
WeatherInfoManager.getShowingInfo(it).apply {
// total.setInfo(this)
holder.viewItem.setInfo(this)
}
BLog.LOGE("reeeeeeeeeee >>> ${holder.viewItem.hour.text}")
holder.viewItem.amOrPm.visibility =
if (arrayListOf(12, 0).contains(WeatherInfoManager.toZonedDateTime(it.time_epoch).hour) || position == 0) {
View.VISIBLE
} else View.INVISIBLE
holder.viewItem.hour.apply {
if (WeatherInfoManager.toZonedDateTime(it.time_epoch).hour == 0) {
this@apply.setTextColor(Color.BLACK)
this@apply.isSelected = true
} else {
this@apply.setTextColor(Color.WHITE)
this@apply.isSelected = false
}
}
holder.viewItem.imgDress.setImageLevel(it.temp_c.toInt())
}
}
override fun getItemCount(): Int = dataSet.size
}

View File

@ -0,0 +1,56 @@
package rasel.lunar.launcher.home.adapters
import android.annotation.SuppressLint
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import rasel.lunar.launcher.databinding.ItemHourlyWeatherBinding
import rasel.lunar.launcher.databinding.ItemRecHourlyDressBinding
import rasel.lunar.launcher.model.Hour
import rasel.lunar.launcher.model.WeatherInfoManager
import rasel.lunar.launcher.utils.BLog
class WeatherHourlyAdapter(private val dataSet: ArrayList<Hour>): RecyclerView.Adapter<WeatherHourlyAdapter.ViewHolder>() {
class ViewHolder(val viewItem: ItemHourlyWeatherBinding): RecyclerView.ViewHolder(viewItem.root)
override fun onCreateViewHolder(parent: ViewGroup, type: Int): WeatherHourlyAdapter.ViewHolder {
val binding = ItemHourlyWeatherBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return WeatherHourlyAdapter.ViewHolder(binding)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val data = dataSet[position] as? Hour
BLog.LOGE("saved weatherForcast >>> asFlow ${dataSet.size}")
data?.let {
WeatherInfoManager.getShowingInfo(it).apply {
holder.viewItem.setInfo(this)
}
BLog.LOGE("reeeeeeeeeee >>> ${holder.viewItem.hour.text}")
holder.viewItem.amOrPm.visibility =
if (arrayListOf(12, 0).contains(WeatherInfoManager.toZonedDateTime(it.time_epoch).hour) || position == 0) {
View.VISIBLE
} else View.INVISIBLE
holder.viewItem.hour.apply {
if (WeatherInfoManager.toZonedDateTime(it.time_epoch).hour == 0) {
this@apply.setTextColor(Color.BLACK)
this@apply.isSelected = true
} else {
this@apply.setTextColor(Color.WHITE)
this@apply.isSelected = false
}
}
holder.viewItem.imgDress.setImageLevel(it.temp_c.toInt())
}
}
override fun getItemCount(): Int = dataSet.size
fun update(li: Collection<Hour>) {
BLog.LOGE("${this.javaClass.simpleName} update")
li.toList()
this.dataSet.clear()
this.dataSet.addAll(li)
}
}

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_hourly_weather"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
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">
</androidx.recyclerview.widget.RecyclerView>

View File

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable name="info" type="rasel.lunar.launcher.model.ShowingWeatherInfo"/>
</data>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="80dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_height="wrap_content"
android:gravity="center">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/amOrPm"
android:gravity="center"
android:text="@{info.amOrPm}"
android:fontFamily="sans-serif-medium"
android:textSize="14sp" />
<TextView
android:layout_width="50dp"
android:layout_height="wrap_content"
android:id="@+id/hour"
android:background="@drawable/date_bg"
android:fontFamily="sans-serif-medium"
android:gravity="center"
android:textSize="14sp"
android:text="@{info.textHour}"
android:textAlignment="center"/>
<ImageView
android:id="@+id/imgDress"
android:layout_width="40dp"
android:src="@drawable/level_dress_img"
android:layout_height="40dp"
android:contentDescription="온도별 옷차림"
app:tint="@android:color/white"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textDress"
android:fontFamily="sans-serif-light"
android:textSize="11sp"
android:text="@{info.dress}"
android:gravity="center"
android:textAlignment="center"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/temperature"
android:text="@{info.temp}"
android:fontFamily="sans-serif-medium"
android:textSize="14sp"
android:gravity="center"
android:textAlignment="center"/>
</LinearLayout>
</layout>

View File

@ -130,7 +130,7 @@
<include
android:id="@+id/noticeSummary"
layout="@layout/recommended_hourly_dress"
layout="@layout/weather_book"
android:layout_margin="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"

View File

@ -3,66 +3,9 @@
<data>
<variable name="info" type="rasel.lunar.launcher.model.ShowingWeatherInfo"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/weather_dress_recycller"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAlignment="center">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
android:id="@+id/header">
<ImageView
android:id="@+id/imageView"
android:layout_width="25dp"
android:layout_height="25dp"
android:contentDescription="시계 아이콘"
app:srcCompat="@drawable/ico_time"
tools:ignore="ImageContrastCheck"
android:layout_marginLeft="20dp"
app:tint="@android:color/white"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/textView2"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<TextView
android:id="@+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:text="시간별 예보"
android:gravity="left"
android:textSize="14sp"
android:layout_marginLeft="10dp"
app:layout_constraintStart_toEndOf="@id/imageView"
app:layout_constraintEnd_toStartOf="@id/textViewLocation"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintWidth_default="spread"/>
<TextView
android:id="@+id/textViewLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:text="@{info.textLocation}"
android:textAlignment="center"
android:textSize="11sp"
android:layout_marginRight="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
app:layout_constraintTop_toBottomOf="@id/header"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:id="@+id/weather_recycller"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</androidx.recyclerview.widget.RecyclerView>
</androidx.constraintlayout.widget.ConstraintLayout>
android:layout_height="match_parent">
</androidx.recyclerview.widget.RecyclerView>
</layout>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="textLocation" type="String"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
android:id="@+id/header"
android:paddingVertical="5dp">
<ImageView
android:id="@+id/imageView"
android:layout_width="25dp"
android:layout_height="25dp"
android:contentDescription="시계 아이콘"
app:srcCompat="@drawable/ico_time"
tools:ignore="ImageContrastCheck"
android:layout_marginLeft="20dp"
app:tint="@android:color/white"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/textView2"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<TextView
android:id="@+id/textView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:text="시간별 예보"
android:gravity="left"
android:textSize="14sp"
android:layout_marginLeft="10dp"
app:layout_constraintStart_toEndOf="@id/imageView"
app:layout_constraintEnd_toStartOf="@id/textViewLocation"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintWidth_default="spread"/>
<TextView
android:id="@+id/textViewLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:text="@{textLocation}"
android:textAlignment="center"
android:textSize="11sp"
android:layout_marginRight="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/weatherViewPager"
android:layout_width="match_parent"
android:layout_height="120dp"
app:layout_constraintTop_toBottomOf="@+id/header"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>