Kotlin падает в PasswordTransformationMethod, а Java работает нормально - PullRequest
0 голосов
/ 03 июня 2018

Код ниже вылетает в Kotlin / Android с трассировкой стека, предоставленной внизу.Он был конвертирован из Java / Android, у которого не было такой проблемы.Оригинальный Java-код также предоставляется.Сбой происходит, когда я пытаюсь добавить символ в поле пароля.Редактирование существующих персонажей работает хорошо.

У меня есть два вопроса по этому поводу:

  1. Что побудило Kotlin заменить java.lang.CharSequence на CharSequence Kotlin?Эти два совершенно разные, и я подозреваю, что это вызывает сбой.
  2. Есть ли способ заставить его работать в Kotlin?

Код Kotlin, который вылетает из AndroidPaint

        mPwd!!.transformationMethod = object : PasswordTransformationMethod() {
        override fun getTransformation(source: CharSequence, view: View): CharSequence {
            return PasswordCharSequence(source)
        }
        internal inner class PasswordCharSequence(private val source: CharSequence)// Store char sequence
            : CharSequence {

            val mSource = source
            public override val length = mSource.length

            init {
                App.d(TAG, "SOURCE " + mSource + " " + length)
            }
            override fun get(index: Int): Char {
                App.d(TAG, "SOURCE IND " + index + " " + mSource.length)
                return if (mChkUnmask!!.isChecked) mSource.get(index) else '*'
            }
            override fun subSequence(start: Int, end: Int): CharSequence {
                App.d(TAG, "SOURCE SUB " + start + " " + end)
                return mSource.subSequence(start, end) // Return default
            }
        }
    }

Оригинальный код Java, который отлично работает

        mPwd.setTransformationMethod(new PasswordTransformationMethod() {

        @Override
        public CharSequence getTransformation(CharSequence source, View view) {
            return new PasswordCharSequence(source);
        }

        class PasswordCharSequence implements CharSequence {
            private CharSequence mSource;
            public PasswordCharSequence(CharSequence source) {
                mSource = source; // Store char sequence
            }
            public char charAt(int index) {
                return mChkUnmask.isChecked()?mSource.charAt(index):'*';
            }
            public int length() {
                return mSource.length(); // Return default
            }
            public CharSequence subSequence(int start, int end) {
                return mSource.subSequence(start, end); // Return default
            }
        }
    });

Трассировка стека от Logcat

06-03 00:35:08.143 16694 16694 E AndroidRuntime: java.lang.IndexOutOfBoundsException
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.graphics.Paint.getRunAdvance(Paint.java:2986)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.text.TextLine.handleText(TextLine.java:719)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.text.TextLine.handleRun(TextLine.java:873)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.text.TextLine.measureRun(TextLine.java:387)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.text.TextLine.measure(TextLine.java:277)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.text.TextLine.metrics(TextLine.java:251)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.text.Layout.getLineExtent(Layout.java:1072)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.text.Layout.getLineWidth(Layout.java:1038)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.widget.TextView.desired(TextView.java:8142)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.widget.TextView.onMeasure(TextView.java:8208)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.view.View.measure(View.java:21051)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.view.View.measure(View.java:21051)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:715)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:461)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.view.View.measure(View.java:21051)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6459)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:141)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.view.View.measure(View.java:21051)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6459)
06-03 00:35:08.143 16694 16694 E AndroidRuntime:        at android.support.v7.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:400)

Выход программы из Log.d (...)

10 - это длина CharSequence здесь.Первая цифра - текущий индекс.Сбой происходит, когда я пытался добавить символ с индексом 9 с клавиатуры.Он никогда не добавлялся и не отображался в выводе ниже

06-03 00:35:08.121 16694 16694 D GAC-STORE: SOURCE IND 810
06-03 00:35:08.121 16694 16694 D GAC-STORE: SOURCE IND 710
06-03 00:35:08.121 16694 16694 D GAC-STORE: SOURCE IND 610
06-03 00:35:08.121 16694 16694 D GAC-STORE: SOURCE IND 510
06-03 00:35:08.121 16694 16694 D GAC-STORE: SOURCE IND 410
06-03 00:35:08.121 16694 16694 D GAC-STORE: SOURCE IND 310
06-03 00:35:08.121 16694 16694 D GAC-STORE: SOURCE IND 210
06-03 00:35:08.121 16694 16694 D GAC-STORE: SOURCE IND 110
06-03 00:35:08.121 16694 16694 D GAC-STORE: SOURCE IND 010
06-03 00:35:08.121 16694 16694 D GAC-STORE: SOURCE IND 010
06-03 00:35:08.121 16694 16694 D GAC-STORE: SOURCE IND 110
06-03 00:35:08.121 16694 16694 D GAC-STORE: SOURCE IND 210
06-03 00:35:08.121 16694 16694 D GAC-STORE: SOURCE IND 310
06-03 00:35:08.121 16694 16694 D GAC-STORE: SOURCE IND 410
06-03 00:35:08.121 16694 16694 D GAC-STORE: SOURCE IND 510
06-03 00:35:08.122 16694 16694 D GAC-STORE: SOURCE IND 610
06-03 00:35:08.122 16694 16694 D GAC-STORE: SOURCE IND 710
06-03 00:35:08.122 16694 16694 D GAC-STORE: SOURCE IND 810
06-03 00:35:08.122 16694 16694 D GAC-STORE: SOURCE IND 010
06-03 00:35:08.122 16694 16694 D GAC-STORE: SOURCE IND 110
06-03 00:35:08.122 16694 16694 D GAC-STORE: SOURCE IND 210
06-03 00:35:08.122 16694 16694 D GAC-STORE: SOURCE IND 310
06-03 00:35:08.122 16694 16694 D GAC-STORE: SOURCE IND 410
06-03 00:35:08.122 16694 16694 D GAC-STORE: SOURCE IND 510
06-03 00:35:08.122 16694 16694 D GAC-STORE: SOURCE IND 610
06-03 00:35:08.122 16694 16694 D GAC-STORE: SOURCE IND 710
06-03 00:35:08.122 16694 16694 D GAC-STORE: SOURCE IND 810
06-03 00:35:08.122 16694 16694 D GAC-STORE: SOURCE IND 810

Макет для mPwd

<EditText
    android:id="@+id/txtDlgPwd"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/chkStorePwd"
    android:hint ="Ecnryption Password"
    android:maxLines="1"
    android:singleLine="true"
    android:inputType="textPassword|textNoSuggestions"
    android:imeOptions="actionDone"
    android:layout_marginLeft="10dp"
    android:layout_marginTop="20dp"
    android:textSize="15sp"/>

Ответы [ 2 ]

0 голосов
/ 26 августа 2019
class CustomPasswordSymbole : PasswordTransformationMethod() {
    override fun getTransformation(source: CharSequence?, view: View?): CharSequence {
        return PasswordCharSequence(source)
    }

    class PasswordCharSequence(source: CharSequence?) : CharSequence{
        val mSource = source
        override val length: Int=6 ///manually enter lenght of your password

        override fun get(index: Int): Char {
            return '*'
         }

        override fun subSequence(startIndex: Int, endIndex: Int): CharSequence {
            return  mSource!!.subSequence(startIndex, endIndex)
        }
    }
}
0 голосов
/ 04 июня 2018

К счастью, Android / Kotlin позволяет смешивать файлы Java и Kotlin в одном проекте.Я использовал это как способ решения проблемы.

Создан Java-класс для обработки пароля.Обратите внимание, что CharSequence является нативным классом Java здесь, и это имеет значение.

import java.lang.CharSequence;

public class PasswordHandler implements CharSequence {

    private CharSequence mSource;
    private Switch mUnmask;

    public PasswordHandler(CharSequence source, Switch unmask) {
        mSource = source;
        mUnmask = unmask;
    }

    public char charAt(int index) {
        return mUnmask.isChecked()?mSource.charAt(index):'*';
    }
    public int length() {
        return mSource.length();
    }
    public CharSequence subSequence(int start, int end) {
        return mSource.subSequence(start, end);
    }

    @NonNull
    @Override
    public String toString() {
        String star = new String();
        int l = length();
        if (!mUnmask.isChecked()) {
            while (l-- > 0){
                star += "*";
            }
        }
        return mUnmask.isChecked()? mSource.toString():star;
    }
}

Создание этого класса в методе getTransfromation класса Kotlin.На этот раз компилятор Kotlin воспринял это хорошоСбои больше не происходят. Я все еще хотел бы видеть чистое решение Котлина для этого.

mPwd!!.transformationMethod = object : PasswordTransformationMethod() {
            override fun getTransformation(source: CharSequence, view: View): CharSequence {
                return PasswordHandler(source, mChkUnmask)
            }

        } 
...