mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-04-14 19:56:32 +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
|
||||
|
||||
import android.text.Html
|
||||
import java.util.Locale
|
||||
|
||||
fun String.fromHtml(): CharSequence {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
fun String.localizedCapitalize(): String {
|
||||
return this.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
|
||||
}
|
||||
|
|
@ -36,6 +36,7 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".ui.activities.TaskListActivity" />
|
||||
<activity android:name=".ui.activities.AvatarActivity" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
@ -4,4 +4,4 @@ import android.app.Application
|
|||
import dagger.hilt.android.HiltAndroidApp
|
||||
|
||||
@HiltAndroidApp
|
||||
class MainApplication : Application() { }
|
||||
class MainApplication : Application()
|
||||
|
|
@ -2,5 +2,4 @@ package com.habitrpg.wearos.habitica.data.repositories
|
|||
|
||||
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
|
||||
|
||||
class UserLocalRepository @Inject constructor() {
|
||||
}
|
||||
class UserLocalRepository @Inject constructor()
|
||||
|
|
@ -14,23 +14,30 @@ class Items {
|
|||
var gear: Gear? = null
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
class Profile {
|
||||
var name: String? = null
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
class User: Avatar {
|
||||
override val currentMount: String? = null
|
||||
override val currentPet: String? = null
|
||||
override val sleep: Boolean = false
|
||||
override val stats: Stats? = null
|
||||
override val preferences: Preferences? = null
|
||||
override val flags: Flags? = null
|
||||
override val gemCount: Int = 0
|
||||
override val hourglassCount: Int = 0
|
||||
val items: Items? = null
|
||||
override var currentMount: String? = null
|
||||
override var currentPet: String? = null
|
||||
override var sleep: Boolean = false
|
||||
override var stats: Stats? = null
|
||||
override var preferences: Preferences? = null
|
||||
override var flags: Flags? = null
|
||||
override var gemCount: Int = 0
|
||||
override var hourglassCount: Int = 0
|
||||
var items: Items? = null
|
||||
override val costume: Outfit?
|
||||
get() = items?.gear?.costume
|
||||
override val equipped: Outfit?
|
||||
get() = items?.gear?.equipped
|
||||
override val hasClass: Boolean = false
|
||||
|
||||
var profile: Profile? = null
|
||||
|
||||
override fun isValid(): Boolean {
|
||||
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.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
|
|
@ -40,16 +39,13 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||
WearableLinearLayoutManager(this@MainActivity, HabiticaScrollingLayoutCallback())
|
||||
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() {
|
||||
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(
|
||||
MenuItem(
|
||||
"avatar",
|
||||
|
|
@ -105,17 +101,21 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
|||
AppCompatResources.getDrawable(this, R.drawable.ic_settings),
|
||||
ContextCompat.getColor(this, R.color.blue_100)
|
||||
) {
|
||||
openTasklist(TaskType.REWARD)
|
||||
}
|
||||
)
|
||||
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) {
|
||||
val intent = Intent(this, TaskListActivity::class.java).apply {
|
||||
putExtra("task_type", type.name)
|
||||
putExtra("task_type", type.value)
|
||||
}
|
||||
startActivity(intent)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package com.habitrpg.wearos.habitica.ui.activities
|
|||
import android.os.Bundle
|
||||
import androidx.activity.viewModels
|
||||
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.models.tasks.Task
|
||||
import com.habitrpg.wearos.habitica.ui.adapters.TaskListAdapter
|
||||
import com.habitrpg.wearos.habitica.ui.viewmodels.TaskListViewModel
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
|
@ -18,22 +19,24 @@ class TaskListActivity: BaseActivity<ActivityTasklistBinding>() {
|
|||
binding = ActivityTasklistBinding.inflate(layoutInflater)
|
||||
super.onCreate(savedInstanceState)
|
||||
binding.root.apply {
|
||||
isEdgeItemsCenteringEnabled = true
|
||||
layoutManager =
|
||||
WearableLinearLayoutManager(this@TaskListActivity, HabiticaScrollingLayoutCallback())
|
||||
adapter = this@TaskListActivity.adapter
|
||||
}
|
||||
|
||||
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" }
|
||||
)
|
||||
setAdapterTitle()
|
||||
|
||||
viewModel.tasks.observe(this) {
|
||||
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 androidx.recyclerview.widget.RecyclerView
|
||||
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.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()
|
||||
set(value) {
|
||||
field = value
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HubViewHolder {
|
||||
return HubViewHolder(RowHubBinding.inflate(parent.context.layoutInflater, parent, false).root)
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
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) {
|
||||
holder.bind(data[position])
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
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 {
|
||||
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)
|
||||
|
||||
fun bind(item: MenuItem) {
|
||||
binding.title.text = item.title
|
||||
binding.iconView.setImageDrawable(item.icon)
|
||||
binding.iconView.setColorFilter(item.color)
|
||||
override fun bind(data: MenuItem) {
|
||||
binding.title.text = data.title
|
||||
binding.iconView.setImageDrawable(data.icon)
|
||||
binding.iconView.setColorFilter(data.color)
|
||||
binding.root.setOnClickListener {
|
||||
item.onClick()
|
||||
data.onClick()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,31 +5,49 @@ import android.view.ViewGroup
|
|||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.habitrpg.common.habitica.extensions.layoutInflater
|
||||
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.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()
|
||||
set(value) {
|
||||
field = value
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TaskViewHolder {
|
||||
return TaskViewHolder(RowHabitBinding.inflate(parent.context.layoutInflater, parent, false).root)
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
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) {
|
||||
holder.bind(data[position])
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
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 {
|
||||
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)
|
||||
|
||||
fun bind(task: Task) {
|
||||
override fun bind(task: Task) {
|
||||
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 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
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="18sp" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
Loading…
Reference in a new issue