mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-07-17 11:32:05 +00:00
Correctly load in user data and display headers in lists
This commit is contained in:
parent
97cc310460
commit
0be269ee7e
17 changed files with 163 additions and 57 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
package com.habitrpg.android.habitica.extensions
|
package com.habitrpg.android.habitica.extensions
|
||||||
|
|
||||||
import android.text.Html
|
import android.text.Html
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
fun String.fromHtml(): CharSequence {
|
fun String.fromHtml(): CharSequence {
|
||||||
return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
|
return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
|
||||||
|
|
@ -10,3 +11,7 @@ fun String.fromHtml(): CharSequence {
|
||||||
Html.fromHtml(this)
|
Html.fromHtml(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun String.localizedCapitalize(): String {
|
||||||
|
return this.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
|
||||||
|
}
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".ui.activities.TaskListActivity" />
|
<activity android:name=".ui.activities.TaskListActivity" />
|
||||||
|
<activity android:name=".ui.activities.AvatarActivity" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
@ -4,4 +4,4 @@ import android.app.Application
|
||||||
import dagger.hilt.android.HiltAndroidApp
|
import dagger.hilt.android.HiltAndroidApp
|
||||||
|
|
||||||
@HiltAndroidApp
|
@HiltAndroidApp
|
||||||
class MainApplication : Application() { }
|
class MainApplication : Application()
|
||||||
|
|
@ -2,5 +2,4 @@ package com.habitrpg.wearos.habitica.data.repositories
|
||||||
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class TaskLocalRepository @Inject constructor() {
|
class TaskLocalRepository @Inject constructor()
|
||||||
}
|
|
||||||
|
|
@ -2,5 +2,4 @@ package com.habitrpg.wearos.habitica.data.repositories
|
||||||
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class UserLocalRepository @Inject constructor() {
|
class UserLocalRepository @Inject constructor()
|
||||||
}
|
|
||||||
|
|
@ -14,23 +14,30 @@ class Items {
|
||||||
var gear: Gear? = null
|
var gear: Gear? = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
class Profile {
|
||||||
|
var name: String? = null
|
||||||
|
}
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
class User: Avatar {
|
class User: Avatar {
|
||||||
override val currentMount: String? = null
|
override var currentMount: String? = null
|
||||||
override val currentPet: String? = null
|
override var currentPet: String? = null
|
||||||
override val sleep: Boolean = false
|
override var sleep: Boolean = false
|
||||||
override val stats: Stats? = null
|
override var stats: Stats? = null
|
||||||
override val preferences: Preferences? = null
|
override var preferences: Preferences? = null
|
||||||
override val flags: Flags? = null
|
override var flags: Flags? = null
|
||||||
override val gemCount: Int = 0
|
override var gemCount: Int = 0
|
||||||
override val hourglassCount: Int = 0
|
override var hourglassCount: Int = 0
|
||||||
val items: Items? = null
|
var items: Items? = null
|
||||||
override val costume: Outfit?
|
override val costume: Outfit?
|
||||||
get() = items?.gear?.costume
|
get() = items?.gear?.costume
|
||||||
override val equipped: Outfit?
|
override val equipped: Outfit?
|
||||||
get() = items?.gear?.equipped
|
get() = items?.gear?.equipped
|
||||||
override val hasClass: Boolean = false
|
override val hasClass: Boolean = false
|
||||||
|
|
||||||
|
var profile: Profile? = null
|
||||||
|
|
||||||
override fun isValid(): Boolean {
|
override fun isValid(): Boolean {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.habitrpg.wearos.habitica.ui.activities
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import com.habitrpg.wearos.habitica.databinding.ActivityAvatarBinding
|
||||||
|
|
||||||
|
class AvatarActivity: BaseActivity<ActivityAvatarBinding>() {
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
binding = ActivityAvatarBinding.inflate(layoutInflater)
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,6 @@ package com.habitrpg.wearos.habitica.ui.activities
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.content.res.AppCompatResources
|
import androidx.appcompat.content.res.AppCompatResources
|
||||||
|
|
@ -40,16 +39,13 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||||
WearableLinearLayoutManager(this@MainActivity, HabiticaScrollingLayoutCallback())
|
WearableLinearLayoutManager(this@MainActivity, HabiticaScrollingLayoutCallback())
|
||||||
adapter = this@MainActivity.adapter
|
adapter = this@MainActivity.adapter
|
||||||
}
|
}
|
||||||
|
binding.root.post {
|
||||||
|
binding.root.setPaddingRelative(0, (binding.root.height * 0.25).toInt(), 0, (binding.root.height * 0.25).toInt())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
binding.root.post {
|
|
||||||
binding.root.setPaddingRelative(0, (binding.root.height * 0.25).toInt(), 0, (binding.root.height * 0.25).toInt())
|
|
||||||
binding.root.scrollY = 0
|
|
||||||
}
|
|
||||||
adapter.data = listOf(
|
adapter.data = listOf(
|
||||||
MenuItem(
|
MenuItem(
|
||||||
"avatar",
|
"avatar",
|
||||||
|
|
@ -105,17 +101,21 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||||
AppCompatResources.getDrawable(this, R.drawable.ic_settings),
|
AppCompatResources.getDrawable(this, R.drawable.ic_settings),
|
||||||
ContextCompat.getColor(this, R.color.blue_100)
|
ContextCompat.getColor(this, R.color.blue_100)
|
||||||
) {
|
) {
|
||||||
openTasklist(TaskType.REWARD)
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
viewModel.user.observe(this) {
|
viewModel.user.observe(this) {
|
||||||
Log.d("MainActivity", "onStart: ${it.currentPet}")
|
adapter.title = it.profile?.name ?: ""
|
||||||
|
adapter.notifyItemChanged(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun openAvatarActivity() {
|
||||||
|
startActivity(Intent(this, AvatarActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
private fun openTasklist(type: TaskType) {
|
private fun openTasklist(type: TaskType) {
|
||||||
val intent = Intent(this, TaskListActivity::class.java).apply {
|
val intent = Intent(this, TaskListActivity::class.java).apply {
|
||||||
putExtra("task_type", type.name)
|
putExtra("task_type", type.value)
|
||||||
}
|
}
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,9 @@ package com.habitrpg.wearos.habitica.ui.activities
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.wear.widget.WearableLinearLayoutManager
|
import androidx.wear.widget.WearableLinearLayoutManager
|
||||||
|
import com.habitrpg.common.habitica.models.tasks.TaskType
|
||||||
|
import com.habitrpg.wearos.habitica.R
|
||||||
import com.habitrpg.wearos.habitica.databinding.ActivityTasklistBinding
|
import com.habitrpg.wearos.habitica.databinding.ActivityTasklistBinding
|
||||||
import com.habitrpg.wearos.habitica.models.tasks.Task
|
|
||||||
import com.habitrpg.wearos.habitica.ui.adapters.TaskListAdapter
|
import com.habitrpg.wearos.habitica.ui.adapters.TaskListAdapter
|
||||||
import com.habitrpg.wearos.habitica.ui.viewmodels.TaskListViewModel
|
import com.habitrpg.wearos.habitica.ui.viewmodels.TaskListViewModel
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
|
@ -18,22 +19,24 @@ class TaskListActivity: BaseActivity<ActivityTasklistBinding>() {
|
||||||
binding = ActivityTasklistBinding.inflate(layoutInflater)
|
binding = ActivityTasklistBinding.inflate(layoutInflater)
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding.root.apply {
|
binding.root.apply {
|
||||||
isEdgeItemsCenteringEnabled = true
|
|
||||||
layoutManager =
|
layoutManager =
|
||||||
WearableLinearLayoutManager(this@TaskListActivity, HabiticaScrollingLayoutCallback())
|
WearableLinearLayoutManager(this@TaskListActivity, HabiticaScrollingLayoutCallback())
|
||||||
adapter = this@TaskListActivity.adapter
|
adapter = this@TaskListActivity.adapter
|
||||||
}
|
}
|
||||||
|
setAdapterTitle()
|
||||||
adapter.data = listOf(
|
|
||||||
Task().apply { text = "Test 1" },
|
|
||||||
Task().apply { text = "Test 2" },
|
|
||||||
Task().apply { text = "Test 3" },
|
|
||||||
Task().apply { text = "Test 4" },
|
|
||||||
Task().apply { text = "Test 5" }
|
|
||||||
)
|
|
||||||
|
|
||||||
viewModel.tasks.observe(this) {
|
viewModel.tasks.observe(this) {
|
||||||
adapter.data = it
|
adapter.data = it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setAdapterTitle() {
|
||||||
|
adapter.title = when (viewModel.taskType) {
|
||||||
|
TaskType.HABIT -> getString(R.string.habits)
|
||||||
|
TaskType.DAILY -> getString(R.string.dailies)
|
||||||
|
TaskType.TODO -> getString(R.string.todos)
|
||||||
|
TaskType.REWARD -> getString(R.string.rewards)
|
||||||
|
null -> ""
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,37 +4,55 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.habitrpg.common.habitica.extensions.layoutInflater
|
import com.habitrpg.common.habitica.extensions.layoutInflater
|
||||||
|
import com.habitrpg.wearos.habitica.databinding.RowHeaderBinding
|
||||||
import com.habitrpg.wearos.habitica.databinding.RowHubBinding
|
import com.habitrpg.wearos.habitica.databinding.RowHubBinding
|
||||||
import com.habitrpg.wearos.habitica.ui.activities.MenuItem
|
import com.habitrpg.wearos.habitica.ui.activities.MenuItem
|
||||||
|
import com.habitrpg.wearos.habitica.ui.viewHolders.BindableViewHolder
|
||||||
|
import com.habitrpg.wearos.habitica.ui.viewHolders.HeaderViewHolder
|
||||||
|
|
||||||
class HubAdapter: RecyclerView.Adapter<HubViewHolder>() {
|
class HubAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
|
var title: String = ""
|
||||||
var data: List<MenuItem> = listOf()
|
var data: List<MenuItem> = listOf()
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HubViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
return HubViewHolder(RowHubBinding.inflate(parent.context.layoutInflater, parent, false).root)
|
val inflater = parent.context.layoutInflater
|
||||||
|
return if (viewType == 0) {
|
||||||
|
HeaderViewHolder(RowHeaderBinding.inflate(inflater, parent, false).root)
|
||||||
|
} else {
|
||||||
|
HubViewHolder(RowHubBinding.inflate(inflater, parent, false).root)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: HubViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
holder.bind(data[position])
|
if (holder is HubViewHolder) {
|
||||||
|
val item = data[position - 1]
|
||||||
|
holder.bind(item)
|
||||||
|
} else if (holder is HeaderViewHolder){
|
||||||
|
holder.bind(title)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemViewType(position: Int): Int {
|
||||||
|
return if (position == 0) 0 else 1
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return data.size
|
return data.size + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class HubViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
|
class HubViewHolder(itemView: View): BindableViewHolder<MenuItem>(itemView) {
|
||||||
val binding = RowHubBinding.bind(itemView)
|
val binding = RowHubBinding.bind(itemView)
|
||||||
|
|
||||||
fun bind(item: MenuItem) {
|
override fun bind(data: MenuItem) {
|
||||||
binding.title.text = item.title
|
binding.title.text = data.title
|
||||||
binding.iconView.setImageDrawable(item.icon)
|
binding.iconView.setImageDrawable(data.icon)
|
||||||
binding.iconView.setColorFilter(item.color)
|
binding.iconView.setColorFilter(data.color)
|
||||||
binding.root.setOnClickListener {
|
binding.root.setOnClickListener {
|
||||||
item.onClick()
|
data.onClick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5,31 +5,49 @@ import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.habitrpg.common.habitica.extensions.layoutInflater
|
import com.habitrpg.common.habitica.extensions.layoutInflater
|
||||||
import com.habitrpg.wearos.habitica.databinding.RowHabitBinding
|
import com.habitrpg.wearos.habitica.databinding.RowHabitBinding
|
||||||
|
import com.habitrpg.wearos.habitica.databinding.RowHeaderBinding
|
||||||
import com.habitrpg.wearos.habitica.models.tasks.Task
|
import com.habitrpg.wearos.habitica.models.tasks.Task
|
||||||
|
import com.habitrpg.wearos.habitica.ui.viewHolders.BindableViewHolder
|
||||||
|
import com.habitrpg.wearos.habitica.ui.viewHolders.HeaderViewHolder
|
||||||
|
|
||||||
class TaskListAdapter: RecyclerView.Adapter<TaskViewHolder>() {
|
class TaskListAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
|
var title: String = ""
|
||||||
var data: List<Task> = listOf()
|
var data: List<Task> = listOf()
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TaskViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
return TaskViewHolder(RowHabitBinding.inflate(parent.context.layoutInflater, parent, false).root)
|
val inflater = parent.context.layoutInflater
|
||||||
|
return if (viewType == 0) {
|
||||||
|
HeaderViewHolder(RowHeaderBinding.inflate(inflater, parent, false).root)
|
||||||
|
} else {
|
||||||
|
TaskViewHolder(RowHabitBinding.inflate(inflater, parent, false).root)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: TaskViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
holder.bind(data[position])
|
if (holder is TaskViewHolder) {
|
||||||
|
val item = data[position - 1]
|
||||||
|
holder.bind(item)
|
||||||
|
} else if (holder is HeaderViewHolder){
|
||||||
|
holder.bind(title)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemViewType(position: Int): Int {
|
||||||
|
return if (position == 0) 0 else 1
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return data.size
|
return data.size + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TaskViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
class TaskViewHolder(itemView: View) : BindableViewHolder<Task>(itemView) {
|
||||||
val binding = RowHabitBinding.bind(itemView)
|
val binding = RowHabitBinding.bind(itemView)
|
||||||
|
|
||||||
fun bind(task: Task) {
|
override fun bind(task: Task) {
|
||||||
binding.title.text = task.text
|
binding.title.text = task.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.habitrpg.wearos.habitica.ui.viewHolders
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
|
||||||
|
abstract class BindableViewHolder<T>(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||||
|
abstract fun bind(data: T)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.habitrpg.wearos.habitica.ui.viewHolders
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import com.habitrpg.wearos.habitica.databinding.RowHeaderBinding
|
||||||
|
|
||||||
|
class HeaderViewHolder(itemView: View): BindableViewHolder<String>(itemView) {
|
||||||
|
private val binding = RowHeaderBinding.bind(itemView)
|
||||||
|
|
||||||
|
override fun bind(data: String) {
|
||||||
|
binding.textView.text = data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,5 +3,4 @@ package com.habitrpg.wearos.habitica.ui.viewmodels
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import com.habitrpg.wearos.habitica.data.repositories.UserRepository
|
import com.habitrpg.wearos.habitica.data.repositories.UserRepository
|
||||||
|
|
||||||
open class BaseViewModel(val userRepository: UserRepository): ViewModel() {
|
open class BaseViewModel(val userRepository: UserRepository): ViewModel()
|
||||||
}
|
|
||||||
7
wearos/src/main/res/layout/activity_avatar.xml
Normal file
7
wearos/src/main/res/layout/activity_avatar.xml
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
17
wearos/src/main/res/layout/row_header.xml
Normal file
17
wearos/src/main/res/layout/row_header.xml
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="@dimen/spacing_medium">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_view"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
tools:text="Header Text"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textSize="20sp" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/title"
|
android:id="@+id/title"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="18sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
Loading…
Reference in a new issue