在ListView(Android)中关注EditTexts的问题

时间:2014-10-23 00:10:42

标签: android android-layout listview android-listview android-edittext

我有一个ListView,每个项目都有一些EditTexts。我对硬件键盘没有任何问题,但软键盘让人感觉不舒服。我有两个问题。

  1. 当我第一次点击EditText时,它会暂时显示焦点,但一旦键盘显示就会失去焦点。然后,我必须再次单击EditText以获得焦点。
  2. 当焦点的EditText滚动到视图外时,焦点转到......嗯...请参阅屏幕截图。我不确定发生了什么。
  3. 关于#1的更多细节:

    • 当屏幕首次加载时,焦点位于“Gr High School Scale”字段,但键盘未显示。
    • 如果我立即点击所需的EditText,其OnFocusChangeListener会告诉我它会获得焦点然后失去焦点。在视觉上,我看到光标出现在字段中,但是当键盘加载时光标跳开(如截图中所示)并且我不知道焦点在哪里。

    我已经玩了一下ListView的Focusable和DescendantFocusability属性,但无济于事。有什么建议?

    每次将焦点的EditText滚动到视图外时,会显示另一个醉酒光标: enter image description here

    更新:相关代码。
    使用ListView XML的活动布局:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res/com.NsouthProductions.gradetrackerpro"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.NsouthProductions.gradetrackerpro.Activity_EditCourseGPA" >
    
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="34dp"
        android:text="Define the GPA and Percent scale for this course." />
    
    <RadioGroup
        android:id="@+id/radioGroup1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/textView1"
        android:layout_marginLeft="5dp" >
    
        <LinearLayout
            android:id="@+id/linlay_rad_group_existing_scale"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
    
            <RadioButton
                android:id="@+id/radio0_existing_scale"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="0"
                android:checked="true"
                android:text="Existing Scale" />
    
            <Spinner
                android:id="@+id/spinner_existing_scales"
                android:layout_width="wrap_content"
                android:layout_height="33dp"
                android:layout_gravity="right"
                android:layout_weight="1" />
    
        </LinearLayout>
    
        <LinearLayout
            android:id="@+id/linlay_rad_group_new_scale"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
    
            <RadioButton
                android:id="@+id/radio1_new_scale"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="0"
                android:text="New Scale" />
    
            <TextView
                android:id="@+id/textView2"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:lines="1"
                android:maxLines="1"
                android:text=" " />
    
            <EditText
                android:id="@+id/editText1"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:inputType="textPersonName"
                android:maxLines="1"
                android:scrollHorizontally="true"
                android:text="Gr High School Scale" >
    
                <requestFocus />
            </EditText>
    
        </LinearLayout>
    </RadioGroup>
    
    
     <LinearLayout
        android:id="@+id/linlay_scale_save_buttons"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true" >
    
        <Button
            android:id="@+id/btn_gpa_cancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button" />
    
        <Button
            android:id="@+id/btn_gpa_save"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button" />
    
    </LinearLayout>
    
     <ListView
         android:id="@+id/listview_scale"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_above="@id/linlay_scale_save_buttons"
         android:layout_alignParentLeft="true"
         android:layout_below="@id/radioGroup1"
         android:focusable="true"
         android:focusableInTouchMode="true"
         android:headerDividersEnabled="true"
         android:scrollingCache="true" >
    
     </ListView>
    

    列出项目XML:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linlay_scale_list_item"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >
    
            <CheckBox
                    android:id="@+id/checkbox_scale_item"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="A-" />
    
                <EditText
                    android:id="@+id/et_gpa"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:enabled="true"
                    android:inputType="numberDecimal"
                    android:maxLength="6"
                    android:text="4.000" />
    
                <EditText
                    android:id="@+id/et_min"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:enabled="true"
                    android:inputType="numberDecimal"
                    android:maxLength="6"
                    android:text="94.75" />
    
                <EditText
                    android:id="@+id/et_max"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:inputType="numberDecimal"
                    android:maxLength="6"
                    android:text="100.0" />
    

    在我的适配器中设置视图:

    View v = convertView;
    ViewHolder holder;
    
        v = inflater.inflate(R.layout.scale_list_item, 
        holder = new ViewHolder();
        holder.cb = (CheckBox) v.findViewById(R.id.checkbox_scale_item);
        holder.et_gpa = (EditText) v.findViewById(R.id.et_gpa);
        holder.et_min = (EditText) v.findViewById(R.id.et_min);
        holder.et_max = (EditText) v.findViewById(R.id.et_max);
    

    我不确定还有什么要发布的。我有焦点和textChange监听器,但即使这些被注释掉,问题仍然存在。如果还有其他需要,请告诉我。谢谢。

    有关触摸EditText时焦点的行为的详细信息:

    1. 单击(触摸)EditText
    2. EditText获得焦点
    3. EditText失去焦点
    4. ListView获得焦点(并尝试设置子焦点视图requestChildFocus ...似乎没有成功)。
    5. ListView失去焦点
    6. ListView获得焦点(并尝试再次设置子焦点)。
    7. 以上内容基于EditText和ListView的监听器。 注意:使用硬件键盘,EditText会获得焦点,就是这样。我认为出现的软键盘会影响焦点。

      最终更新:最后,使用ListView太困难了,特别是因为我想根据对一行中EditText的更改来更新多行。当键盘启动时,这很难做到,ListView只会在任何时候考虑一​​些行。

      我改为使用嵌套的LinearLayouts。每个水平布局都是一个“行”,我将它们放在一个ArrayList中以便管理它们,这是一块蛋糕,相对来说(仍然不容易)。

2 个答案:

答案 0 :(得分:5)

您正面临ListView回收问题。当您向上或向下滚动或键盘出现时ListView再次刷新并失去EditText's焦点。所以,首先阅读this answer to understand ListView Recycling mechanism,然后在我的脑海中按照我方面的建议解决您当前的情况。

我建议您在Button上使用ListView项目,此按钮的文字应该是通用的,例如输入学生信息或您喜欢的内容。点击此Button打开AlertDialog并设置您的xml视图(目前您的所有edittexts,例如listview项目上的et_gpa,et_min,et_max等

例如:

btnInfo.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {

                showStudentInfoAlert();

}

});

public void showStudentInfoAlert() 
    {
        AlertDialog.Builder builder = new AlertDialog.Builder(context);

       LayoutInflater in = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

View v = in.inflate(R.layout.your_xml_having_edittexts, null);

EditText et_gpa = (EditText) v.findViewById(R.id.et_gpa);

//add all edit texts like this and after that just set view on alert dialog

        builder.setTitle("Enter student's info");

        builder.setView(v);

        builder.setPositiveButton("Save", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {

               //save all edittexts values and do what erver you want with those values 

            }
        });

        dialog.show();
    }

答案 1 :(得分:2)

首先,当屏幕加载时,重点放在&#34; Gr High School Scale&#34;字段,因为xml中有<requestFocus />。但这并不保证键盘可能会显示..使键盘显示使用getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); 另外我认为它会立即失去焦点,因为listview已经将注意力从edittext

上移开
<ListView
 android:id="@+id/listview_scale"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:layout_above="@id/linlay_scale_save_buttons"
 android:layout_alignParentLeft="true"
 android:layout_below="@id/radioGroup1"
 android:focusable="true" //this
 android:focusableInTouchMode="true" // and that
 android:headerDividersEnabled="true"
 android:scrollingCache="true" >

,因为你的listview edittext都没有要求聚焦,所以焦点只停留在listview而不是edittext上。所以你需要将焦点重新表现回edittext ..而且还要从android文档中找到它陈述 By default the user can not move focus to a view; ..并说明"if focusableInTouchMode is true for a view, that view can gain focus when clicked on, and can keep focus if another view is clicked on that doesn't have this attribute set to true. " 大多数情况下,当您第一次创建一个edittext时,它会自动向其添加<requestFocus />,指定它需要聚焦,或者它可以采取焦点..但在您的情况下,使用此文档,edittext将永远不会保持焦点,因为listview正在采取它远离他..所以简而言之,试试这个所有视图(包括你的编辑文本)你想要像在listview上那样关注焦点

android:focusable="true" 
android:focusableInTouchMode="true" 

所以在edittext上尝试一下,让我知道它是否有帮助......感谢等待