Function to animate an ImageView in a RecyclerView - android

To forward my application, i need a function that will rotate an imageView in a recyclerView.
The recyclerView is one of 3 recyclerviews that are already working well, and are clickable through a cardView.
shortvideo there:
https://mega.nz/#!W6AyAYaY!07WG8kr_POYiGsgt0yja6fk8RaclZLw2-MiMFrmEQmk
I created Classes with a few members, which permit to know the state of the objects.
I am newbie in Android programmation, and it was difficult for me to make these recyclerView working well :-)
7 April : i finally succeeded to implement my function
but the result is weird !
can see there :
https://mega.nz/#!DzI2iaiB!VBG9Ex4TZlAsoUYPSRhXXMP4weH-9hXyjbqF1nCRyeA
There is an imageView which is rotating, but this is the left one, not the clicked one, and there is a mix, a swap between pictures.
My question is : are the imageViews clickable and focusable like cardViews ?
if so i can try to make the imageView focusable and clickable (actually the cardView is... )
What about the index is recyclerViews ? isn't it the cardview which is clicked which has the index ? or the left one in the screen ?
I am puzzled :-)
Following: the layout with CardView and imageView; MainActivity where i tried to write the function; and the Adapter for the Top RecyclerView where the function is supposed to
rotate (180 °) the imageView at the index ( index, tag and position )
no change about that xml file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:id="#+id/flag_card_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:focusable="true"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground">
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="#+id/flagcountry"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintDimensionRatio="W,55:100"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginLeft="2dp"/>
<TextView
android:id="#+id/flagname"
android:layout_width="6dp"
android:layout_height="match_parent"
app:layout_constraintLeft_toRightOf="#id/flagcountry"
android:layout_centerVertical="true"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
under new kt file
package training.geography.triplerecyclerview
import android.provider.Settings.Global.getString
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.cardview.widget.CardView
import androidx.recyclerview.widget.RecyclerView
class FlagAdapter(val flagcountrylist: List<FlagCard>,
val flagitemClickListener : View.OnClickListener
//val flagitemOnLongClickListener : View.OnLongClickListener
):
RecyclerView.Adapter<FlagAdapter.FlagViewHolder> () {
class FlagViewHolder(flagView: View) : RecyclerView.ViewHolder(flagView) {
val flagcardView = flagView.findViewById<CardView>(R.id.flag_card_view)
val flagcountry = flagView.findViewById<ImageView>(R.id.flagcountry)
val flagname = flagView.findViewById<TextView>(R.id.flagname)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):
FlagViewHolder {
val inflater = LayoutInflater.from(parent.context)
val viewItem = inflater.inflate(R.layout.item_flag, parent, false)
return FlagViewHolder(viewItem)
}
override fun onBindViewHolder(flagholder: FlagViewHolder, position: Int) {
//val flagcountry: String = flagcountrylist.FlagCard.flagimage[position]
//var flagimageList: List<String> = flagcountrylist.map { it.flagimage }
var flagsouthList: List<String> = flagcountrylist.map { it.flagsouth }
var iflagsouth = flagsouthList[position]
flagholder.flagname.text = iflagsouth
flagholder.flagcardView.tag = position
flagholder.flagcardView.setOnClickListener(flagitemClickListener)
//flagholder.flagcardView.setOnLongClickListener(itemOnLongClickListener)
when (position){
0 -> flagholder.flagcountry.setImageResource(R.drawable.afgcol)
1 -> flagholder.flagcountry.setImageResource(R.drawable.argsvk)
2 -> flagholder.flagcountry.setImageResource(R.drawable.armche)
3 -> flagholder.flagcountry.setImageResource(R.drawable.auttgo)
4 -> flagholder.flagcountry.setImageResource(R.drawable.azepry)
5 -> flagholder.flagcountry.setImageResource(R.drawable.bhrtur)
6 -> flagholder.flagcountry.setImageResource(R.drawable.bratls)
7 -> flagholder.flagcountry.setImageResource(R.drawable.bwasur)
8 -> flagholder.flagcountry.setImageResource(R.drawable.cafbtn)
9 -> flagholder.flagcountry.setImageResource(R.drawable.critun)
10 -> flagholder.flagcountry.setImageResource(R.drawable.pandza)
11 -> flagholder.flagcountry.setImageResource(R.drawable.persau)
12 -> flagholder.flagcountry.setImageResource(R.drawable.svnago)
13 -> flagholder.flagcountry.setImageResource(R.drawable.sweben)
14 -> flagholder.flagcountry.setImageResource(R.drawable.tcdgbr)
15 -> flagholder.flagcountry.setImageResource(R.drawable.thabol)
16 -> flagholder.flagcountry.setImageResource(R.drawable.tjkdeu)
17 -> flagholder.flagcountry.setImageResource(R.drawable.tkmbel)
18 -> flagholder.flagcountry.setImageResource(R.drawable.tzablz)
19 -> flagholder.flagcountry.setImageResource(R.drawable.ukrcmr)
20 -> flagholder.flagcountry.setImageResource(R.drawable.uryblr)
21 -> flagholder.flagcountry.setImageResource(R.drawable.venbgd)
22 -> flagholder.flagcountry.setImageResource(R.drawable.vnmbfa)
23 -> flagholder.flagcountry.setImageResource(R.drawable.yembih)
24 -> flagholder.flagcountry.setImageResource(R.drawable.zmbchl)
25 -> flagholder.flagcountry.setImageResource(R.drawable.zwealb)
}
//var iflagcard:String = imagelist[position]
//holder.flagcountry.setImageResource(iflagcard)
}
override fun getItemCount(): Int {
return flagcountrylist.size
}
}
---------------------------------------
//under new MainActivity file with function modified
// i don't know what to do with the variable
// flagtempup, i use it to set the string in
// iflagtrigramdown, and i have te warning variable not used...
package training.geography.triplerecyclerview
import android.nfc.Tag
import android.os.Bundle
import android.view.View
import android.view.View.OnClickListener
import android.view.animation.Animation
import android.view.animation.RotateAnimation
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.cardview.widget.CardView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.item_flag.*
data class FlagCard(var flagtrigramup: String, var flagtrigramdown: String,
var flagimage: String, var flagsouth: String, var rotationpossible: Boolean=(true))
data class CountryCard(val countrytrigram: String, val description: String)
data class MapCard(var map_left_up: String,
var map_right_up: String,
var map_left_down: String,
var map_right_down: String,
var maps_img: String,
var mapnorth: String)
class MainActivity : AppCompatActivity(), OnClickListener {
var afg_col = FlagCard("col", "afg", "afgcol", "afg", true)
var arg_svk = FlagCard("arg", "svk", "argsvk", "svk", true)
var arm_che = FlagCard("che", "arm", "armche", "arm", true)
var aut_tgo = FlagCard("tgo", "aut", "auttgo", "aut", true)
var aze_pry = FlagCard("aze", "pry", "azepry", "pry", true)
var bhr_tur = FlagCard("tur", "bhr", "bhrtur", "bhr", true)
var bra_tls = FlagCard("tls", "bra", "bratls", "bra", true)
var bwa_sur = FlagCard("sur", "bwa", "bwasur", "bwa", true)
var caf_btn = FlagCard("btn", "caf", "cafbtn", "caf", true)
var cri_tun = FlagCard("cri", "tun", "critun", "tun", true)
var pan_dza = FlagCard("pan", "dza", "pandza", "dza", true)
var per_sau = FlagCard("per", "sau", "persau", "sau", true)
var svn_ago = FlagCard("svn", "ago", "svnago", "ago", true)
var swe_ben = FlagCard("swe", "ben", "sweben", "ben", true)
var tcd_gbr = FlagCard("tcd", "gbr", "tcdgbr", "gbr", true)
var tha_bol = FlagCard("tha", "bol", "thabol", "bol", true)
var tjk_deu = FlagCard("tjk", "deu", "tjkdeu", "deu", true)
var tkm_bel = FlagCard("tkm", "bel", "tkmbel", "bel", true)
var tza_blz = FlagCard("tza", "blz", "tzablz", "blz", true)
var ukr_cmr = FlagCard("ukr", "cmr", "ukrcmr", "cmr", true)
var ury_blr = FlagCard("ury", "blr", "uryblr", "blr", true)
var ven_bgd = FlagCard("ven", "bgd", "venbgd", "bgd", true)
var vnm_bfa = FlagCard("vnm", "bfa", "vnmbfa", "bfa", true)
var yem_bih = FlagCard("yem", "bih", "yembih", "bih", true)
var zmb_chl = FlagCard("zmb", "chl", "zmbchl", "chl", true)
var zwe_alb = FlagCard("zwe", "alb", "zwealb", "alb", true)
var afg = CountryCard("afg", "afg")
var ago = CountryCard("ago", "ago")
var alb = CountryCard("alb", "alb")
var arg = CountryCard("arg", "arg")
var arm = CountryCard("arm", "arm")
var aut = CountryCard("aut", "aut")
var aze = CountryCard("aze", "aze")
var bel = CountryCard("bel", "bel")
var bfa = CountryCard("bfa", "bfa")
var bhr = CountryCard("bhr", "bhr")
var bih = CountryCard("bih", "bih")
var blz = CountryCard("blz", "blz")
var bol = CountryCard("bol", "bol")
var bra = CountryCard("bra", "bra")
var btn = CountryCard("btn", "btn")
var bwa = CountryCard("bwa", "bwa")
var caf = CountryCard("caf", "caf")
var che = CountryCard("che", "che")
var chl = CountryCard("chl", "chl")
var cmr = CountryCard("cmr", "cmr")
var col = CountryCard("col", "col")
var cri = CountryCard("cri", "cri")
var deu = CountryCard("deu", "deu")
var gbr = CountryCard("gbr", "gbr")
var pan = CountryCard("pan", "pan")
var per = CountryCard("per", "per")
var pry = CountryCard("pry", "pry")
var sau = CountryCard("sau", "sau")
var sur = CountryCard("sur", "sur")
var svk = CountryCard("svk", "svk")
var svn = CountryCard("svn", "svn")
var swe = CountryCard("swe", "swe")
var tcd = CountryCard("tcd", "tcd")
var tgo = CountryCard("tgo", "tgo")
var tha = CountryCard("tha", "tha")
var tjk = CountryCard("tjk", "tjk")
var tkm = CountryCard("tkm", "tkm")
var tls = CountryCard("tls", "tls")
var tun = CountryCard("tun", "tun")
var tur = CountryCard("tur", "tur")
var tza = CountryCard("tza", "tza")
var ukr = CountryCard("ukr", "ukr")
var ury = CountryCard("ury", "ury")
var ven = CountryCard("ven", "ven")
var vnm = CountryCard("vnm", "vnm")
var yem = CountryCard("yem", "yem")
var zmb = CountryCard("zmb", "zmb")
var zwe = CountryCard("zwe", "zwe")
var arm_bol_gbr_ago = MapCard("arm", "bol", "gbr", "ago", "bol", "armbolgbrago")
var aze_bra_aut_ben = MapCard("aze", "bra", "aut", "ben", "bra", "azebraautben")
var bfa_blr_col_bgd = MapCard("bfa", "blr", "col", "bgd", "blr", "bfablrcolbgd")
var bwa_bel_bhr_chl = MapCard("bwa", "bel", "bhr", "chl", "bel", "bwabelbhrchl")
var caf_afg_alb_arg = MapCard("caf", "afg", "alb", "arg", "afg", "cafafgalbarg")
var che_tkm_tur_sur = MapCard("che", "tkm", "tur", "sur", "tkm", "chetkmtursur")
var cri_cmr_btn_bih = MapCard("cri", "cmr", "btn", "bih", "cmr", "cricmrbtnbih")
var sau_blz_deu_dza = MapCard("sau", "blz", "deu", "dza", "blz", "saublzdeudza")
var svn_tha_tcd_pry = MapCard("svn", "tha", "tcd", "pry", "tha", "svnthatcdpry")
var swe_tls_tgo_per = MapCard("swe", "tls", "tgo", "per", "tls", "swetlstgoper")
var tjk_pan_svk_tza = MapCard("tjk", "pan", "svk", "tza", "pan", "tjkpansvktza")
var ven_zwl_yem_ukr = MapCard("ven", "zwl", "yem", "ukr", "zwl", "venzwlyemukr")
var zmb_tur_ury_vnm = MapCard("zmb", "tur", "ury", "vnm", "tur", "zmbtururyvnm")
var flagcountrylist = listOf<FlagCard>(
afg_col,
arg_svk,
arm_che,
aut_tgo,
aze_pry,
bhr_tur,
bra_tls,
bwa_sur,
caf_btn,
cri_tun,
pan_dza,
per_sau,
svn_ago,
swe_ben,
tcd_gbr,
tha_bol,
tjk_deu,
tkm_bel,
tza_blz,
ukr_cmr,
ury_blr,
ven_bgd,
vnm_bfa,
yem_bih,
zmb_chl,
zwe_alb
)
val flagadapter = FlagAdapter(flagcountrylist, this)
var countryList = listOf<CountryCard>(
afg,
ago,
alb,
arg,
arm,
aut,
aze,
bel,
bfa,
bhr,
bih,
blz,
blz,
bol,
bra,
btn,
bwa,
caf,
che,
chl,
cmr,
col,
cri,
deu,
gbr,
pan,
per,
pry,
sau,
sur,
svk,
svn,
swe,
tcd,
tgo,
tha,
tjk,
tkm,
tls,
tun,
tur,
tza,
ukr,
ury,
ven,
vnm,
yem,
zmb,
zwe
)
val countryadapter = CountryAdapter(countryList)
var mapcountrylist = listOf<MapCard>(
arm_bol_gbr_ago,
aze_bra_aut_ben,
bfa_blr_col_bgd,
bwa_bel_bhr_chl,
caf_afg_alb_arg,
che_tkm_tur_sur,
cri_cmr_btn_bih,
sau_blz_deu_dza,
svn_tha_tcd_pry,
swe_tls_tgo_per,
tjk_pan_svk_tza,
ven_zwl_yem_ukr,
zmb_tur_ury_vnm
)
val mapadapter = MapAdapter(mapcountrylist)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val flagsrecyclerView = findViewById<RecyclerView>(R.id.flagsRecyclerView)
flagsrecyclerView.layoutManager = LinearLayoutManager(this, RecyclerView.HORIZONTAL, false)
flagsrecyclerView.adapter = flagadapter
val countryrecyclerView = findViewById<RecyclerView>(R.id.countriesRecyclerView)
countryrecyclerView.layoutManager = LinearLayoutManager(this, RecyclerView.HORIZONTAL, false)
countryrecyclerView.adapter = countryadapter
val maprecyclerView = findViewById<RecyclerView>(R.id.mapsRecyclerView)
maprecyclerView.layoutManager = LinearLayoutManager(this, RecyclerView.HORIZONTAL, false)
maprecyclerView.adapter = mapadapter
}
fun rotateFlagCard (flagCard: FlagCard, position: Int) : FlagCard {
var flagtrigramuplist: List<String> = flagcountrylist.map{it.flagtrigramup }
var iflagtrigramup : String = flagtrigramuplist[position]
var flagimagelist = flagcountrylist.map{it.flagimage}
var iflagimage = flagimagelist[position]
var flagsouthlist = flagcountrylist.map { it.flagsouth }
var iflagsouth = flagsouthlist[position]
var rotationpossiblelist : List<Boolean> = flagcountrylist.map{ it.rotationpossible }
var irotationpossible = rotationpossiblelist[position]
var iflagimageView = findViewById<ImageView>(R.id.flagcountry)
when (position) {
0 -> iflagimageView.setImageResource(R.drawable.afgcol)
1 -> iflagimageView.setImageResource(R.drawable.argsvk)
2 -> iflagimageView.setImageResource(R.drawable.armche)
3 -> iflagimageView.setImageResource(R.drawable.auttgo)
4 -> iflagimageView.setImageResource(R.drawable.azepry)
5 -> iflagimageView.setImageResource(R.drawable.bhrtur)
6 -> iflagimageView.setImageResource(R.drawable.bratls)
7 -> iflagimageView.setImageResource(R.drawable.bwasur)
8 -> iflagimageView.setImageResource(R.drawable.cafbtn)
9 -> iflagimageView.setImageResource(R.drawable.critun)
10 -> iflagimageView.setImageResource(R.drawable.pandza)
11 -> iflagimageView.setImageResource(R.drawable.persau)
12 -> iflagimageView.setImageResource(R.drawable.svnago)
13 -> iflagimageView.setImageResource(R.drawable.sweben)
14 -> iflagimageView.setImageResource(R.drawable.tcdgbr)
15 -> iflagimageView.setImageResource(R.drawable.thabol)
16 -> iflagimageView.setImageResource(R.drawable.tjkdeu)
17 -> iflagimageView.setImageResource(R.drawable.tkmbel)
18 -> iflagimageView.setImageResource(R.drawable.tzablz)
19 -> iflagimageView.setImageResource(R.drawable.ukrcmr)
20 -> iflagimageView.setImageResource(R.drawable.uryblr)
21 -> iflagimageView.setImageResource(R.drawable.venbgd)
22 -> iflagimageView.setImageResource(R.drawable.vnmbfa)
23 -> iflagimageView.setImageResource(R.drawable.yembih)
24 -> iflagimageView.setImageResource(R.drawable.zmbchl)
25 -> iflagimageView.setImageResource(R.drawable.zwealb)
else -> throw AssertionError()
}
if (irotationpossible)
{
iflagimageView.animate().apply {
rotationBy(180f)
duration = 1000L
start()
// permutation of values north south
var flagtrigramdownlist :List<String> = flagcountrylist.map{it.flagtrigramdown}
var iflagtrigramdown : String = flagtrigramdownlist[position]
var flagtempup: String = iflagtrigramup
var flagtempdown: String = iflagtrigramdown
iflagtrigramup = iflagsouth
//flagtempdown = flagtempup
iflagtrigramdown = flagtempup
var iflagCard = FlagCard( iflagtrigramup, iflagtrigramdown, iflagimage, iflagsouth, irotationpossible )
return iflagCard
}
} else {
return flagCard
//Toast.makeText(this, "flag already matched country", Toast.LENGTH_LONG).show()
}
}
override fun onClick(flagcardView: View) {
if (flagcardView.tag != null) {
val index = flagcardView.tag as Int
var flagsouthList: List<String> = flagcountrylist.map{it.flagsouth }
val flags = flagsouthList[index]
Toast.makeText(this, "country : ${flags}", Toast.LENGTH_LONG).show()
var flagcard:FlagCard = flagcountrylist[index]
rotateFlagCard (flagcard, index)
}
}
}

It looks like nobody is interested by what is possible to do with RecyclerViews...
I still have the problem that when an imageView is clicked, this is the one at left which is rotating ! i can't understand what happens, examination in debugger shows the variables are ok, the index is position and do not change...
I tried to apply rotate function to the cardView, same result !
I modified the code in the function and replace the flagCard by iflagCard if rotation was done (because two flags, one up, one down, and of course the FlagCard is different... )
Here the new code :
if (irotationpossible)
{
iflagcardView.animate().apply {
rotationBy(180f)
duration = 1000L
start()
// permutation of values north south
var flagtrigramdownlist :List<String> = flagcountrylist.map{it.flagtrigramdown}
var iflagtrigramdown : String = flagtrigramdownlist[position]
var flagtempup: String = iflagtrigramup
var flagtempdown: String = iflagtrigramdown
iflagtrigramup = iflagsouth
iflagsouth = flagtempup
iflagtrigramdown = flagtempup
var iflagCard = FlagCard( iflagtrigramup, iflagtrigramdown, iflagimage, iflagsouth, irotationpossible )
//flagcountrylist.toSet(position, iflagCard)
//abstract operator fun set(position: Int, iflagCard: FlagCard): FlagCard
flagcountrylist.removeAt(position)
flagcountrylist.add(position, iflagCard)
return iflagCard
}
} else {
return flagCard
//Toast.makeText(this, "flag already matched country", Toast.LENGTH_LONG).show()
}
my question is now about the set function for mutableListOf in Kotlin :
i tried to use " abstract operator fun set(index: Int, element: E): E "
but couldn't build because of abstract !
Is there any other way than my solution to remove then add at the same index ?
Is there any experimented developper curious about the strange rotation in that app ?
https://www.youtube.com/watch?v=d9o7fttLBxk
Why not the image with right index ?

Related

How to add data to Array list that is linked to a recycler view [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 11 months ago.
Improve this question
Good day. So I am trying to add data to my tables by an action. I currently have it is static and would like to know the best way to insert data. My end goal is for a driver to be selected and based on the driver name that was selected it will pull that drivers deliveries for the day. I have seen post about fragments but don't know if that will be relevant to me.
MainActivity
package com.dispatch.tripsheet
import android.os.Bundle
import android.view.View
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private var dbHandler: DBHandler? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recyclerViewTripsheetlist.layoutManager = LinearLayoutManager(this)
recyclerViewTripsheetlist.adapter = TableViewAdapter(Tripsheetlist)
//This is for the drivers. Drivers still need to be pulled from the database
val list : MutableList<String> = ArrayList()
list.add("Deon")
list.add("Leon")
list.add("David")
list.add("Dick")
list.add("Jim")
list.add("Harry")
val adapter = ArrayAdapter( this, androidx.appcompat.R.layout.support_simple_spinner_dropdown_item, list)
val spinner: Spinner = findViewById(R.id.spnDriver)
spinner.adapter = adapter
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{
override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
val item :String = list[p2]
Toast.makeText(this#MainActivity, "Driver $item selected", Toast.LENGTH_SHORT).show()
}
override fun onNothingSelected(p0: AdapterView<*>?) {
//empty
}
//insert code that activates data pull of tripsheet for driver= actifavte by method the class/object that activates the data pull. so datapuul(Driver)
}
limitDropDownHeight(spinner)
//drivers end
val btnLoadData: Button = findViewById(R.id.btnLoadData)
weightsum(tvTotalweight, Tripsheetlist)
totaldelNotes(tvTotaldelv,Tripsheetlist)
setData(btnLoadData,Tripsheetlist)
}
val Tripsheetlist = ArrayList<DataModel>().apply {
add(DataModel(190617, 182832, "", 0,"", "",""))
// Need one row for dummy data. Gets removed so chance wont be seen.
add(DataModel(190617, 182832, "Jcorp", 100,"Delivery done", "Delivery not done",""))
add(DataModel(190617, 182833, "Honda", 100,"No exceptions", "Exceptions",""))
add(DataModel(190617, 182832, "Everflu", 100,"100%", "50%",""))
add(DataModel(190617, 182832, "Panado", 300,"OK", "NO",""))
add(DataModel(190617, 182832, "Gheiters", 100,"Success", "Failed",""))
add(DataModel(190617, 182832, "John", 300,"Yes", "No",""))
// need to change from hardcoded text to input
//these values will change from sql input
var a = 10000
var b = 10000
var c = "Absa"
var d = 50
var e = "No exceptions"
var f = "Exceptions"
var g = ""
// value to changes based on data size.
var x: Int = 29
for (i in 20..x)
{
add(DataModel(a,b,c,d,e,f,g))
a++
}
// })
}
//setData is not 100% ready
private fun setData(btnLoadData: Button, Tripsheetlist: ArrayList<DataModel>) {
btnLoadData.setOnClickListener(View.OnClickListener {
var x: Int = 2
for (i in 3..6)
{ //does not work
this.Tripsheetlist[x].WOrder = 20022
this.Tripsheetlist[x].DElNote = 20022
this.Tripsheetlist[x].Company = "FNB"
this.Tripsheetlist[x].Weight = 20
this.Tripsheetlist[x].Button1 = "No exceptions"
this.Tripsheetlist[x].Button2 = "Exceptions"
this.Tripsheetlist[x].tvdone = ""
x++
}
btnLoadData.setBackgroundColor(getColor(R.color.green))
}
})
}
//works
fun weightsum(args: TextView, Tripsheetlist: ArrayList<DataModel>) {
var totweight: Int = 0
var sum: Int = 0
for (i in 0 until Tripsheetlist.size -1) {
sum += Tripsheetlist[i].Weight
}
totweight = sum
tvTotalweight.setText("Total Weight: " + totweight + "kg")
}
//works
fun totaldelNotes(tvTotaldelv: TextView?, Tripsheetlist: ArrayList<DataModel>) {
var totnotes: Int = 1
var sum: Int = 0
// var input: String
totnotes = Tripsheetlist.size -1
tvTotaldelv?.setText("Total Delivery Notes: " +totnotes)
}
//works
fun limitDropDownHeight(spinner: Spinner){
val popup = Spinner::class.java.getDeclaredField( "mPopup")
popup.isAccessible = true
val popupWindow = popup.get(spinner)as ListPopupWindow
popupWindow.height = (200 * resources.displayMetrics.density).toInt()
}
}
TableViewAdapter
package com.dispatch.tripsheet
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.table_list_item.view.*
class TableViewAdapter( var Tripsheetlist: List<DataModel> = emptyList()) : RecyclerView.Adapter<TableViewAdapter.RowViewHolder>() {
// var dataItems: List<DataModel> = emptyList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RowViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.table_list_item, parent, false)
return RowViewHolder(itemView)
}
override fun getItemCount(): Int { return Tripsheetlist.size// + 1 // one more to add header row
}
private fun updateData(data: List<DataModel>) {
Tripsheetlist = data
notifyDataSetChanged()
}
override fun onBindViewHolder(holder: RowViewHolder, position: Int) {
val rowPos = holder.adapterPosition
val dataItem = Tripsheetlist[position]
if (rowPos == 0) {
// Header Cells. Main Headings appear here
holder.itemView.apply {
setHeaderBg(txtWOrder)
setHeaderBg(txtDElNote)
setHeaderBg(txtCompany)
// setHeaderBg(txtAddress)
setHeaderBg(txtWeight)
setHeaderBg(txtbutton1)
setHeaderBg(txtbutton2)
setHeaderBg(txttvdone)
txtWOrder.text = "WOrder"
txtDElNote.text = "DElNote"
txtCompany.text = "Company"
// txtAddress.text = "Address"
txtWeight.text = "Weight"
txtbutton1.text = "Delivered"
txtbutton2.text = "Exception"
txttvdone.text = ""
}
} else {
val modal = Tripsheetlist[rowPos ]
holder.itemView.apply {
setContentBg(txtWOrder)
setContentBg(txtDElNote)
setContentBg(txtCompany)
// setContentBg(txtAddress)
setContentBg(txtWeight)
setContentBg(txtbutton1)
setContentBg(txtbutton2)
setContentBg(txttvdone)
txtWOrder.text = modal.WOrder.toString()
txtDElNote.text = modal.DElNote.toString()
txtCompany.text = modal.Company.toString()
// txtAddress.text = modal.Address.toString()
txtWeight.text = modal.Weight.toString()
txtbutton1.text = modal.Button1.toString()
txtbutton2.text = modal.Button2.toString()
txttvdone.text = modal.tvdone.toString()
}
}
holder.txttvdone.apply {
setBackgroundResource(when (dataItem.state) {
DataState.Unselected -> android.R.color.transparent
DataState.Success -> R.color.green
DataState.Failure -> R.color.orange
})
text = when (dataItem.state) {
DataState.Unselected -> ""
DataState.Success -> "✓"
DataState.Failure -> "x"
//this is where I add code to export data through api maybe add it in the datastate set where it is success and Failure
}
}
holder.apply {
txtbutton1.setOnClickListener {
Log.e("Clicked", "Successful delivery")
//this is where I add code to export data through api
dataItem.state = DataState.Success
notifyDataSetChanged()
}
txtbutton2.setOnClickListener {
Log.e("Clicked", "Exception on delivery")
dataItem.state = DataState.Failure
notifyDataSetChanged()
}
}
}
class RowViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
val txttvdone:TextView = itemView.findViewById<TextView>(R.id.txttvdone)
val txtbutton1:Button = itemView.findViewById<Button>(R.id.txtbutton1)
val txtbutton2:Button = itemView.findViewById<Button>(R.id.txtbutton2)
}
class MyViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
var txtbutton1 = view.findViewById<Button>(R.id.txtbutton1)
val txtbutton2:Button = itemView.findViewById<Button>(R.id.txtbutton2)
var txttvdone = view.findViewById<TextView>(R.id.txttvdone)
}
private fun setHeaderBg(view: View) {
view.setBackgroundResource(R.drawable.table_header_cell_bg)
}
private fun setContentBg(view: View) {
view.setBackgroundResource(R.drawable.table_content_cell_bg)
}
}
I have created something with a button just to test it out. But what happens is. The data only changes after clicking the load data button and then a button on my recycler view, which is not ideal.
btnLoadData.setOnClickListener(View.OnClickListener {
var x: Int = 2
for (i in 3..6)
{ //does not work
this.Tripsheetlist[x].WOrder = 20022
this.Tripsheetlist[x].DElNote = 20022
this.Tripsheetlist[x].Company = "FNB"
this.Tripsheetlist[x].Weight = 20
this.Tripsheetlist[x].Button1 = "No exceptions"
this.Tripsheetlist[x].Button2 = "Exceptions"
this.Tripsheetlist[x].tvdone = ""
x++
}
Any and all help is appreciated. Let me know if any additional information is needed.
For my layouts. I have a activity main with my recycler view and then a table list item for my rows. Below is how my app looks.
There are two ways to approach this,
add a setData method to RV , so your part of code looks like
class TableViewAdapter(){
private var data : List<DataModel> = emptyList()
fun setData( newData : List<..>){
data = newData
notifyDataSetChanged() // and handle other events to update
}
}
then you can update data on go
use DiffUtil supported RV like ListAdapter or implement it yourself

Randomize question on Android Studio - Kotlin

I made a simple quiz on Android Studio which contains 8 questions. How to make the questions become random without duplicated. This app does not use a database. I'm new to programming so I don't know what to do about this
Here's the code Kuis Activity
private lateinit var kuis: TextView
private lateinit var rg: RadioGroup
private lateinit var choiceA: RadioButton
private lateinit var choiceB: RadioButton
private lateinit var choiceC: RadioButton
private lateinit var choiceD: RadioButton
private var number = 0
val question: Array<String> = arrayOf(
"Mandau merupakan senjata tradisional yang berasal dari suku...",
"Pakaian tradisional suku Madura bernama...",
"Suku yang teridentifikasi memiliki 13 kerajaan adalah...",
"Cheongsam merupakan pakaian tradisional dari...",
"Lagu Jubata merupakan lagu yang berasal dari suku Dayak yang memiliki arti...",
"Berikut ini merupakan kuliner khas Kalimantan Barat kecuali...",
"'Takadang jantu barang dah latih'. Penggalan lirik tersebut berasal dari lagu...",
"Rumah Adat Saoraja merupakan rumah adat yang berasal dari suku..."
)
val option = arrayOf(
"Jawa", "Dayak", "Melayu", "Bugis",
"Batik", "Teluk Belanga", "King Baba", "Pesa'an",
"Jawa", "Dayak", "Melayu", "Madura",
"Tionghoa", "Dayak", "Melayu", "Bugis",
"Tanah", "Tuhan", "Sungai", "Keselamatan",
"Kwetiau", "Pengkang", "Rendang", "Chai Kwe",
"Tanah Parenean", "Jubata", "Cik Cik Periuk", "Sungai Kapuas",
"Dayak", "Tionghoa", "Melayu", "Bugis"
)
val answer = arrayOf(
"Dayak",
"Pesa'an",
"Melayu",
"Tionghoa",
"Tuhan",
"Rendang",
"Jubata",
"Bugis"
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_kuis)
supportActionBar?.title = "Kuis"
kuis = findViewById(R.id.kuis)
rg = findViewById(R.id.pilihan)
choiceA = findViewById(R.id.pilihanA)
choiceB = findViewById(R.id.pilihanB)
choiceC = findViewById(R.id.pilihanC)
ChoiceD = findViewById(R.id.pilihanD)
kuis.setText(question[number])
choiceA.setText(option[0])
choiceB.setText(option[1])
choiceC.setText(option[2])
choiceD.setText(option[3])
rg.check(0)
correct = 0
wrong = 0
}
fun next(view: View) {
if (choiceA.isChecked || choiceB.isChecked || choiceC.isChecked || choiceD.isChecked) {
val userAnswer: RadioButton = findViewById(rg.checkedRadioButtonId)
val takeUserAnswer: String = userAnswer.text.toString()
rg.check(0)
if (takeUserAnswer.equals(answer[number])) correct++
else wrong++
number++
if (number< 8) {
kuis.setText(question[number])
choiceA.setText(option[(number * 4) + 0])
choiceB.setText(option[(number * 4) + 1])
choiceC.setText(option[(number * 4) + 2])
choiceD.setText(option[(number * 4) + 3])
} else {
result = correct * 100 / 8
val intent = Intent(this, HasilKuis::class.java)
startActivity(intent)
}
} else {
Toast.makeText(this, "Belum Dijawab", Toast.LENGTH_SHORT).show()
}
Inefficient way would be something like this:
val soal = mutableListOf<String>(...)
val indices = mutableSetOf<Int>()
do {
val randomIndex = Random.nextInt(soal.size)
if (randomIndex !in indices) {
// Update views with their respective data using the randomIndex, e.g. soal[randomIndex]
indices.add(randomIndex)
}
} while (indices.size < 8)
The efficient way would be to make your arrays MutableList<String> and modify their size along the way:
val soal = mutableListOf<String>(...)
var upperBound = soal.lastIndex
do {
val randomIndex = if (upperBound != 0) Random.nextInt(upperBound) else 0
// Update views with their respective data using the randomIndex, e.g. soal.removeAt(randomIndex)
upperBound--
} while (soal.isNotEmpty())

Android with Kotlin recyclerView with checkboxes randomly checked after delete list item

apologies for my limited knowledge of programming and any sloppiness. I have a reyclerview with alarm objects that I can add and it creates them. When I add say 4 alarms, and delete three of them. The last alarms checkbox is checked by itself. I can not in anyway use the checkbox.setChecked() method for some reason. android studio is not recognizing it, if anyone could please let me know why that is. Also if you know of a solution to the auto check on the last alarm object please.
package com.example.alarmclock
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.Checkable
import android.widget.EditText
import android.widget.TextView
import androidx.core.widget.doAfterTextChanged
import androidx.core.widget.doBeforeTextChanged
import androidx.recyclerview.widget.RecyclerView
import java.security.Key
class AlarmAdapter (private val alarmList: MutableList<Alarm>) : RecyclerView.Adapter<AlarmAdapter.ViewHolder>() {
//start viewholder
inner class ViewHolder(alarm: View) : RecyclerView.ViewHolder(alarm) {
val alarmLabel = itemView.findViewById<EditText>(R.id.alarmLabel)
val editTextTime = itemView.findViewById<EditText>(R.id.editTextTime)
val textView1 = itemView.findViewById<TextView>(R.id.textView1)
val deleteCheckBox = itemView.findViewById<Button>(R.id.deleteAlarmCheckBox)
//val deleteButton = itemView.findViewById<Button>(R.id.deleteAlarmButton)
//val addButton = itemView.findViewById<Button>(R.id.addAlarmButton)
val mondayCheckBox = itemView.findViewById<Button>(R.id.mondayCheckBox)
val tuesdayCheckBox = itemView.findViewById<Button>(R.id.tuesdayCheckBox)
val wednesdayCheckBox = itemView.findViewById<Button>(R.id.wednesdayCheckBox)
val thursdayCheckBox = itemView.findViewById<Button>(R.id.thursdayCheckBox)
val fridayCheckBox = itemView.findViewById<Button>(R.id.fridayCheckBox)
val saturdayCheckBox = itemView.findViewById<Button>(R.id.saturdayCheckBox)
val sundayCheckBox = itemView.findViewById<Button>(R.id.sundayCheckBox)
val amCheckBox = itemView.findViewById<Button>(R.id.amCheckBox)
val pmCheckBox = itemView.findViewById<Button>(R.id.pmCheckBox)
}//end viewholder
fun addAlarm (alarm: Alarm) {
alarmList.add(alarm)
notifyItemInserted(alarmList.size - 1)
}
fun returnAlarmList (): MutableList<Alarm> {
return alarmList
}
fun removeAlarms() {
alarmList.removeAll {
alarm -> alarm.deleteCheck == true
}
//notifyDataSetChanged()
}
fun deleteAlarm (deletedAlarmList: List<Int> ) {
val deletedListIterator = deletedAlarmList.iterator()
val alarmListIterator = alarmList.iterator()
while (deletedListIterator.hasNext()){
while (alarmListIterator.hasNext()){
if (deletedListIterator.next() == alarmListIterator.next().alarmId){
alarmList.remove(alarmListIterator.next())
}
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val context = parent.context
val inflater = LayoutInflater.from(context)
val alarmView = inflater.inflate(R.layout.alarms, parent, false)
return ViewHolder(alarmView)
}
override fun getItemCount(): Int {
return alarmList.size
}
override fun onBindViewHolder(holder: AlarmAdapter.ViewHolder, position: Int) {
val alarm: Alarm = alarmList[position]
val alarmLabel = holder.alarmLabel
var textView1 = holder.textView1
var editTextTime = holder.editTextTime
var mondayCheckBox = holder.mondayCheckBox
var tuesdayCheckBox = holder.tuesdayCheckBox
var wednesdayCheckBox = holder.wednesdayCheckBox
var thursdayCheckBox = holder.thursdayCheckBox
var fridayCheckBox = holder.fridayCheckBox
var saturdayCheckBox = holder.saturdayCheckBox
var sundayCheckBox = holder.sundayCheckBox
var amCheckBox = holder.amCheckBox
var pmCheckBox = holder.pmCheckBox
var deleteAlarmCheckBox = holder.deleteCheckBox
var lastCharacter = ""
var secondLastCharacter = ""
deleteAlarmCheckBox.setOnClickListener {
alarm.deleteCheck = !alarm.deleteCheck
}
alarmLabel.doAfterTextChanged {
alarm.alarmLabel = alarmLabel.text.toString()
textView1.text = alarm.alarmLabel
}
editTextTime.doAfterTextChanged {
//lastCharacter = editTextTime.text.get(editTextTime.text.length-1).toString()
textView1.text = lastCharacter
if (editTextTime.text.length == 2 && secondLastCharacter != ":"){
//if (lastCharacter != ":") {
editTextTime.setText(editTextTime.text.toString().plus(":"))
editTextTime.setSelection(editTextTime.text.length)
//}
}
editTextTime.doBeforeTextChanged { _, _, _, _ ->
if (editTextTime.length() != 0) {
secondLastCharacter = editTextTime.text.get(editTextTime.text.length - 1).toString()
}
}
if (editTextTime.text.length == 5 ){
alarm.hour = editTextTime.text.get(0).toString().plus(editTextTime.text.get(1).toString())
if (alarm.hour.toInt() < 10) alarm.hour = "0".plus(alarm.hour)
///////
var inputedTimeList = editTextTime.text.toList()
val timeIterator = inputedTimeList.iterator()
}
}
mondayCheckBox.setOnClickListener {
alarm.monday = !alarm.monday
textView1.text = alarm.monday.toString()
}
tuesdayCheckBox.setOnClickListener {
alarm.tuesday = !alarm.tuesday
}
wednesdayCheckBox.setOnClickListener {
alarm.wednesday = !alarm.wednesday
}
thursdayCheckBox.setOnClickListener {
alarm.thursday = !alarm.thursday
}
fridayCheckBox.setOnClickListener {
alarm.friday = !alarm.friday
}
saturdayCheckBox.setOnClickListener {
alarm.saturday = !alarm.saturday
}
sundayCheckBox.setOnClickListener {
alarm.sunday = !alarm.sunday
}
amCheckBox.setOnClickListener {
alarm.amPm = !alarm.amPm
}
}
}
The answer is quite simple, RecyclerView items are reused, so be sure that you set the all the values onBindViewHolder, because after your item is deleted, the actual view is not, so previously set values might be preset although they are not correct according to your data.
The easiest way would be to have isChecked Boolean value store in the Alarm object, onBindViewHolder always set the isChecked param on the Checkbox according to the value returned from the Alarm and when you change the isChecked inside the Checkbox listener - make sure you also update the value inside the Alarm object.
Another solution would be calling notifyDatasetChanged() on the RecyclerView, but it's definitely not the best solution especially if you have dynamic row deletion (and possibly a neat animation).
P.S. consider using viewBinding in your project, it will save you time writing all that ugly findViewById code :)))

Android Animated Carousel TextView within RecyclerView width wider than screen text gets clipped off. Even when animated into view

I am building a stock ticker type carousel that has market prices running along the screen as shown. The 'CRC' Ticker has only the partial view showing, it clips off at the edge of the parent which is the width of the device even when it is animated into view. I want it to have a width large enough hold all the children that goes past the device width.
Here if the Carousel layout xml:
<?xml version="1.0" encoding="utf-8"?>
<com.android.forexwatch.views.timepanel.CarouselView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/carouselLinear"
android:layout_width="match_parent"
android:layout_height="30dp"
android:orientation="horizontal"
android:singleLine="true"
android:animateLayoutChanges="true"
/>
Here is the class:
package com.android.forexwatch.views.timepanel
import android.content.Context
import android.util.AttributeSet
import android.view.ContextThemeWrapper
import android.view.LayoutInflater
import android.widget.RelativeLayout
import androidx.appcompat.widget.LinearLayoutCompat
import com.android.forexwatch.model.Index
import com.android.forexwatch.R
import com.android.forexwatch.model.CityInfoDetailed
import com.github.ybq.android.spinkit.SpinKitView
class CarouselView(context: Context, attrs: AttributeSet): LinearLayoutCompat(context, attrs) {
companion object {
private const val IndexWidth = 600F
}
private var contextThemeWrapper: ContextThemeWrapper? = null
init {
contextThemeWrapper = ContextThemeWrapper(context.applicationContext, R.style.Theme_ForexWatch)
}
fun setupView ( cityInfo: CityInfoDetailed?, isMirror: Boolean = false) {
createPriceTickerViews(cityInfo, isMirror)
}
private fun createPriceTickerViews(cityInfo: CityInfoDetailed?, isMirror: Boolean = false) {
destroy()
removeAllViews()
var calculatedWidth = 0
cityInfo?.indexes?.forEachIndexed {
index, element ->
if (isMirror) index.plus(cityInfo?.indexes.count())
val loader: SpinKitView = LayoutInflater.from(contextThemeWrapper).inflate(R.layout.preloader, null) as SpinKitView
val priceTicker: PriceTicker = LayoutInflater.from(contextThemeWrapper).inflate(R.layout.price_ticker, null) as PriceTicker
addView(priceTicker)
addView(loader)
// priceTicker.x = IndexWidth * index
calculatedWidth.plus(IndexWidth)
priceTicker.initialize(element, cityInfo, loader)
}
layoutParams.width = calculatedWidth
}
private fun destroy() {
for (idx in 0 .. this.childCount) {
val view = getChildAt(idx)
if (view is PriceTicker) {
view.destroy()
}
}
}
}
Here is the parent class:
package com.android.forexwatch.views.timepanel
import android.animation.ValueAnimator
import android.graphics.Color
import android.view.View
import android.view.ViewGroup
import android.view.animation.LinearInterpolator
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.android.forexwatch.R
import com.android.forexwatch.adapters.TimePanelRecyclerViewAdapter
import com.android.forexwatch.events.TimeEvent
import com.android.forexwatch.model.CityInfoDetailed
import com.android.forexwatch.model.TimeObject
import com.android.forexwatch.utils.TimeKeeper
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
class TimePanelView(view: View, container: ViewGroup, timePanelAdapter: TimePanelRecyclerViewAdapter) : RecyclerView.ViewHolder(view) {
companion object {
private const val OffsetTime: Long = 15 * 60
private const val FrameRate: Long = 32
}
private var fxTime: TextView? = null
private var stockTime: TextView? = null
private var city: TextView? = null
private var currentTime: TextView? = null
private var fxTimeLabel: TextView? = null
private var stockTimeLabel: TextView? = null
private var carouselView: CarouselView? = null
private var carouselViewMirror: CarouselView? = null
private var parentContainer: ViewGroup? = null
private var adapter: TimePanelRecyclerViewAdapter? = null
private var cityInfo: CityInfoDetailed? = null
private var view: View? = null
init {
adapter = timePanelAdapter
this.view = view
this.parentContainer = container
EventBus.getDefault().register(this)
}
fun setupView(cityInfo: CityInfoDetailed?) {
this.cityInfo = cityInfo
city = view?.findViewById(R.id.city)
stockTime = view?.findViewById(R.id.stockTime)
fxTime = view?.findViewById(R.id.fxTime)
fxTimeLabel = view?.findViewById(R.id.fxTimeLabel)
stockTimeLabel = view?.findViewById(R.id.stockTimeLabel)
currentTime = view?.findViewById(R.id.currentTime)
carouselView = view?.findViewById(R.id.carouselLinear)
carouselViewMirror = view?.findViewById(R.id.carouselLinearMirror)
city?.text = cityInfo?.cityName
createCarousel()
}
#Subscribe
fun update(event: TimeEvent.Interval?) {
updateCurrentTime()
updateFxTime()
updateStockTime()
}
private fun createCarousel() {
carouselView?.setupView(cityInfo)
carouselViewMirror?.setupView(cityInfo, true)
carouselView?.bringToFront()
carouselViewMirror?.bringToFront()
animateCarousel()
}
private fun updateCurrentTime() {
val timezone: String? = cityInfo?.timeZone
currentTime?.text = TimeKeeper.getCurrentTimeWithTimezone(timezone, "EEE' 'HH:mm:ss")
}
private fun updateFxTime() {
updateTime(fxTime, fxTimeLabel, cityInfo?.forexOpenTimes, cityInfo?.forexCloseTimes, cityInfo?.timeZone, "FX", Companion.OffsetTime * 8)
}
private fun updateStockTime() {
updateTime(stockTime, stockTimeLabel, cityInfo?.stockOpenTime, cityInfo?.stockCloseTime, cityInfo?.timeZone, cityInfo?.stockExchangeName, Companion.OffsetTime)
}
private fun updateTime(timeView: TextView?, timeLabel: TextView?, open: TimeObject?, close: TimeObject?, timezone: String?, type: String?, timeOffset: Long) {
if (TimeKeeper.isMarketOpen(open, close, timezone)) {
timeView?.text = TimeKeeper.getTimeDifference(close, close, timezone, true)
displayMarketColors(timeView, timeOffset, close, timezone, Color.GREEN, true)
timeLabel?.text = "To " + type + " Close"
} else {
timeView?.text = TimeKeeper.getTimeDifference(open, close, timezone, false)
displayMarketColors(timeView, timeOffset, open, timezone, Color.RED, false)
timeLabel?.text = "To " + type + " Open"
}
}
private fun displayMarketColors(timeView: TextView?, timeOffset: Long, time: TimeObject?, timezone: String?, outRangeColor: Int, isMarketOpen: Boolean?) {
val color = if (TimeKeeper.isTimeWithinRange(timeOffset, time, timezone, isMarketOpen)) Color.parseColor("#FF7F00") else outRangeColor
timeView?.setTextColor(color)
}
private fun animateCarousel() {
if (cityInfo?.indexes?.count() == 1) {
return
}
// carouselView?.x = carouselView?.x?.minus(3.0F)!!
/* CoroutineScope(Dispatchers.Main).launch {
delay(FrameRate)
animateCarousel()
}*/
val animator = ValueAnimator.ofFloat(0.0f, 1.0f)
animator.repeatCount = ValueAnimator.INFINITE
animator.interpolator = LinearInterpolator()
animator.duration = 18000L
animator.addUpdateListener { animation ->
val progress = animation.animatedValue as Float
val width: Int? = carouselView?.width
val translationX = -width?.times(progress)!!
carouselView?.translationX = translationX!!
carouselViewMirror?.translationX = translationX!! + width!!
}
animator.start()
}
}
The PriceTicker layout which extends AppCompatTextView
<com.android.forexwatch.views.timepanel.PriceTicker
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
class="com.android.forexwatch.views.timepanel.PriceTicker"
android:layout_width="240dp"
android:layout_height="match_parent"
android:textAlignment="center"
android:textSize="13sp"
android:singleLine="true"
android:background="#drawable/rectangle_shape"
app:layout_constraintBottom_toBottomOf="parent"
/>
I found the solution by invalidating and requestingLayout on the priceTicker TextView and the container. Also changed the width of the container and priceTicker to the desired width.
calculatedWidth = calculatedWidth.plus(IndexWidth).toInt()
priceTicker.initialize(index, cityInfo, loader)
priceTicker.width = IndexWidth.toInt()
resetLayout(priceTicker)
}
layoutParams.width = (calculatedWidth)
resetLayout(thisContainer)
}
}
private fun destroy() {
for (idx in 0 .. this.childCount) {
val view = getChildAt(idx)
if (view is PriceTicker) {
view.destroy()
}
}
}
private fun resetLayout(view: View?) {
view?.invalidate()
view?.requestLayout()
}

Android PreferenceFragmentCompat title blank space

I don't know why using this Fragment can make the problem , it seems that isIconSpaceReserved = false is useful for not preferenceCagory
class TFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
val context = preferenceManager.context
val screen = preferenceManager.createPreferenceScreen(context)
val category1 = PreferenceCategory(context)
category1.title = "button"
category1.summary = "what is the problem"
category1.key = "bbb"
val swithButton = SwitchPreferenceCompat(context)
swithButton.title = "button"
swithButton.summary = "summary"
swithButton.key = "sss"
swithButton.isIconSpaceReserved = false
val swithButton2 = EditTextPreference(context)
swithButton2.title = "edit"
val swithButton3 = SeekBarPreference(context)
swithButton3.title = "seekbar"
swithButton3.value = 1
screen.addPreference(category1)
category1.addPreference(swithButton)
val category2 = PreferenceCategory(context)
category2.title = "category2"
screen.addPreference(category2)
category2.addPreference(swithButton2)
category2.addPreference(swithButton3)
preferenceScreen = screen
}
style is normal, I try so many ways but it's useless.
now, I tried the 'androidx.preference:preference:1.1.0-alpha01' , so lucky, It fixed the bug that the isIconSpaceReserved was not supported for PreferenceCategory.
override fun setPreferenceScreen(preferenceScreen: PreferenceScreen?) {
super.setPreferenceScreen(preferenceScreen)
if (preferenceScreen != null) {
val count = preferenceScreen.preferenceCount
for (i in 0 until count) {
if (preferenceScreen.getPreference(i) is PreferenceCategory) {
val category = preferenceScreen.getPreference(i) as PreferenceCategory
val childCount = category.preferenceCount
for (j in 0 until childCount) {
category.getPreference(j).isIconSpaceReserved = false
}
}
preferenceScreen.getPreference(i).isIconSpaceReserved = false
}
}
}

Categories

Resources