繁体   English   中英

Android:CustomView 中的 EditText 在触摸时未按预期运行

[英]Android: EditText in CustomView not behaving as expected when touched

我有一个 CustomView,其中包含一个 LinearLayout,其中包含一个 EditText 和另一个自定义视图元素。 但是,当我运行我的应用程序并触摸 EditText 时,它的行为与预期不同(似乎没有获得焦点并且软键盘没有打开)。 我试过在 EditText 和 LinearLayout 上设置duplicateParentState="true"。 我还附加了一个 onTouchEventListener 到 EditText,它调用了一个简单的 toast 并且 toast 确实出现了。

这是我的 CustomView 的代码。

表单字段.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="horizontal"
    android:layout_marginBottom="15dp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/grey_rounded_borders">

    <EditText
        android:id="@+id/edit_text"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:inputType="text"
        android:padding="10dp"
        android:textColor="#2d6169"
        android:textSize="18sp"
        android:background="@color/transparent" />

    <RelativeLayout
        android:layout_marginStart="5dp"
        android:layout_marginEnd="10dp"
        android:layout_width="wrap_content"
        android:layout_height="match_parent">

        <com.example.app.ValidationIcon
            android:id="@+id/validation_icon"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            tools:ignore="ContentDescription" />

    </RelativeLayout>

</LinearLayout>

表单域.java

package com.example.app;

import android.content.Context;
import android.content.res.TypedArray;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;

import java.util.ArrayList;

public class FormField extends LinearLayout {

    private EditText editText;
    private ValidationIcon validationIcon;

    private Integer fieldInputType;
    private String fieldInputHint;

    public FormField(Context context)
    {
        super(context);
    }

    public FormField(Context context, AttributeSet attributeSet)
    {
        super(context, attributeSet);

        TypedArray attrs = context.obtainStyledAttributes(attributeSet, R.styleable.FormField, 0, 0);

        fieldInputType = attrs.getInt(
                R.styleable.FormField_fieldInputType,
                InputType.TYPE_TEXT_VARIATION_NORMAL
        );
        fieldInputHint = attrs.getString(
            R.styleable.FormField_fieldInputHint
        );

        attrs.recycle();

        inflate(getContext(), R.layout.form_field, this);

        this.setFocusable(true);
        this.setFocusableInTouchMode(true);

        editText = (EditText)findViewById(R.id.edit_text);
        editText.setInputType(fieldInputType);
        editText.setHint(fieldInputHint);
        editText.setFocusableInTouchMode(true);

        validationIcon = (ValidationIcon)findViewById(R.id.validation_icon);
        validationIcon.setValid(true);

        ArrayList<View> touchables = new ArrayList<View>();
        touchables.add(this);
        touchables.add(editText);

        addTouchables(touchables);
    }

    public FormField(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

}

注册布局.xml

<RelativeLayout android:id="@+id/container"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="20dp">

    <RelativeLayout android:id="@+id/account_details"
        android:layout_marginBottom="15dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.example.app.FormField
            android:id="@+id/name_field"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            custom:fieldInputHint="@string/name_field_hint" />

        <com.example.app.FormField
            android:id="@+id/email_field"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            custom:fieldInputHint="@string/email_field_hint" />

        <com.example.app.FormField
            android:id="@+id/password_field"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            custom:fieldInputHint="@string/password_field_hint" />

        <com.example.app.FormField
            android:id="@+id/re_password_field"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            custom:fieldInputHint="@string/re_password_field_hint" />

    </RelativeLayout>

</RelativeLayout>

最小 SDK 版本设置为 14,目标设置为 20。任何帮助将不胜感激!

编辑:

我今天在 FormField 上测试长按时收到了这条 logcat 消息。

W/TextView﹕ TextView does not support text selection. Action mode cancelled.

我仔细检查了我的代码,并且 EditText 元素只被转换为 EditText。 如果 EditText 被转换为一个 TextView 可以解释我的原始问题,但现在我对为什么或如何将它转换为 TextView 感到困惑。

看起来您正在扩展 LinearLayout 但从未在您的布局中使用它。 从您发布的内容来看,您根本没有使用 FormField,我看到的唯一自定义视图是 ValidationIcon 视图。 因此,将触摸事件挂接到 EditText 和 ValidationIcon 不会发生,因为您没有在 layout.xml 中使用 FormField。

与其扩展 LinearLayout,不如使用预定义的方法和属性来处理您要实现的行为。 例如显示键盘、请求焦点、显示提示:

<EditText
    android:id="@+id/edit_text"
    android:layout_weight="1"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    **android:inputType="text"**
    **android:hint="@styleable/FormField_fieldInputHint"**
    android:padding="10dp"
    android:textColor="#2d6169"
    android:textSize="18sp"
    android:background="@color/transparent" />

键盘应该在编辑文本获得焦点时显示,如果没有,您可以通过请求焦点和处理 IME 管理器调用以编程方式执行此操作。 例如,从活动/片段:

//call this from onViewCreated to grab focus and begin the flow
editText.requestFocus();
//set focus listener to handle keyboard display
editText.setOnFocusChangeListener(new OnFocusChangeListener() {
     @Override
     public void onFocusChange(View v, boolean hasFocus) {
          if (!hasFocus) {
              InputMethodManager imm = (InputMethodManager)getSystemService(
  Context.INPUT_METHOD_SERVICE);
              imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
     } else {
              InputMethodManager imm = (InputMethodManager)getSystemService(
  Context.INPUT_METHOD_SERVICE);
              imm.showSoftInputFromWindow(myEditText.getWindowToken(), 0);
     }
});

确保没有设置inputType:'none'或 '0X000000'

  • 在此处输入图片说明

将此代码用于带有标题的自定义 Edittext


custom_view.xml

        <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:foregroundGravity="right"
        app:layout_anchorGravity="right">
    
        <LinearLayout
            android:orientation="vertical"
            android:id="@+id/search_closed_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center|right"
            android:background="@color/white"
            android:foregroundGravity="center"
            android:gravity="right">
    
            <TextView
                android:id="@+id/txt_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center|left"
                android:layout_marginStart="16dp"
                android:layout_marginTop="14dp"
                android:fontFamily="@font/intel"
                android:foregroundGravity="center"
                android:text="textview"
                android:textColor="@color/title_color"
                android:textSize="14dp"
                android:textStyle="bold" />
    
            <androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/lay"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="4dp"
                android:clickable="true"
                android:orientation="horizontal">
    
                <androidx.appcompat.widget.AppCompatEditText
                    android:id="@+id/edt_text"
                    android:layout_width="match_parent"
                    android:layout_height="50dp"
                    android:background="@drawable/edit_txtbg"
                    android:fontFamily="@font/intel"
                    android:gravity="center|start"
                    android:paddingStart="24dp"
                    android:textColor="@color/text_color"
                    android:textColorHint="@color/txt_hint"
                    android:textSize="@dimen/text_nev"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toStartOf="@+id/img_add_patient"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />
    
    
            </androidx.constraintlayout.widget.ConstraintLayout>
        </LinearLayout>
    
    
    </FrameLayout>


自定义编辑文本.kt

        package com.mdppractice.custom
    
    import android.content.Context
    import android.text.InputType
    import android.util.AttributeSet
    import android.view.LayoutInflater
    import android.widget.EditText
    import android.widget.FrameLayout
    import android.widget.TextView
    import com.mdppractice.R
    
    
    class CustomEditText(
        context: Context,
        attrs: AttributeSet,
    ) : FrameLayout(context, attrs) {
    
        private var txt_title: TextView
        private var edt_text: EditText
    
        init {
            LayoutInflater.from(context)
                .inflate(R.layout.custom_view, this, true)
            txt_title = findViewById(R.id.txt_title)
            edt_text = findViewById(R.id.edt_text)
    
    
            val a = context.obtainStyledAttributes(attrs, R.styleable.CustomEditText)
            txt_title.text = a.getString(R.styleable.CustomEditText_title)
            edt_text.hint = a.getString(R.styleable.CustomEditText_hint)
    
            when(a.getString(R.styleable.CustomEditText_inputType)) {
                "number" -> edt_text.inputType = InputType.TYPE_CLASS_PHONE
                "textCapSentences" -> edt_text.inputType = InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
                "text" -> edt_text.inputType = InputType.TYPE_CLASS_TEXT
            }
    
            a.recycle()
    
        }
    
        fun setmInputType(type: Int) {
            edt_text.setRawInputType(InputType.TYPE_CLASS_TEXT)
            setmInputType(type)
        }
    
        fun setTitle(title: Int) {
            txt_title.setText(title)
        }
    
        fun set_Text(title: Int) {
            edt_text.setText(title)
        }
    
        fun getTitle(): String {
            return txt_title.text.toString()
        }
    
        fun get_Text(): String {
            return edt_text.text.toString()
        }
    
    
    }


主/../attr.xml

  <declare-styleable name="CustomEditText">
    <attr name="title" format="string"/>
    <attr name="onCenter" format="boolean"/>
    <attr name="hint" format="string"/>
    <attr name="maxLength" format="integer"/>
    <attr name="inputType" format="string"/>
</declare-styleable>


@drawable/edit_txtbg

            <?xml version="1.0" encoding="utf-8"?>
        <shape xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/listview_background_shape">
            <stroke android:width="1dp" android:color="@color/button_bg_border" />
            <padding android:left="0dp"
                android:top="0dp"
                android:right="0dp"
                android:bottom="0dp" />
            <corners android:radius="6dp"/>
            <solid android:color="@color/button_bg" />
        
        </shape>
  • 在布局中使用

     <com.mdppractice.custom.CustomEditText android:id="@+id/edt_custom" android:layout_width="match_parent" android:layout_height="wrap_content" app:title="Patient ID/Phone" android:autofillHints="@string/verified" android:foregroundGravity="center" android:hint="Please enter name" app:inputType="textCapSentences" android:textColor="@color/title_color" android:textSize="14dp" android:textStyle="bold" />


感谢您

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM