data binding

This commit is contained in:
JUNGGWAN KIM 2024-10-11 09:34:04 +09:00
parent 46e9865005
commit a190454e00
9 changed files with 231 additions and 163 deletions

View File

@ -60,6 +60,7 @@ android {
buildFeatures { buildFeatures {
viewBinding = true viewBinding = true
dataBinding = true
} }
compileOptions { compileOptions {

View File

@ -83,6 +83,7 @@ import rasel.lunar.launcher.apps.AppDrawer
import rasel.lunar.launcher.apps.DismissCalback import rasel.lunar.launcher.apps.DismissCalback
import rasel.lunar.launcher.apps.SearchMenu import rasel.lunar.launcher.apps.SearchMenu
import rasel.lunar.launcher.databinding.LauncherActivityBinding import rasel.lunar.launcher.databinding.LauncherActivityBinding
import rasel.lunar.launcher.databinding.RecommendedHourlyDressBinding
import rasel.lunar.launcher.feeds.Feeds import rasel.lunar.launcher.feeds.Feeds
import rasel.lunar.launcher.feeds.WidgetHost import rasel.lunar.launcher.feeds.WidgetHost
import rasel.lunar.launcher.helpers.Constants.Companion.KEY_APPLICATION_THEME import rasel.lunar.launcher.helpers.Constants.Companion.KEY_APPLICATION_THEME
@ -411,7 +412,6 @@ internal class LauncherActivity : AppCompatActivity() {
} }
} }
} }
} }
override fun onDestroy() { override fun onDestroy() {

View File

@ -191,7 +191,7 @@ internal class LauncherHome : Fragment() {
mSmsLogsAdapter = SmsLogsAdapter(arrayListOf(), requireContext()) mSmsLogsAdapter = SmsLogsAdapter(arrayListOf(), requireContext())
mNotiAdapter = NotificationItemAdapter(requireContext()) mNotiAdapter = NotificationItemAdapter(requireContext())
mRssAdapter = RssItemAdapter(requireContext()) mRssAdapter = RssItemAdapter(requireContext())
mWeatherAdapter = WeatherAdapter(arrayListOf()) mWeatherAdapter = WeatherAdapter(arrayListOf(),binding.noticeSummary)
// WorkersDb.getRealm().query<WeatherForcast>().first().find()?.forecast?.let { // WorkersDb.getRealm().query<WeatherForcast>().first().find()?.forecast?.let {
// mWeatherAdapter?.update(it.forecastday) // mWeatherAdapter?.update(it.forecastday)
// BLog.LOGE("saved weatherForcast >>> ${it.forecastday}") // BLog.LOGE("saved weatherForcast >>> ${it.forecastday}")

View File

@ -2,34 +2,39 @@ package rasel.lunar.launcher.home.adapters
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.graphics.Color import android.graphics.Color
import android.os.Handler
import android.os.Looper
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import io.realm.kotlin.ext.query
import rasel.lunar.launcher.R 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.home.adapters.WeatherAdapter.ViewHolder
import rasel.lunar.launcher.model.Day import rasel.lunar.launcher.model.Day
import rasel.lunar.launcher.model.Hour import rasel.lunar.launcher.model.Hour
import rasel.lunar.launcher.model.Location
import rasel.lunar.launcher.model.WeatherForcast
import rasel.lunar.launcher.utils.BLog import rasel.lunar.launcher.utils.BLog
import rasel.lunar.launcher.workers.WorkersDb
import java.time.Instant import java.time.Instant
import java.time.ZoneId import java.time.ZoneId
import java.util.Calendar import java.util.Calendar
import java.util.Date import java.util.Date
class WeatherAdapter(private val dataSet: ArrayList<Hour>): RecyclerView.Adapter<ViewHolder>(){ class WeatherAdapter(
private val dataSet: ArrayList<Hour>, private val total : RecommendedHourlyDressBinding): RecyclerView.Adapter<ViewHolder>(){
var isChangedAmOrPm: Boolean = true var isChangedAmOrPm: Boolean = true
class ViewHolder(view: View): RecyclerView.ViewHolder(view) { class ViewHolder(val viewItem: ItemRecHourlyDressBinding): RecyclerView.ViewHolder(viewItem.root)
val viewItem: View
init { // @SuppressLint("NotifyDataSetChanged")
viewItem = view.findViewById(R.id.weather_item)
}
}
// @SuppressLint("NotifyDataSetChanged")
fun update(li: Collection<Hour>) { fun update(li: Collection<Hour>) {
li.toList() li.toList()
this.dataSet.clear() this.dataSet.clear()
@ -47,9 +52,11 @@ class WeatherAdapter(private val dataSet: ArrayList<Hour>): RecyclerView.Adapter
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context) // val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_rec_hourly_dress, parent, false) // .inflate(R.layout.item_rec_hourly_dress, parent, false)
return ViewHolder(view) // 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) fun getToday() = Calendar.getInstance().get(Calendar.DAY_OF_YEAR)
@ -62,68 +69,26 @@ class WeatherAdapter(private val dataSet: ArrayList<Hour>): RecyclerView.Adapter
// today.time = Date(data?.time_epoch?.toLong()?.times(1000L) ?: 0L) // today.time = Date(data?.time_epoch?.toLong()?.times(1000L) ?: 0L)
// val dayOfItem = today.get(Calendar.DAY_OF_YEAR) // val dayOfItem = today.get(Calendar.DAY_OF_YEAR)
data?.let { data?.let {
holder.viewItem.findViewById<TextView>(R.id.amOrPm) total.loc = WorkersDb.getRealm().query<Location>().also {
.apply { BLog.LOGE("re >>> ${it.description()}") // 쿼리 로그
Instant.ofEpochSecond(it.time_epoch.toLong()) }.find().first()
.atZone(ZoneId.systemDefault())
.hour holder.viewItem.setHour(it)
.run { BLog.LOGE("reeeeeeeeeee >>> ${holder.viewItem.hour.text}")
this@apply.text = if (this < 12) "오전" else "오후" holder.viewItem.amOrPm.visibility =
isChangedAmOrPm = when (this) { if (arrayListOf(12, 0).contains(data.toZonedDateTime(it.time_epoch).hour) || position == 0) {
12, 0 -> true View.VISIBLE
else -> false } else View.INVISIBLE
} holder.viewItem.hour.apply {
} if (data.toZonedDateTime(it.time_epoch).hour == 0) {
this.visibility = if (isChangedAmOrPm || position == 0) View.VISIBLE else View.INVISIBLE this@apply.setTextColor(Color.BLACK)
this@apply.isSelected = true
} else {
this@apply.setTextColor(Color.WHITE)
this@apply.isSelected = false
} }
holder.viewItem.findViewById<TextView>(R.id.hour)
.apply {
Instant.ofEpochSecond(it.time_epoch.toLong())
.atZone(ZoneId.systemDefault())
.run {
if (this.hour == 0) {
this@apply.setTextColor(Color.BLACK)
this@apply.isSelected = true
this@apply.text = when (this.dayOfYear - getToday()) {
1 -> "내일"
2 -> "모레"
3 -> "글피"
else -> "${this.dayOfMonth}"
}
} else {
this@apply.setTextColor(Color.WHITE)
this@apply.isSelected = false
this@apply.text = "${this.hour}"
}
}
}
var img: Int? = null
var textDress: String? = null
if (it.temp_c >= 23) {
img = R.drawable.dress_short_sleeves
textDress = "반팔"
} else if ((23 > it.temp_c) && (it.temp_c >= 20)) {
img = R.drawable.dress_long_sleeves
textDress = "긴팔"
} else if ((20 > it.temp_c) && (it.temp_c >= 17)) {
img = R.drawable.dress_knitwear
textDress = "니트"
} else if ((17 > it.temp_c) && (it.temp_c >= 12)) {
img = R.drawable.dress_flimsy_outer
textDress = "얇은겉옷"
} else if ((12 > it.temp_c) && (it.temp_c >= 6)) {
img = R.drawable.dress_heavy_outer
textDress = "두꺼운겉옷"
} else {
img = R.drawable.dress_padded_coat
textDress = "패딩"
} }
holder.viewItem.findViewById<ImageView>(R.id.imgDress) holder.viewItem.imgDress.setImageLevel(it.temp_c.toInt())
.setImageResource(img ?: R.drawable.dress_padded_coat)
holder.viewItem.findViewById<TextView>(R.id.textDress)
.text = textDress
holder.viewItem.findViewById<TextView>(R.id.temperature)
.text = "${it.temp_c}"
} }
} }

View File

@ -5,6 +5,10 @@ import io.realm.kotlin.types.RealmList
import io.realm.kotlin.types.RealmObject import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.Ignore import io.realm.kotlin.types.annotations.Ignore
import io.realm.kotlin.types.annotations.PrimaryKey import io.realm.kotlin.types.annotations.PrimaryKey
import rasel.lunar.launcher.R
import java.time.Instant
import java.time.ZoneId
import java.util.Calendar
class WeatherForcast: RealmObject { class WeatherForcast: RealmObject {
@ -32,6 +36,8 @@ class Location: RealmObject {
var tz_id: String? = null var tz_id: String? = null
var localtime_epoch = 0 var localtime_epoch = 0
var localtime: String? = null var localtime: String? = null
fun getTextLocation(): String = "$name / $country"
} }
class Current: RealmObject { class Current: RealmObject {
@ -176,4 +182,57 @@ class Hour: RealmObject {
var gust_mph = 0.0 var gust_mph = 0.0
var gust_kph = 0.0 var gust_kph = 0.0
var uv = 0.0 var uv = 0.0
fun toZonedDateTime(timeEpoch: Int) = Instant.ofEpochSecond(timeEpoch.toLong())
.atZone(ZoneId.systemDefault())
fun getAmOrPm(): String = toZonedDateTime(time_epoch).hour.run {
if (this < 12) "오전" else "오후"
}
fun getTextHour(): String = toZonedDateTime(time_epoch)
.run {
if (this.hour == 0) {
when (this.dayOfYear - Calendar.getInstance().get(Calendar.DAY_OF_YEAR)) {
1 -> "내일"
2 -> "모레"
3 -> "글피"
else -> "${this.dayOfMonth}"
}
} else {
"${this.hour}"
}
}
fun getDress(): String =
if (temp_c >= 23) {
"반팔"
} else if ((23 > temp_c) && (temp_c >= 20)) {
"긴팔"
} else if ((20 > temp_c) && (temp_c >= 17)) {
"니트"
} else if ((17 > temp_c) && (temp_c >= 12)) {
"얇은겉옷"
} else if ((12 > temp_c) && (temp_c >= 6)) {
"두꺼운겉옷"
} else {
"패딩"
}
fun getImgDress() =
if (temp_c >= 23) {
R.drawable.dress_short_sleeves
} else if ((23 > temp_c) && (temp_c >= 20)) {
"긴팔"
} else if ((20 > temp_c) && (temp_c >= 17)) {
"니트"
} else if ((17 > temp_c) && (temp_c >= 12)) {
"얇은겉옷"
} else if ((12 > temp_c) && (temp_c >= 6)) {
"두꺼운겉옷"
} else {
"패딩"
}
fun getTemp(): String = "${temp_c}"
} }

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:maxLevel="6" android:drawable="@drawable/dress_padded_coat"/>
<item android:minLevel="6" android:maxLevel="12" android:drawable="@drawable/dress_heavy_outer"/>
<item android:minLevel="12" android:maxLevel="17" android:drawable="@drawable/dress_flimsy_outer"/>
<item android:minLevel="17" android:maxLevel="20" android:drawable="@drawable/dress_knitwear"/>
<item android:minLevel="20" android:maxLevel="23" android:drawable="@drawable/dress_long_sleeves"/>
<item android:minLevel="23" android:drawable="@drawable/dress_long_sleeves"/>
</level-list>

View File

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

View File

@ -1,45 +1,68 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <layout xmlns:android="http://schemas.android.com/apk/res/android">
xmlns:app="http://schemas.android.com/apk/res-auto" <data>
xmlns:tools="http://schemas.android.com/tools" <variable name="loc" type="rasel.lunar.launcher.model.Location"/>
android:layout_width="match_parent" </data>
android:layout_height="match_parent" <androidx.constraintlayout.widget.ConstraintLayout
android:textAlignment="center"> xmlns:app="http://schemas.android.com/apk/res-auto"
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/linearLayout"
android:layout_width="409dp"
android:layout_height="wrap_content"
android:gravity="left|center"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<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" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:text="시간별 예보"
android:textAlignment="center"
android:textSize="14sp"
android:layout_marginLeft="10dp"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
app:layout_constraintTop_toBottomOf="@id/linearLayout"
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_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="match_parent"
</androidx.recyclerview.widget.RecyclerView> android:textAlignment="center">
</androidx.constraintlayout.widget.ConstraintLayout> <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="@{loc.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>
</layout>

View File

@ -166,4 +166,5 @@
</string> </string>
<string name="wiki" translatable="false">Wiki</string> <string name="wiki" translatable="false">Wiki</string>
</resources> </resources>