Hot questions for Using Android EditText in kotlin

Question:

My OnClickListener gets only called on the second click. The OnLongClickListener for the same View works as expected. I tried using OnTouchListener instead, but that gets obviously triggered when swiping.

My listeners are abstract methods of an Interface that I implement in my activity:

interface OnVocableFlashcardFragmentInteractionListener {
    fun onEditTextLongClick(view: View): Boolean
    fun onEditTextClick(view: View)
}

I set the listeners of my View like this in my RecyclerViewAdapter Class:

init{
    setHasStableIds(true)

    mEditTextOnClickListener = View.OnClickListener {
        mListener.onEditTextClick(it)
    }

    mEditTextOnLongClickListener = View.OnLongClickListener {
        mListener.onEditTextLongClick(it)
    }
}

override fun onBindViewHolder(holder: FlashcardViewHolder, position: Int) {
    ...
    editText.let { it.tag = it.keyListener; it.keyListener = null; }
    editText.setOnClickListener(mEditTextOnClickListener)
    editText.setOnLongClickListener(mEditTextOnLongClickListener)
    ...
}

The implementation of the listeners in my activity looks like following:

override fun onEditTextClick(view: View) {
    //-- only show toast if view is not editable (becomes editable on LongClick)
    if ((view as EditText).keyListener == null) {
        if (mToast != null) {
            mToast!!.cancel()
        }
        //-- inform user to long press to edit entry
        mToast = Toast.makeText(this, resources.getString(R.string.long_click_to_edit), Toast.LENGTH_LONG)
        mToast!!.show()
    }
}

override fun onEditTextLongClick(view: View): Boolean {
    //-- I saved the KeyListener in the editTexts tag attribute
    //-- to make it clickable again when needed
    (view as EditText).keyListener = view.getTag() as KeyListener
    showSoftKeyboard(view)
    return true
}

The XML of my View looks like following:

            <EditText
            android:id="@+id/et_vocable_word"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:background="@null"
            android:textStyle="bold"
            android:hint="@string/enter_word"
            android:imeOptions="actionNext"
            android:inputType="textNoSuggestions"
            android:maxLines="1"
            android:singleLine="true" />

the view's parents and its parents parents are not declared as android:focusable="true" or android:clickable="true"

In my AndroidManifest.xml I have set android:windowSoftInputMode="stateHidden" for my activity to prevent the SoftInput from showing up when the activity starts.

Am I doing something utterly wrong or why does the OnClickListener only get called on the second click? Does anyone have an Idea how I could solve the problem?


Answer:

you must make edit text focusable attribute false, because its default value is auto and this means is framework determine it must be true and false.when it be true at your first touch it has been focused by keyboard.

https://developer.android.com/reference/android/R.styleable#View_focusable

Question:

I am developing an app that requires screen pinning and a full window so I hide the navigation bar etc.

When the activity opens and the EditText gains focus the Soft Keyboard will become visible and it will shift the EditText above it -- Great, no problems there.

The issue appears when I dismiss the Soft Keyboard and reopen it by clicking on said EditText, the Soft Keyboard will now hide the EditText.

Any ideas on how I can resolve this? I have tried containing the entire layout inside a ScrollView and the issue is still happening.

Window flags being used:

 val flags = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
        or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
        or View.SYSTEM_UI_FLAG_FULLSCREEN
        or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)

 window.decorView.systemUiVisibility = flags
 window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)

Inside my Manifest I use:

android:windowSoftInputMode="stateHidden|adjustResize"

SOLVED.

I managed to resolve this by removing the input type from the EditText.


Answer:

I managed to solve this by removing the input type from the EditText.

Question:

I've looked into using a TextWatcher and an InputFilter, but I'm not too sure how to approach this problem.

The idea is to have an EditText that inserts text from right to left. As the use input changes, I would like the following to occur.

- User enters "1" -> Text formats as 00:01
- User enters "2" -> Text formats as 00:12
- User enters "8" -> Text formats as 01:28

How could I approach this? Inputfilter seems to be for excluding text and using setText inside the TextWatcher appears to run in an endless loop.


Answer:

Try this:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <EditText
        android:id="@+id/edittext"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="25dp"
        android:padding="20dp"
        android:inputType="number"
        android:maxLength="4"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textview"
        android:textSize="25dp"
        android:padding="20dp"/>

</LinearLayout>

MainActivity.kt

import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        edittext.addTextChangedListener(object : TextWatcher {
            override fun afterTextChanged(s: Editable) {}
            override fun beforeTextChanged(s: CharSequence, start: Int,
                                           count: Int, after: Int) {
            }
            override fun onTextChanged(s: CharSequence, start: Int,
                                       before: Int, count: Int) {
                if (s.length<5){
                    var a=""
                    var i=4-s.length
                    var j=0
                    while (j<i){
                        a+="0"
                        j++
                    }
                    var b=a+s
                    b = b.substring(0, 2) + ":" + b.substring(2, b.length)
                textview.setText(b)}
            }
        })
    }
}