EditText right drawable doesn't update after showError - android

EditText right drawable doesn't update after showError method gets called. I have tried to set setError to null, set right drawable to null but nothing helps.
Drawable right = DrawableUtils.getDrawable(context,R.drawable.eye_look);
right.setBounds(new Rect(0, 0, rigth.getIntrinsicWidth(), right.getIntrinsicHeight()));
myEditText.setError(null, null);
myEditText.setCompoundDrawablesWithIntrinsicBounds(DrawableUtils.getDrawable(context,R.drawable.pass_look), null, right, null);
Any ideas ?
Code example for checking:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
vEditText.error = "Some error"
vButton.setOnClickListener {
vEditText.error = null
}
vEditText.setOnTouchListener(object : OnTouchListener {
override fun onTouch(p0: View?, event: MotionEvent?): Boolean {
val DRAWABLE_LEFT = 0
val DRAWABLE_TOP = 1
val DRAWABLE_RIGHT = 2
val DRAWABLE_BOTTOM = 3
if (event?.action == MotionEvent.ACTION_UP) {
if (event.rawX >= (vEditText.right - vEditText.compoundDrawables[DRAWABLE_RIGHT].bounds.width())) {
vEditText.setCompoundDrawablesWithIntrinsicBounds(null, null, ContextCompat.getDrawable(vEditText.context,android.R.drawable.btn_star_big_on), null)
vEditText.error = null
return true
}
}
return false
}
})
}
}

First decorate the EditText with your desired Drawable.
Drawable right = DrawableUtils.getDrawable(context,R.drawable.eye_look);
right.setBounds(new Rect(0, 0, rigth.getIntrinsicWidth(), right.getIntrinsicHeight()));
myEditText.setCompoundDrawablesWithIntrinsicBounds(DrawableUtils.getDrawable(context,R.drawable.pass_look), null, right, null);
...
Now whenever need to show error just use
myEditText.setError("Your error message");
And hide error drawable like below
myEditText.setError(null);
Which actually hide the error drawable and show your drawable. No need to do anything more.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
I have update your code, check now
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//This is important to set here
vEditText.setCompoundDrawablesWithIntrinsicBounds(null, null, ContextCompat.getDrawable(vEditText.context,android.R.drawable.btn_star_big_on), null)
vEditText.error = "Some error"
vButton.setOnClickListener {
vEditText.error = null
}
}
Now type something on vEditText or click vButton and check.

Try this:
myEditText.setError(null);
myEditText.setErrorEnabled(false);
myEditText.setCompoundDrawablesWithIntrinsicBounds(ContextCompat.getDrawable(context,R.drawable.icon), null, ContextCompat.getDrawable(context,R.drawable.icon), null);

Related

How to set the color of the cursor(caret) multiple times in Android

Lets say we have a simple EditText and I want to change the cursor(caret) to some other color, before we were use reflections to get access to the private fields, but with introduction of Android API Q(29), we can now use textCursorDrawable to set the drawable for the blinking cursor.
Here is the xml code of the EditText
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="#+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Test"
android:textSize="30sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Now we can use a WrapDrawable to wrap a ColorDrawable, that will be set as textCursorDrawable value of the EditText, in order for us to change the cursor color.
Here is the code for the WrapDrawable:
class WrapDrawable(color: Int) : Drawable() {
private var drawable = ColorDrawable(color)
#ColorInt
var color: Int = color
set(value) {
field = value
drawable = ColorDrawable(value)
}
override fun setBounds(left: Int, top: Int, right: Int, bottom: Int) {
super.setBounds(left, top, right, bottom)
drawable.setBounds(left, top, right, bottom)
}
override fun getConstantState(): ConstantState? {
return drawable.constantState
}
override fun setAlpha(alpha: Int) {
drawable.alpha = alpha
}
override fun setColorFilter(colorFilter: ColorFilter?) {
drawable.colorFilter = colorFilter
}
override fun getOpacity(): Int {
return drawable.alpha
}
override fun draw(canvas: Canvas) {
drawable.draw(canvas)
}
override fun getIntrinsicWidth(): Int {
return drawable.bounds.width()
}
override fun getIntrinsicHeight(): Int {
return drawable.bounds.height()
}
}
In the code below, we change the color of the cursor twice once to Color.RED and second time to Color.BLUE, now we should expect to have a BLUE cursor.
But the problem is that once textCursorDrawable is set, we cannot change it even if we try nullify it.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val text = findViewById<EditText>(R.id.editText)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// set the cursor color to RED
text.textCursorDrawable = WrapDrawable(Color.RED).apply {
setBounds(0, 0, 5, text.lineHeight)
}
// set the cursor color to BLUE !!! NOT WORKING !!!
text.textCursorDrawable = WrapDrawable(Color.BLUE).apply {
setBounds(0, 0, 5, text.lineHeight)
}
}
}
}
So my question is how can we reassign the textCursorDrawable value multiple times?
I have found a workaround by updating the already existing textCursorDrawable value, and changing the ColorDrawable using the color variable.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val text = findViewById<EditText>(R.id.editText)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// set the cursor color to RED
text.textCursorDrawable = WrapDrawable(Color.RED).apply {
setBounds(0, 0, 5, text.lineHeight)
}
// set the cursor color to BLUE
text.textCursorDrawable?.let {
if (it is WrapDrawable) {
it.color = Color.BLUE
it.setBounds(0, 0, 5, text.lineHeight)
}
}
}
}
}
The documentation for setTextCursorDrawable() states:
Note that any change applied to the cursor Drawable will not be visible until the cursor is hidden and then drawn again.
I have taken a quick look through the TextView and EditText code and haven't determined how to make the change you want. I am not saying that it can't be done; I just don't see it.
Instead, try making a change to your WrapDrawable like this:
(text.textCursorDrawable as WrapDrawable).apply {
color = Color.BLUE
setBounds(0, 0, 5, text.lineHeight)
}
This will work and will save the instantiation of a new WrapDrawable.
Update
Can't prove a negative, but it looks like the cursor drawable can't be replaced once set. The following is the reasoning.
For API 31, there are only two places within the TextView code where the cursor drawable is set. The private scope of mCursorDrawable will restrict outside access.
In TextView.java:
private Drawable mCursorDrawable;
public void setTextCursorDrawable(#Nullable Drawable textCursorDrawable) {
mCursorDrawable = textCursorDrawable;
mCursorDrawableRes = 0;
if (mEditor != null) {
mEditor.loadCursorDrawable();
}
}
#Nullable public Drawable getTextCursorDrawable() {
if (mCursorDrawable == null && mCursorDrawableRes != 0) {
mCursorDrawable = mContext.getDrawable(mCursorDrawableRes);
}
return mCursorDrawable;
}
It is the text editor class that the cursor is drawn and it reaches back into the TextView to get the drawable that will be used.
In Editor.java:
Drawable mDrawableForCursor = null;
private void drawCursor(Canvas canvas, int cursorOffsetVertical) {
final boolean translate = cursorOffsetVertical != 0;
if (translate) canvas.translate(0, cursorOffsetVertical);
if (mDrawableForCursor != null) {
mDrawableForCursor.draw(canvas);
}
if (translate) canvas.translate(0, -cursorOffsetVertical);
}
void loadCursorDrawable() {
if (mDrawableForCursor == null) {
mDrawableForCursor = mTextView.getTextCursorDrawable();
}
}
loadCursorDrawable is the only place that mDrawableForCursor is set so, once it is defined, it can't be changed. Since it can't be changed, it can't be set to null to pick up a new cursor drawable that may be defined in the text view.
So, the long and the short of this is that the cursor can be changed in TextView but cannot be propagated to the editor.

How to use SetOnClickListener on a programmatic ScrollView Android Kotlin

I created a scrollView programmaticaly that contains 20 views each with an image and a text.
I have two questions :
1 - is the id assignment correct and is my setOnClickListener correct?
2 - By which method onClick can I know which view of the scrollView the user has clicked?
See my code below
private var integerList: MutableList<Int>? = mutableListOf()
private var cellNo: MutableList<String>? = mutableListOf()
private var sv_mvmtChoosed = ""
private fun showSpinner() {
/* SCROllL VIEW */
var linearLayout: LinearLayout? = null
linearLayout = findViewById(R.id.linear1)
val layoutInflater = LayoutInflater.from(this)
var randIndex = 0
for (posIndex in 0..19) {
val rand = Random()
randIndex = rand.nextInt(20)
while (integerList!!.contains(randIndex)) {
randIndex = rand.nextInt(20)
}
integerList!!.add(randIndex)
// Create the view...
val view: View = layoutInflater.inflate(R.layout.scroll_bckgrnd, linearLayout, false)
// give it an id
view.id = generateViewId()
view.setOnClickListener(this)
cellNo!!.add(view.id.toString())
println(cellNo)
//... then populate it with image and text
val iv = view.findViewById<ImageView>(R.id.iv)
iv.setImageResource(sv_photoImage[randIndex])
val tv = view.findViewById<TextView>(R.id.tv)
tv.text = sv_photoName[randIndex]
linearLayout?.addView(view)
}
// which view the user did select?
fun onClick(view: View?) {
when (view!!.id) {
??? -> doSomething
}
}
}
Any idea to get me back on track will be welcome.
Its probably better to make a new OnClickListener for every view.
view.setOnClickListener(this)
needs to be this
view.setOnClickListener {
// do something
}
or
view.setOnClickListener(createOnClickListner())
fun createOnClickListner():View.OnClickListener{
return object :View.OnClickListener{
override fun onClick(view : View) {
//do something with the view that was clicked
}
}
}
Thanks a lot avalerio.
I finally found a solution as follow :
I replaced :
// give it an id
view.id = generateViewId()
view.setOnClickListener(this)
cellNo!!.add(view.id.toString())
println(cellNo)
with :
// give it an id
view.id = posIndex
view.setOnClickListener(this)
then I did this :
// the onClickListener for my 20 images/text
override fun onClick(view: View?) {
when (view!!.id) {
// Now de position clicked on the ScrollView
in 0..19 -> didHeSucceeded(view!!.id)
}
}
And use the result:
private fun didHeSucceeded(scrllPos: Int) {
// TODO: close de scrollView, how ? :-)
spinnerChoice = nameOfTechScrollVw[scrllPos]
succes = (!allreadyChoosedArray.contains(spinnerChoice)) && (currentArray.contains(spinnerChoice
))
if (succes) {
...
...
}
It works perfectly

Getting NumberFormatException in onSavedInstanceState() method [duplicate]

This question already has answers here:
How can I prevent java.lang.NumberFormatException: For input string: "N/A"?
(6 answers)
Closed 2 years ago.
I am using onSavedInstanceState() method so that after after rotating device my textview should not lost its value but i'm getting crash that i've mentioned in activity.
Following is my activity
class SavedInstanceActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_saved_instance)
imgPlus.setOnClickListener {
if (tvText.text.toString().toInt() >= 10)
tvText.text = "10"
else
tvText.text = tvText.text.toString().toInt().plus(1).toString()
}
imgMinus.setOnClickListener {
if (tvText.text.toString().toInt() <= 0)
tvText.text = "0"
else
tvText.text = tvText.text.toString().toInt().minus(1).toString()
}
if (savedInstanceState != null) {
count = savedInstanceState.getInt("int", 0)
tvText.text = count.toString()
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt("int", tvText.toString().toInt()) //getting crash here java.lang.NumberFormatException: For input string: "com.google.android.material.textview.MaterialTextView{12c8970 V.ED..... ........ 511,982-570,1084 #7f080174 app:id/tvText}"
Log.d("saved", tvText.toString())
}
}
You are tried to convert textview as string instead of text
Try like beklow...
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt("int", tvText.text.toString().toInt())
Log.d("saved", tvText.toString())
}
You are using tvText.toString().toInt() it should be tvText.text.toString().toInt() . Also you need to check if text is empty or not before parsing it to Int . See the code below i have made some modifications.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
imgPlus.setOnClickListener {
if (tvText.text.toString().isNotEmpty() && tvText.text.toString().toInt() >= 10)
tvText.text = "10"
else
tvText.text = tvText.text.toString().toInt().plus(1).toString()
}
imgMinus.setOnClickListener {
if (tvText.text.toString().isNotEmpty() && tvText.text.toString().toInt() <= 0)
tvText.text = "0"
else
tvText.text = tvText.text.toString().toInt().minus(1).toString()
}
if (savedInstanceState != null) {
val count = savedInstanceState.getInt("int", 0)
tvText.text = count.toString()
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
if(tvText.text.toString().isNotEmpty())
outState.putInt("int", tvText.text.toString().toInt())
}
I don't recommend relying on a text UI element to store your non-text application state. It's kind of convoluted. I would keep the count as an Int property and sync it with the TextView. Actually, I would put the count in the ViewModel if there was one, but for simplicity:
class SavedInstanceActivity : AppCompatActivity() {
private var count = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_saved_instance)
imgPlus.setOnClickListener {
count = min(count + 1, 10)
tvText.text = count.toString()
}
imgMinus.setOnClickListener {
count = max(count - 1, 0)
tvText.text = count.toString()
}
if (savedInstanceState != null) {
count = savedInstanceState.getInt("int", 0)
tvText.text = count.toString()
}
}
//...
}
To take it a step further, you could make the property automatically update the text view when it's changed:
class SavedInstanceActivity : AppCompatActivity() {
private var count by Delegates.observable(0) { _, _, _ ->
tvText.text = count.toString()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_saved_instance)
imgPlus.setOnClickListener {
count = min(count + 1, 10)
}
imgMinus.setOnClickListener {
count = max(count - 1, 0)
}
if (savedInstanceState != null) {
count = savedInstanceState.getInt("int", 0)
}
}
//...
}
As for your specific problem, as the other answers have mentioned, it's because you're trying to convert the text without safely checking if it is parseable as an Int, and it's not if it's blank. It is safer to use toIntOrNull() which gives you an Int? to work with instead of throwing an exception when the text is invalid.

Typechecking in Kotlin

I am a Kotlin newbie. I have a simple app in which I'm trying to sanitise all my input. Everything works in theory, but my app doesn't produce the required output.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val editTextWeight = findViewById<EditText>(R.id.weightEditText) as EditText
val editTextHeight = findViewById<EditText>(R.id.heightEditText) as EditText
val calculateButton = findViewById<Button>(R.id.calcButton)
calculateButton.isEnabled = false
val weight = editTextWeight.text.toString().toDoubleOrNull()
val height = editTextHeight.text.toString().toDoubleOrNull()
if (weight != null && height != null ) {
calculateButton.isEnabled = true
calculateButton?.setOnClickListener()
{
val bmi = weight / (height*height )
Toast.makeText(this#MainActivity,
"Your BMI is $bmi", Toast.LENGTH_LONG).show()
}
}
}
}
I have tried to add an else condition ie:
//calculateButton.isEnabled = false
if (weight != null && height != null ) {
//calculateButton.isEnabled = true
calculateButton?.setOnClickListener()
{
val bmi = weight / (height*height )
Toast.makeText(this#MainActivity,
"Your BMI is $bmi", Toast.LENGTH_LONG).show()
}
}else
Toast.makeText(this#MainActivity,
"Please enter both values correctly!", Toast.LENGTH_LONG).show()
The button is clickable, but I get no output from the app.
What am I doing wrong? Is there an app state like in Angular where I can seperate component initialisation from program logic?
You should check the text input when you perform click on your button, in perfect programm your code should look like this :
class MainActivity : AppCompatActivity() {
lateinit var calculateButton: Button
lateinit var editTextWeight: EditText
lateinit var editTextHeight: EditText
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
editTextWeight = findViewById(R.id.weightEditText)
editTextHeight = findViewById(R.id.heightEditText)
calculateButton = findViewById(R.id.calcButton)
calculateButton.setOnClickListener()
{
val weight: Double = editTextWeight.text.toString().toDoubleOrNull() ?: 0.0
val height: Double = editTextHeight.text.toString().toDoubleOrNull() ?: 0.0
val bmi = weight / (height * height)
if (bmi.isNaN())
Toast.makeText(this#MainActivity,
"Input error, please try again!", Toast.LENGTH_LONG).show()
else
Toast.makeText(this#MainActivity,
"Your BMI is $bmi", Toast.LENGTH_LONG).show()
}
}
}

RecyclerView not updating after delete/update of a note

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.

Categories

Resources