fix merge conflicts

dev_raz_wip
Razmig Sarkissian 7 years ago
commit 73c5f27a19
  1. 61
      app/src/androidTest/java/net/pokeranalytics/android/ExampleInstrumentedUnitTest.kt
  2. 138
      app/src/main/java/net/pokeranalytics/android/model/LiveData.kt
  3. 4
      app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
  4. 2
      app/src/main/java/net/pokeranalytics/android/model/realm/TimeFrame.kt
  5. 50
      app/src/main/java/net/pokeranalytics/android/ui/adapter/TableSizeGridAdapter.kt
  6. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/EditableDataFragment.kt
  7. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt
  8. 1
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetData.kt
  9. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDoubleEditTextFragment.kt
  10. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDoubleListFragment.kt
  11. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetEditTextFragment.kt
  12. 17
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt
  13. 6
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListFragment.kt
  14. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetSumFragment.kt
  15. 82
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetTableSizeGridFragment.kt
  16. 34
      app/src/main/java/net/pokeranalytics/android/ui/view/GridSpacingItemDecoration.kt
  17. 11
      app/src/main/java/net/pokeranalytics/android/util/Extensions.kt
  18. 4
      app/src/main/res/layout/bottom_sheet_double_list.xml
  19. 11
      app/src/main/res/layout/bottom_sheet_grid.xml
  20. 2
      app/src/main/res/layout/bottom_sheet_list.xml
  21. 26
      app/src/main/res/layout/row_bottom_sheet_grid_title.xml

@ -1,5 +1,6 @@
package net.pokeranalytics.android
import android.os.Looper
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.realm.RealmResults
import net.pokeranalytics.android.calculus.Calculator
@ -167,26 +168,26 @@ class ExampleInstrumentedUnitTest : RealmInstrumentedUnitTest() {
Assert.fail("No netbbPer100Hands stat")
}
// val stdHourly = results.computedStat(Stat.STANDARD_DEVIATION_HOURLY)
// if (stdHourly != null) {
// assertEquals(111.8, stdHourly.value, delta)
// } else {
// Assert.fail("No stdHourly stat")
// }
//
// val std = results.computedStat(Stat.STANDARD_DEVIATION)
// if (std != null) {
// assertEquals(200.0, std.value, delta)
// } else {
// Assert.fail("No std stat")
// }
//
// val std100 = results.computedStat(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS)
// if (std100 != null) {
// assertEquals(503.12, std100.value, delta)
// } else {
// Assert.fail("No std100 stat")
// }
val stdHourly = results.computedStat(Stat.STANDARD_DEVIATION_HOURLY)
if (stdHourly != null) {
assertEquals(141.42, stdHourly.value, delta)
} else {
Assert.fail("No stdHourly stat")
}
val std = results.computedStat(Stat.STANDARD_DEVIATION)
if (std != null) {
assertEquals(282.84, std.value, delta)
} else {
Assert.fail("No std stat")
}
val std100 = results.computedStat(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS)
if (std100 != null) {
assertEquals(707.1, std100.value, delta)
} else {
Assert.fail("No std100 stat")
}
}
@ -335,16 +336,16 @@ class ExampleInstrumentedUnitTest : RealmInstrumentedUnitTest() {
fun testOverlappingSessionDeletion() {
val realm = this.mockRealm
// this.sessions = realm.where(Session::class.java).findAll() // monitor session deletions
// Looper.prepare()
// this.sessions?.addChangeListener { t, changeSet ->
//
// val deletedSessions = realm.where(Session::class.java).`in`("id", changeSet.deletions.toTypedArray()).findAll()
// deletedSessions.forEach { it.cleanup() }
//
// }
// Looper.loop()
this.sessions = realm.where(Session::class.java).findAll() // monitor session deletions
Looper.prepare()
this.sessions?.addChangeListener { t, changeSet ->
val deletedSessions = realm.where(Session::class.java).`in`("id", changeSet.deletions.toTypedArray()).findAll()
deletedSessions.forEach { it.cleanup() }
}
Looper.loop()
realm.beginTransaction()

@ -13,86 +13,102 @@ import net.pokeranalytics.android.ui.view.Localizable
* An interface to easily handle the validity of any object we want to save
*/
interface ObjectSavable {
fun isValidForSave(): Boolean { return true }
fun isValidForSave(): Boolean {
return true
}
}
/**
* An enum managing the business objects related to a realm results
*/
enum class LiveData : Localizable {
BANKROLL,
GAME,
LOCATION,
TOURNAMENT_FEATURE,
TRANSACTION_TYPE;
BANKROLL,
GAME,
LOCATION,
TOURNAMENT_FEATURE,
TRANSACTION_TYPE;
fun items(realm: Realm, fieldName: String? = null, sortOrder: Sort? = null): RealmResults<*> {
return realm.where(this.relatedEntity).findAll().sort(fieldName?:this.sortingFieldName, sortOrder?:this.sorting)
}
fun items(realm: Realm, fieldName: String? = null, sortOrder: Sort? = null): RealmResults<*> {
return realm.where(this.relatedEntity).findAll()
.sort(fieldName ?: this.sortingFieldName, sortOrder ?: this.sorting)
}
private var sortingFieldName: String = "name"
private var sorting: Sort = Sort.ASCENDING
/**
* Return a copy of a RealmResults
*/
fun itemsArray(realm: Realm, fieldName: String? = null, sortOrder: Sort? = null): ArrayList<*> {
val results: ArrayList<Any> = ArrayList()
results.addAll(
realm.copyFromRealm(
realm.where(this.relatedEntity).findAll().sort(
fieldName ?: this.sortingFieldName, sortOrder ?: this.sorting
)
)
)
return results
}
private val relatedEntity: Class < out RealmObject >
get() {
return when (this) {
BANKROLL -> Bankroll::class.java
GAME -> Game::class.java
LOCATION -> Location::class.java
TOURNAMENT_FEATURE -> TournamentFeature::class.java
TRANSACTION_TYPE -> TransactionType::class.java
}
}
private var sortingFieldName: String = "name"
private var sorting: Sort = Sort.ASCENDING
fun newEntity(): RealmObject {
return when (this) {
BANKROLL -> Bankroll()
GAME -> Game()
LOCATION -> Location()
TOURNAMENT_FEATURE -> TournamentFeature()
TRANSACTION_TYPE -> TransactionType()
}
}
fun getData(realm:Realm, primaryKey:String?): RealmObject? {
var proxyItem: RealmObject? = null
primaryKey?.let {
val t = realm.where(this.relatedEntity).equalTo("id", it).findFirst()
t?.let {
proxyItem = t
}
}
return proxyItem
}
private val relatedEntity: Class<out RealmObject>
get() {
return when (this) {
BANKROLL -> Bankroll::class.java
GAME -> Game::class.java
LOCATION -> Location::class.java
TOURNAMENT_FEATURE -> TournamentFeature::class.java
TRANSACTION_TYPE -> TransactionType::class.java
}
}
fun deleteData(realm:Realm, data:LiveDataDataSource) {
realm.where(this.relatedEntity).equalTo("id", data.primaryKey).findAll().deleteAllFromRealm()
}
fun updateOrCreate(realm:Realm, primaryKey:String?): RealmObject {
val proxyItem: RealmObject? = this.getData(realm, primaryKey)
proxyItem?.let {
return proxyItem
} ?: run {
return this.newEntity()
/* realm.beginTransaction()
val t = realm.createObject(this.relatedEntity, UUID.randomUUID().toString())
realm.commitTransaction()
return realm.copyFromRealm(t)*/
}
}
val proxyItem: RealmObject? = this.getData(realm, primaryKey)
proxyItem?.let {
return proxyItem
} ?: run {
return this.newEntity()
}
}
override val resId: Int?
get() {
return when (this) {
BANKROLL -> R.string.bankroll
GAME -> R.string.game
LOCATION -> R.string.location
TOURNAMENT_FEATURE -> R.string.tournament_type
TRANSACTION_TYPE -> R.string.operation_types
}
}}
fun newEntity(): RealmObject {
return when (this) {
BANKROLL -> Bankroll()
GAME -> Game()
LOCATION -> Location()
TOURNAMENT_FEATURE -> TournamentFeature()
TRANSACTION_TYPE -> TransactionType()
}
}
fun getData(realm: Realm, primaryKey: String?): RealmObject? {
var proxyItem: RealmObject? = null
primaryKey?.let {
val t = realm.where(this.relatedEntity).equalTo("id", it).findFirst()
t?.let {
proxyItem = t
}
}
return proxyItem
}
override val resId: Int?
get() {
return when (this) {
BANKROLL -> R.string.bankroll
GAME -> R.string.game
LOCATION -> R.string.location
TOURNAMENT_FEATURE -> R.string.tournament_type
TRANSACTION_TYPE -> R.string.operation_types
}
}
}
/*
interface ListableDataSource {

@ -249,6 +249,7 @@ open class Session : RealmObject(), SessionInterface, RowRepresentableDataSource
SessionRow.GAME -> game?.title ?: "--"
SessionRow.LOCATION -> location?.title ?: "--"
SessionRow.BANKROLL -> bankroll?.title ?: "--"
SessionRow.TABLE_SIZE -> tableSize?.toString() ?: "--"
SessionRow.START_DATE -> if (timeFrame != null) timeFrame?.startDate?.short() ?: "--" else "--"
SessionRow.END_DATE -> if (timeFrame != null) timeFrame?.endDate?.short() ?: "--" else "--"
SessionRow.COMMENT -> if (comment.isNotEmpty()) comment else "--"
@ -292,6 +293,7 @@ open class Session : RealmObject(), SessionInterface, RowRepresentableDataSource
data.add(BottomSheetData("", inputType = InputType.TYPE_CLASS_NUMBER))
data.add(BottomSheetData("", inputType = InputType.TYPE_CLASS_NUMBER))
}
SessionRow.TABLE_SIZE -> {data.add(BottomSheetData(tableSize))}
SessionRow.GAME -> {
// Add current game & games list
data.add(BottomSheetData(game, data = LiveData.GAME.items(realm)))
@ -325,7 +327,7 @@ open class Session : RealmObject(), SessionInterface, RowRepresentableDataSource
localResult.buyin = value as Double
result = localResult
}
SessionRow.TABLE_SIZE -> tableSize = value as Int?
SessionRow.GAME -> game = value as Game?
SessionRow.BANKROLL -> bankroll = value as Bankroll?
SessionRow.LOCATION -> location = value as Location?

@ -51,7 +51,7 @@ open class TimeFrame : RealmObject() {
@Ignore
var session: Session? = null
//get() = this.sessions?.first() ?: null
get() = if (this.sessions != null && this.sessions.isEmpty()) null else this.sessions?.first()
// Group
@LinkingObjects("timeFrame")

@ -0,0 +1,50 @@
package net.pokeranalytics.android.ui.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.row_bottom_sheet_grid_title.view.*
import net.pokeranalytics.android.R
class TableSizeGridAdapter(private var tableSizes: ArrayList<String>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
companion object {
const val ROW_TABLE_SIZE: Int = 100
}
var onClickOnItem: ((position: Int) -> Unit)? = null
inner class CellSessionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(tableSize: String) {
itemView.title.text = tableSize
itemView.container.setOnClickListener {
onClickOnItem?.invoke(adapterPosition)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
when (viewType) {
ROW_TABLE_SIZE -> return CellSessionViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.row_bottom_sheet_grid_title, parent, false))
else -> throw IllegalStateException("Need to implement type $viewType in HistoryAdapter")
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (getItemViewType(position)) {
ROW_TABLE_SIZE -> (holder as TableSizeGridAdapter.CellSessionViewHolder).bind(tableSizes[position])
}
}
override fun getItemCount(): Int {
return tableSizes.size
}
override fun getItemViewType(position: Int): Int {
return ROW_TABLE_SIZE
}
}

@ -56,7 +56,7 @@ class EditableDataFragment : PokerAnalyticsFragment(), RowRepresentableDelegate,
rowRepresentableAdapter.refreshRow(row)
}
override fun setValue(value: Any, row: RowRepresentable) {
override fun setValue(value: Any?, row: RowRepresentable) {
(this.item as RowEditable).updateValue(value, row)
this.getRealm().executeTransaction {
it.copyToRealmOrUpdate(this.item)

@ -93,7 +93,7 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Bott
sessionAdapter.refreshRow(row)
}
override fun setValue(value: Any, row: RowRepresentable) {
override fun setValue(value: Any?, row: RowRepresentable) {
currentSession.updateValue(value, row)
sessionAdapter.refreshRow(row)
}

@ -2,7 +2,6 @@ package net.pokeranalytics.android.ui.fragment.components.bottomsheet
import android.text.InputType
import io.realm.RealmResults
import net.pokeranalytics.android.ui.view.RowRepresentable
class BottomSheetData(
var defaultValue: Any? = null,

@ -26,7 +26,7 @@ class BottomSheetDoubleEditTextFragment : BottomSheetFragment() {
editText1.requestFocus()
}
override fun getValue(): Any {
override fun getValue(): Any? {
return values
}

@ -52,7 +52,7 @@ class BottomSheetDoubleListFragment : BottomSheetFragment(), LiveDataDelegate {
val viewManager = LinearLayoutManager(requireContext())
val dataAdapter = LiveDataAdapter(this, R.layout.row_bottom_sheet_title)
gameNameRecyclerView.apply {
reyclerView1.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = dataAdapter

@ -26,7 +26,7 @@ class BottomSheetEditTextFragment : BottomSheetFragment() {
editText1.requestFocus()
}
override fun getValue(): Any {
override fun getValue(): Any? {
return value
}

@ -24,7 +24,7 @@ enum class BottomSheetType {
interface BottomSheetDelegate {
fun clickOnAdd(row: RowRepresentable)
fun clickOnClear(row: RowRepresentable)
fun setValue(value: Any, row: RowRepresentable)
fun setValue(value: Any?, row: RowRepresentable)
}
@ -37,14 +37,15 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
companion object {
fun create(
fragmentManager: FragmentManager?,
row: RowRepresentable,
bottomSheetDelegate: BottomSheetDelegate,
data: ArrayList<BottomSheetData>
fragmentManager: FragmentManager?,
row: RowRepresentable,
bottomSheetDelegate: BottomSheetDelegate,
data: ArrayList<BottomSheetData>
): BottomSheetFragment {
val bottomSheetFragment = when (row.bottomSheetType) {
BottomSheetType.LIST -> BottomSheetListFragment()
BottomSheetType.GRID -> BottomSheetTableSizeGridFragment()
BottomSheetType.DOUBLE_LIST -> BottomSheetDoubleListFragment()
BottomSheetType.EDIT_TEXT -> BottomSheetEditTextFragment()
BottomSheetType.DOUBLE_EDIT_TEXT -> BottomSheetDoubleEditTextFragment()
@ -61,7 +62,7 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_bottom_sheet,container,false)
return inflater.inflate(R.layout.fragment_bottom_sheet, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -113,8 +114,8 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
return data
}
open fun getValue(): Any {
return Any()
open fun getValue(): Any? {
return null
}
/**

@ -5,7 +5,7 @@ import android.view.LayoutInflater
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import io.realm.RealmResults
import kotlinx.android.synthetic.main.bottom_sheet_double_list.*
import kotlinx.android.synthetic.main.bottom_sheet_list.*
import kotlinx.android.synthetic.main.fragment_bottom_sheet.view.*
import net.pokeranalytics.android.R
import net.pokeranalytics.android.model.realm.Game
@ -58,7 +58,7 @@ class BottomSheetListFragment : BottomSheetFragment(), LiveDataDelegate {
val bottomSheetData = getData()
if (bottomSheetData.isNotEmpty() && bottomSheetData.first().data != null) {
this.realmData = bottomSheetData.first().data
this.realmData = bottomSheetData.first().data as RealmResults<*>
}
}
@ -72,7 +72,7 @@ class BottomSheetListFragment : BottomSheetFragment(), LiveDataDelegate {
val viewManager = LinearLayoutManager(requireContext())
dataAdapter = LiveDataAdapter(this, R.layout.row_bottom_sheet_title)
gameNameRecyclerView.apply {
reyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = dataAdapter

@ -28,7 +28,7 @@ class BottomSheetSumFragment : BottomSheetFragment() {
editText1.requestFocus()
}
override fun getValue(): Any {
override fun getValue(): Any? {
return value
}

@ -0,0 +1,82 @@
package net.pokeranalytics.android.ui.fragment.components.bottomsheet
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import androidx.recyclerview.widget.GridLayoutManager
import kotlinx.android.synthetic.main.bottom_sheet_grid.*
import kotlinx.android.synthetic.main.fragment_bottom_sheet.view.*
import net.pokeranalytics.android.ui.adapter.TableSizeGridAdapter
import net.pokeranalytics.android.ui.view.GridSpacingItemDecoration
import net.pokeranalytics.android.util.px
class BottomSheetTableSizeGridFragment : BottomSheetFragment() {
private var dataList: ArrayList<String> = ArrayList()
private lateinit var dataAdapter: TableSizeGridAdapter
private var defaultSize: Int? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initData()
initUI()
}
override fun onResume() {
super.onResume()
dataAdapter.notifyDataSetChanged()
}
override fun getValue(): Any? {
return defaultSize
}
/**
* Init data
*/
private fun initData() {
val bottomSheetData = getData()
if (bottomSheetData.isNotEmpty() && bottomSheetData.first().defaultValue != null) {
defaultSize = bottomSheetData.first().defaultValue as Int?
}
dataList.add(getString(net.pokeranalytics.android.R.string.heads_up))
for (i in 3..10) {
dataList.add("$i-max")
}
}
/**
* Init UI
*/
private fun initUI() {
setAddButtonVisible(false)
LayoutInflater.from(requireContext())
.inflate(net.pokeranalytics.android.R.layout.bottom_sheet_grid, view?.bottomSheetContainer, true)
val viewManager = GridLayoutManager(requireContext(), 3)
dataAdapter = TableSizeGridAdapter(dataList)
dataAdapter.onClickOnItem = { position ->
bottomSheetDelegate.setValue(position + 2, row)
dismiss()
}
val spanCount = 3
val spacing = 2.px
val includeEdge = false
reyclerView.apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = dataAdapter
addItemDecoration(GridSpacingItemDecoration(spanCount, spacing, includeEdge))
}
}
}

@ -0,0 +1,34 @@
package net.pokeranalytics.android.ui.view
import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.RecyclerView
/**
* Manage spacing for recycler view & grid layout manager
*/
class GridSpacingItemDecoration(val spanCount: Int, val spacing: Int, val includeEdge: Boolean) :
RecyclerView.ItemDecoration() {
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
val position = parent.getChildAdapterPosition(view) // item position
val column = position % spanCount // item column
if (includeEdge) {
outRect.left = spacing - column * spacing / spanCount // spacing - column * ((1f / spanCount) * spacing)
outRect.right = (column + 1) * spacing / spanCount // (column + 1) * ((1f / spanCount) * spacing)
if (position < spanCount) { // top edge
outRect.top = spacing
}
outRect.bottom = spacing // item bottom
} else {
outRect.left = column * spacing / spanCount // column * ((1f / spanCount) * spacing)
outRect.right =
spacing - (column + 1) * spacing / spanCount // spacing - (column + 1) * ((1f / spanCount) * spacing)
if (position >= spanCount) {
outRect.top = spacing // item top
}
}
}
}

@ -1,5 +1,6 @@
package net.pokeranalytics.android.util
import android.content.res.Resources
import android.widget.Toast
import net.pokeranalytics.android.ui.activity.components.PokerAnalyticsActivity
import net.pokeranalytics.android.ui.fragment.components.PokerAnalyticsFragment
@ -8,6 +9,16 @@ import java.text.DecimalFormat
import java.text.SimpleDateFormat
import java.util.*
// Sizes
val Int.dp: Int
get() = (this / Resources.getSystem().displayMetrics.density).toInt()
val Int.px: Int
get() = (this * Resources.getSystem().displayMetrics.density).toInt()
val Float.dp: Float
get() = (this / Resources.getSystem().displayMetrics.density)
val Float.px: Float
get() = (this * Resources.getSystem().displayMetrics.density)
// Double

@ -5,13 +5,13 @@
android:orientation="horizontal">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/gameTypeRecyclerView"
android:id="@+id/reyclerView1"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:minHeight="200dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/gameNameRecyclerView"
android:id="@+id/reyclerView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="200dp" />

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/reyclerView"
android:layout_width="match_parent"
android:layout_height="200dp" />
</FrameLayout>

@ -4,7 +4,7 @@
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/gameNameRecyclerView"
android:id="@+id/reyclerView"
android:layout_width="match_parent"
android:layout_height="200dp" />

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="64dp"
android:background="@color/kaki_light"
android:foreground="?selectableItemBackground"
android:padding="8dp">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="0dp"
android:ellipsize="end"
android:gravity="center"
android:lines="1"
android:maxLines="1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Data Type Title" />
</androidx.constraintlayout.widget.ConstraintLayout>
Loading…
Cancel
Save