I have a dialog to select more than one days of a week as follows:
class DialogSettingsEnabledDays : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity.let {
val selectedDaysValue = BooleanArray(7) { _ -> false }
val selectedDaysIndex = ArrayList<Int>()
val daysToIndexMap = mutableMapOf<String, Int>()
val indexToDaysMap = mutableMapOf<Int, String>()
val daysArray = resources.getStringArray(R.array.days_medium)
for (i in 0..6) {
daysToIndexMap[daysArray[i]] = i
indexToDaysMap[i] = daysArray[i]
}
val prefs = it!!.getSharedPreferences(getString(R.string.shared_prefs_settings), Context.MODE_PRIVATE)
val selectedDaysString = prefs.getString("enabled_days", getString(R.string.default_enabled_days))
val selectedDays = selectedDaysString!!.split(", ")
for (day in selectedDays) {
selectedDaysValue[daysToIndexMap.getValue(day)] = true
selectedDaysIndex.add(daysToIndexMap.getValue(day))
}
val enabledDaysBuilder = AlertDialog.Builder(it)
enabledDaysBuilder
.setTitle(R.string.settings_enabled_days)
.setMultiChoiceItems(R.array.days_long, selectedDaysValue) { _, which, isChecked ->
if (isChecked)
selectedDaysIndex.add(which)
else if (selectedDaysIndex.contains(which))
selectedDaysIndex.remove(Integer.valueOf(which))
}
.setPositiveButton(R.string.dialog_ok) { _, _ ->
if (selectedDaysIndex.isEmpty()) {
Toast.makeText(it, "Select atleast one day !!", Toast.LENGTH_SHORT).show()
} else {
selectedDaysIndex.sort()
val selectedDaysList = mutableListOf<String>()
for (i in selectedDaysIndex) {
selectedDaysList.add(indexToDaysMap.getValue(i))
}
val editor = prefs.edit()
editor
.putString("enabled_days", selectedDaysList.joinToString())
.apply()
val enabledDays = it.findViewById<LinearLayout>(R.id.settings_enabled_days)
enabledDays.findViewById<TextView>(R.id.secondary_text).text = selectedDaysList.joinToString()
}
}
.setNegativeButton(R.string.dialog_cancel) { _, _ -> /* do nothing */ }
enabledDaysBuilder.create()
}
}
}
And I am calling this dialog in this way from my activity:
findViewById<LinearLayout>(R.id.settings_enabled_days)
.setOnClickListener {
DialogSettingsEnabledDays().show(this.supportFragmentManager, null)
}
My problem is that my selection of days resets to default on rotation.
By default I mean the selection stored in SharedPreferences, that is selectedDaysValue in .setMultiChoiceItems.
Suppose, these are the selected days when the dialog pops up:
Mon, Tue, Wed, Thu, Fri
Now, I change the selection as:
Mon, Tue
But, when I rotate the phone, the selection sets back to default:
Mon, Tue, Wed, Thu, Fri
How can I retain my selection on orientation change?
Because in some apps I have seen, the Dialog selection remains same on rotation.
Android system will automatically restore your fragment state, while the state changed fragment is not actually getting destroyed but only its view is recreated, so what ever value is inside your fragment variables will be kept as it is, all you have to do is reassign that variables value to your view, here's the reference link https://inthecheesefactory.com/blog/fragment-state-saving-best-practices/en
Well, this is the final solution I have made by making changes in the DialogFragment code only:
Changing the scope of data to be stored:
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity.let {
val selectedDaysValue = BooleanArray(7) { _ -> false }
val selectedDaysIndex = ArrayList<Int>()
to:
private var selectedDaysValue = BooleanArray(7) { _ -> false }
private var selectedDaysIndex = ArrayList<Int>()
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity.let {
Storing the data:
override fun onSaveInstanceState(outState: Bundle) {
outState.putBooleanArray("selected_days_value", this.selectedDaysValue)
outState.putIntegerArrayList("selected_days_index", this.selectedDaysIndex)
}
And where I read the data as:
val prefs = it!!.getSharedPreferences(getString(R.string.shared_prefs_settings), Context.MODE_PRIVATE)
val selectedDaysString = prefs.getString("enabled_days", getString(R.string.default_enabled_days))
val selectedDays = selectedDaysString!!.split(", ")
for (day in selectedDays) {
selectedDaysValue[daysToIndexMap.getValue(day)] = true
selectedDaysIndex.add(daysToIndexMap.getValue(day))
}
to read from saved state as:
val prefs = activity!!.getSharedPreferences(getString(R.string.shared_prefs_settings), Context.MODE_PRIVATE)
if (savedInstanceState == null) {
val selectedDaysString = prefs.getString("enabled_days", getString(R.string.default_enabled_days))
val selectedDays = selectedDaysString!!.split(", ")
for (day in selectedDays) {
selectedDaysValue[daysToIndexMap.getValue(day)] = true
selectedDaysIndex.add(daysToIndexMap.getValue(day))
}
} else {
with(savedInstanceState) {
selectedDaysValue = getBooleanArray("selected_days_value")!!
selectedDaysIndex = getIntegerArrayList("selected_days_index")!!
}
}
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 ?
PROBLEM - After a note is deleted from second activity, on returning back to first activity(this activity displays notes), changed made to note i.e deleted or edited does not shows change UNLESS the app is restarted and onCreate() method is recalled. If I change my device orientation, then the data gets updated.
How my code works - Basically, my app consists of two activities. First(Main) Activity is where recyclerview resides, this activity handles display of notes by fetching data from SQLite database and displays in form of cardViews. Those cardViews are click able, each cardView when clicked takes to Second(Reference) activity and a corresponding data is loaded into that activity. Now a user has a choice to either make changes to current note or to delete it. If a user clicks on delete button, data of the corresponding note is deleted from SQLite database. On deletion, app automatically goes back to Main activity. HOWEVER, the deleted note does not appears to be deleted in the main activity not until the app is restarted and onCreate method is called.
I have gone through multiple almost similar questions on the site but they do not appear to fit my needs. I am a beginner in Android development so if you could please explain it a little would greatly help me. Thank you.
MAIN ACTIVITY
class MainActivity : AppCompatActivity() {
//START OF EX-INITIALIZATIONS
var dbHandler: PediaDatabase? = null
var adapter: PediaAdapter? = null
var layoutManager: RecyclerView.LayoutManager? = null
var list: ArrayList<UserNotes>? = ArrayList()
var listItems: ArrayList<UserNotes>? = ArrayList()
val PREFS_NAME: String = "MYPREFS"
var myPrefs: SharedPreferences? = null
var first_run: Boolean = true
val REQUEST_CODE: Int = 1
var deletedNoteID: Int = 0
var deletedNoteAdapterPos: Int = 0
//END OF EX-INITIALIZATIONS
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
showOneTimeMessage()
invalidateOptionsMenu()
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
window.navigationBarColor = Color.BLACK
}
//START OF IN-INITIALIZATIONS
dbHandler = PediaDatabase(this)
list = ArrayList<UserNotes>()
listItems = ArrayList()
adapter = PediaAdapter(this, listItems!!)
layoutManager = LinearLayoutManager(this)
recyclerViewID.adapter = adapter
recyclerViewID.layoutManager = layoutManager
//END OF IN-INITIALIZATIONS
//DATA POPULATION STARTS HERE
list = dbHandler!!.readAllNotes()
for(reader in list!!.iterator())
{
var note = UserNotes()
note.noteTitle = reader.noteTitle
note.noteText = reader.noteText
note.noteID = reader.noteID
note.noteDate = reader.noteDate
listItems!!.add(note)
}
adapter!!.notifyDataSetChanged()
//DATA POPULATION ENDS HERE
if(dbHandler!!.totalNotes() == 0) {
recyclerViewID.visibility = View.GONE
}
else{
recyclerViewID.visibility = View.VISIBLE
showWhenEmptyID.visibility = View.GONE
}
}//end onCreate
override fun onRestart() {
super.onRestart()
overridePendingTransition(R.anim.slide_out, R.anim.slide_in)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.top_menu, menu)
val item = menu!!.findItem(R.id.delete_note_menu)
item.setVisible(false)
return true
//return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
if(item!!.itemId == R.id.add_note_menu){
var isNewNote = Intent(this, ReferenceActivity::class.java)
isNewNote.putExtra("isNewNote", true)
startActivityForResult(isNewNote, REQUEST_CODE)
}
if(item!!.itemId == R.id.delete_note_menu)
{
Toast.makeText(this,"DELETED", Toast.LENGTH_SHORT).show()
}
return super.onOptionsItemSelected(item)
}
private fun showOneTimeMessage()
{
var data: SharedPreferences = getSharedPreferences(PREFS_NAME, 0)
if(data.contains("isShown"))
{
first_run = data.getBoolean("isShown", true)
}
Log.d("FIRST_RUN", first_run.toString())
if(first_run) {
val oneTimeMsg = SweetAlertDialog(this)
oneTimeMsg.setTitleText("Hey there!")
oneTimeMsg.setContentText("Thank you for downloading! Please don`t forget to rate our app :)").show()
oneTimeMsg.setConfirmClickListener(object : SweetAlertDialog.OnSweetClickListener {
override fun onClick(sweetAlertDialog: SweetAlertDialog?) {
oneTimeMsg.dismissWithAnimation()
}
}).show()
myPrefs = getSharedPreferences(PREFS_NAME, 0)
var editor: SharedPreferences.Editor = (myPrefs as SharedPreferences).edit()
editor.putBoolean("isShown", false)
editor.commit()
}
}
REFERENCE ACTVITY
class ReferenceActivity : AppCompatActivity() {
var dbHandler: PediaDatabase? = null
var note = UserNotes()
var existingNote = UserNotes()
var noteExisted: Boolean = false
var cardID: Int = 0
var cardAdapterPos: Int? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_reference)
getSupportActionBar()!!.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
getSupportActionBar()!!.setCustomView(R.layout.custom_toolbar);
val dateTxtView = findViewById<View>(resources.getIdentifier("action_bar_title", "id", packageName)) as TextView
overridePendingTransition(R.anim.slide_in, R.anim.slide_out);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
window.navigationBarColor = Color.RED
dbHandler = PediaDatabase(this)
var data = intent
var isNewNote = intent
if(isNewNote != null)
if(isNewNote.extras.getBoolean("isNewNote") != true)
{
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
if(data != null)
{
noteExisted = true
this.cardAdapterPos = data.extras.getInt("cardPosition")
cardID = data.extras.getInt("cardID")
existingNote = dbHandler!!.readNote(cardID)
refTitleID.setText(existingNote.noteTitle, TextView.BufferType.EDITABLE)
refTextID.setText(existingNote.noteText, TextView.BufferType.EDITABLE)
dateTxtView.text = existingNote.noteDate.toString()
}
}else{
dateTxtView.text = "New note"
}
}//end onCreate()
override fun onStop() {
super.onStop()
var title: String = refTitleID.text.toString().trim()
var text: String = refTextID.text.toString().trim()
if(existingNote.noteText == text && existingNote.noteTitle == title)
finish()
if(noteExisted)
{
if(TextUtils.isEmpty(title))
title = "No title"
existingNote.noteTitle = title
existingNote.noteText = text
//existingNote.noteDate =
dbHandler!!.updateNote(existingNote)
var dataToMain = this.intent
dataToMain.putExtra("cardID", cardID)
dataToMain.putExtra("cardAdapterPos", cardAdapterPos)
setResult(Activity.RESULT_OK, dataToMain)
finish()
}
else
{
if(TextUtils.isEmpty(title) && TextUtils.isEmpty(text))
{
finish()
}
else
{
if(TextUtils.isEmpty(title))
title = "No title"
note.noteTitle = title
note.noteText = text
dbHandler!!.createNote(note)
finish()
}
}
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.top_menu, menu)
val addItem: MenuItem = menu!!.findItem(R.id.add_note_menu)
val delItem:MenuItem = menu.findItem(R.id.delete_note_menu)
addItem.setVisible(false)
delItem.setVisible(false)
if(noteExisted)
delItem.setVisible(true)
return true
//return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
if(item!!.itemId == R.id.delete_note_menu)
{
val dialogMsg = SweetAlertDialog(this, SweetAlertDialog.WARNING_TYPE)
dialogMsg.setTitleText("Are you sure?")
dialogMsg.setContentText("You won`t be able to recover this note!")
dialogMsg.setConfirmText("Yes,delete it!")
dialogMsg.setConfirmClickListener(object: SweetAlertDialog.OnSweetClickListener {
override fun onClick(sweetAlertDialog: SweetAlertDialog?) {
dialogMsg.dismissWithAnimation()
dbHandler!!.deleteNote(cardID)
var successMsg = SweetAlertDialog(sweetAlertDialog!!.context, SweetAlertDialog.SUCCESS_TYPE)
successMsg.setTitleText("Note deleted!")
successMsg.setContentText("So long,note").show()
successMsg.setCancelable(false)
//TODO Disable 'OK' button on successMsg dialogbox
Handler().postDelayed({
successMsg.dismissWithAnimation()
finish()
}, 1200)
}
}).show()
}
return super.onOptionsItemSelected(item)
}
}
you need to update your list items inside your adapter;
not sure how it works on kotlin, but I use something like this:
after a note update call adapter.updateItens(itens);
MyAdapter extendes RecyclerView.Adapter<MyViewHolder>
private List<MyItem> elements;
MyAdapter(){
this.elements = new ArrayList<>();
}
void updateElements(List<MyItem> itens){
Collections.sort(itens, new SortByName());
this.elements.clear();
this.elements.addAll(itens);
notifyDataSetChanged();
}
you can do even better if instead of notifyDataSetChanged(), you implement a DiffUtil;
After making changes to the data in the database, the RecyclerViewAdapter needs to be given a new list of data. This should be done in onRestart(), so that once you navigate back to MainActivity from SecondActivity, the RecyclerView is populated with the updated data. Try copying the code that populates the RecyclerView and put it into onRestart(). The reason why it was only updating when onCreate() was called is because that's the only place where you do anything to the view.