Android 如何在 ListItem 中使用 EditText 实现可选择的 ListView

How to implement selectable ListView with EditText in ListItem in Android

我正在尝试实现一个自定义列表视图,其中包含带有微调器和编辑文本的列表项。并且列表项需要是可选择的,列表项中的编辑文本也需要是可编辑的。但问题是当我使用 setFocusable(true) 将 edittext 设置为可编辑时,列表项不可选择,而当我使用 setFocusable(false) 将 edittext 设置为不可编辑时,列表项是可选择的。有谁知道如何解决这个问题?

下面是我的代码

@Override
public View getView(int position, View convertView, ViewGroup parent) {
  View listItemView = convertView;

  if (listItemView == null) {
    listItemView = inflater.inflate(R.layout.listitem, null);
    ViewHolder viewHolder = new ViewHolder();
    viewHolder.view1 = (Spinner) listItemView.findViewById(R.id.view1);
    viewHolder.view2 = (EditText) listItemView.findViewById(R.id.view2);

    viewHolder.view1.setFocusable(false);
    viewHolder.view2.setFocusable(false);

    viewHolder.view1.setAdapter(view1Adapter);
    viewHolder.view1.setOnItemSelectedListener(this);

    viewHodler.view2.setOnFocusChangeListener(this);

    listItemView.setTag(viewHolder);
  }

  CustomListItem item = listViewItemList.get(position);
  ViewHolder viewHolder = listItemView.getTag();
  viewHolder.view1.setSelection(item.view1Value);
  viewHolder.view1.setTag(item);
  viewHolder.view2.setText(item.view2Value);
  viewHolder.view2.setTag(item);

  return listItemView;
}

===== 已更新以添加 xml =====

下面是我的 xml 列表视图和项目文件。

对于列表视图。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#FFFFFF"
tools:context="namespace">

  <FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1">
    <ListView android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:listSelector="#AAAAAA"
        android:background="#FFFFFF"
        android:descendantFocusability="beforeDescendants" />
    <TextView android:id="@android:id/empty" android:layout_width="match_parent"
        android:layout_height="match_parent" android:gravity="center"
        android:text="@string/empty"/>
  </FrameLayout>

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <Button
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:text="@string/add"
        android:id="@+id/btn_add" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:text="@string/delete"
        android:id="@+id/btn_delete" />
  </LinearLayout>
</LinearLayout>

对于列表项。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"
android:weightSum="3">

<Spinner
    android:id="@+id/view1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1" />

<EditText
    android:id="@+id/view2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/empty"
    android:layout_weight="2"
    android:textSize="15sp"
    android:inputType="number" />

</LinearLayout>
<LinearLayout
android:descendantFocusability="beforeDescendants"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
<Spinner
    android:id="@+id/view1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1" />

<EditText
    android:id="@+id/view2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/empty"
    android:layout_weight="2"
    android:textSize="15sp"
    android:inputType="number" />

</LinearLayout>

最后我找到了这个需求的解决方案,但是它需要一点代码才能工作,这与我最初的预期不同。

下面是我的列表适配器的代码块,它实现了 AdapterView.OnItemSelectedListenerView.OnFocusChangeListenerView.OnTouchListener

private EditText activatedEditText;

@Override
public View getView(int position, View convertView, ViewGroup parent) {
  View listItemView = convertView;

  if (listItemView == null) {
    listItemView = inflater.inflate(R.layout.listitem, null);
    ViewHolder viewHolder = new ViewHolder();
    viewHolder.view1 = (Spinner) listItemView.findViewById(R.id.view1);
    viewHolder.view2 = (EditText) listItemView.findViewById(R.id.view2);

    viewHolder.view1.setFocusable(false);
    viewHolder.view2.setFocusable(false);

    viewHolder.view1.setOnTouchListener(this);
    viewHolder.view2.setOnTouchListener(this);

    viewHolder.view1.setAdapter(view1Adapter);
    viewHolder.view1.setOnItemSelectedListener(this);

    viewHodler.view2.setOnFocusChangeListener(this);

    listItemView.setTag(viewHolder);
  }

  CustomListItem item = listViewItemList.get(position);
  ViewHolder viewHolder = listItemView.getTag();
  viewHolder.view1.setSelection(item.view1Value);
  viewHolder.view1.setTag(item);
  viewHolder.view2.setText(item.view2Value);
  viewHolder.view2.setTag(item);

  return listItemView;
}

@Override
public boolean onTouch(View v, MotionEvent event) {
  if(v.getClass() == EditText.class) {
    activatedEditText = (EditText)v;
    activatedEditText.setFocusable(true);
    activatedEditText.setFocusableInTouchMode(true);
    activatedEditText.requestFocus();
  }
  else {
    activatedEditText.clearFocus();
    activatedEditText.setFocusable(false);
    activatedEditText.setFocusableInTouchMode(false);

    InputMethodManager imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(activatedEditText.getWindowToken(), 0);
  }
}