当键盘弹出并滚动ListView时,EditText保持焦点

4
我使用一个列表视图。列表中的每个项目都包含一个编辑框。当我点击一个编辑框时,软键盘弹出,我点击的编辑框会短暂地获得焦点,然后失去焦点。我必须再次点击才能真正获得焦点(为什么?)
(在编辑框上聚焦和打开键盘)我滚动列表视图...
由于列表视图元素被回收,焦点重新出现在列表中其他位置的编辑框上,我想这是正常的。但是,为什么Android不移除这该死的焦点呢?如果用户开始滚动,我该如何告诉Android我不再想在编辑框上聚焦?
以下是活动的代码:
public class SimpleList extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.user_picker);

    ListView listview = (ListView)this.findViewById(R.id.user_picker_list);
    new UserPickerAdapter(this, listview); 

}

适配器的代码如下:

public class UserPickerAdapter extends BaseAdapter {

private final LayoutInflater mInflater;

private String[] mUsers = {"Guib", "Jonas", "Fred", "Denis", "Arnold", "Francois", "David", "Alex", "Saskia", "Verner", "Anatole"};

public UserPickerAdapter(Context context, ListView listview) {

    mInflater = LayoutInflater.from(context);   
    listview.setAdapter(this);  

}

@Override
public int getCount() {
    return mUsers.length;
}

@Override
public Object getItem(int position) {
    return mUsers[position];
}

@Override
public long getItemId(int position) {
    return position;
}

static private class Holder {
    TextView username; 
}

@Override
public View getView(int position, View convertView, ViewGroup arg2) {

    Holder holder;  

    if (convertView != null) {  

        holder = (Holder) convertView.getTag(); 

    } else {    

        holder = new Holder();  
        convertView = mInflater.inflate(R.layout.user_picker_list_item,null);
        holder.username = (TextView) convertView.findViewById(R.id.user_picker_list_item_name);
        convertView.setTag(holder);

    }

    String str = (String)getItem(position);
    holder.username.setText(str);
    return convertView;

}

以防万一,在这里提供'user_picker.xml'的代码:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical" android:padding="0dp"><ListView android:background="@color/color_grey1" android:cacheColorHint="@color/color_grey1" android:id="@+id/user_picker_list" android:divider="@color/color_blueGrey1" android:layout_height="match_parent" android:layout_width="match_parent"/>

还有一个在'user_picker_list_item.xml'中。

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:orientation="vertical" android:layout_height="fill_parent"><EditText android:layout_height="wrap_content"android:id="@+id/user_picker_list_item_name" android:layout_width="wrap_content" android:minWidth="200dp" android:layout_gravity="center"></EditText></LinearLayout> 

4个回答

1
也许我来晚了,但我希望这能对某个人有所帮助。Sangeeth Kumar的答案是正确的方向,但需要在清单文件中添加另一行代码。
问题在于当软键盘弹出时,屏幕上的内容被强制滚动和调整大小。当ListView(或ExpandableListView)滚动时,所有视图都会重新渲染,因此,原来聚焦的项目行中的EditText字段对象现在是完全不同的对象。
因此,要解决这个问题,您需要添加两行代码:
  1. 将以下行添加到ListView项XML中:

    android:descendantFocusability =“beforeDescendants”

  2. 将以下行添加到包含ListView(或ExpandableListView)的活动标记中,该标记位于应用程序的清单文件中

    android:windowSoftInputMode =“adjustPan”

希望这可以帮助您 :)

1

我尝试了Gilbou的解决方案,但它对我没有用,因为我在所有行中都有EditTexts。但通过一些更改,我可以使其正常工作:

EditText currentEdit;

public View getView(int q, View convertView, ViewGroup parent) {

    ViewHolder holder;

    if (convertView==null) {

        convertView = (LinearLayout)inflater.inflate(R.layout.grade_row, null);

        holder = new ViewHolder();
        //Inflate holder
        convertView.setTag(holder);     
    } else {
        holder = (ViewHolder)convertView.getTag();
    }

    if (listView.getSelectedItemPosition() == ListView.INVALID_POSITION) {
        if (currentEdit!=null)
            currentEdit.requestFocus();
    }

    //update row items

    return convertView;
}

此外,在列表视图中的每个EditText上添加焦点变化监听器:
myEditText.setOnFocusChangeListener(new OnFocusChangeListener() {  

    public void onFocusChange(View v, boolean hasFocus) {
        if(!hasFocus) 
            currentEdit = myEditText;
    }
}

请问您能否添加您的适配器getView代码以便处理它? - Shreyash Mahajan

0

我想我找到了解决方案...

我将适配器中getView()方法的一部分代码替换为以下内容:

if (convertView != null) {
   holder = (Holder) convertView.getTag();
   if (((ListView)arg2).getSelectedItemPosition() == ListView.INVALID_POSITION) {
      arg2.requestFocus();
   }
}

0

你需要添加

XML中:

android:descendantFocusability="afterDescendants"

Java中:

listView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);

我认为它可以工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接