Android:CustomView中的EditText在触摸时表现不正常

问题描述 投票:2回答:2

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

这是我的CustomView的代码。

form_field.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>

FormField.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);
    }

}

registration_layout.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。非常感谢您的帮助!

编辑:

我今天在测试在FormFields上的长按时收到此logcat消息。

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

我仔细检查了我的代码,仅将EditText元素转换为EditText。如果将EditText强制转换为TextView可以解释我的原始问题,但现在我对为什么或如何将其强制转换为TextView感到困惑。

java android android-edittext android-custom-view
2个回答
2
投票

似乎您正在扩展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);
     }
});

0
投票

确保未设置inputType:'none'或'0X000000'

© www.soinside.com 2019 - 2024. All rights reserved.