【问题标题】:keyboard reset radiogroup value键盘重置无线电组值
【发布时间】:2013-01-28 00:26:27
【问题描述】:

我有一个自定义 ListView,每行都有一个 radiogroup。 当我更改选中的单选按钮时,我会调用一个带有一些编辑文本字段的对话框(使用 onCheckedChanged() 方法)。但是,当我专注于一个编辑文本来写东西时,我丢失了所有被键盘覆盖的选中单选按钮,并且该组返回到选择的默认选项。 有人可以帮我吗?

列表适配器

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    ContractItemHolder cih = new ContractItemHolder();
    if (row == null){
        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
        row = inflater.inflate(R.layout.row_proposals_item, parent, false);
        cih.setTvItemTitle((TextView)row.findViewById(R.id.textViewItemTitle));
        cih.setRgItemStatus((RadioGroup)row.findViewById(R.id.radioGroupStatus));

        row.setTag(cih);
    }else {
        cih=(ContractItemHolder)row.getTag();
    }
    final ContractItem ci = list.get(position);
    cih.getRgItemStatus().setOnCheckedChangeListener(new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            groupSel = group;
            int selected = group.getCheckedRadioButtonId();
            Dialog d;
            switch (selected) {
            case R.id.radioAccepted:
                d = createDialog(context, ACCEPTED_CODE, ci, selected);
                d.show();
                break;
            case R.id.radioRefused:
                d = createDialog(context, REFUSED_CODE, ci, selected);
                d.show();
                break;
            default:
                break;
            }
        }
    });
    cih.getTvItemTitle().setText(ci.getDescItem());
    return row;
}

列表项布局(行..)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="5dp" 
    android:gravity="center">

    <TextView
        android:id="@+id/textViewItemTitle"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Large Text"
        android:layout_weight="3"
        android:textAppearance="?android:attr/textAppearanceLarge"/> 

    <RadioGroup
        android:id="@+id/radioGroupStatus"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:orientation="horizontal"
        android:layout_weight="1"
        android:showDividers="middle">

        <RadioButton
            android:id="@+id/radioNull"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Non Proposto" 
            android:checked="true"
            android:textAppearance="?android:attr/textAppearanceLarge"/>

        <RadioButton
            android:id="@+id/radioPending"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="In trattativa" 
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textColor="@color/Blue"/>

        <RadioButton
            android:id="@+id/radioAccepted"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Accettato" 
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textColor="@color/Green"/>

        <RadioButton
            android:id="@+id/radioRefused"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Rifiutato" 
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textColor="@color/Red"/>

    </RadioGroup> 

</LinearLayout>

对话框实现

private Dialog createDialog(Context context, final int code, ContractItem item,final int selected){ //type: refused, accepted
    d = new Dialog(context);
    d.setTitle(item.getDescItem());
    d.setContentView(R.layout.layout_dialog_prop);
    d.getWindow().setLayout(900, LayoutParams.WRAP_CONTENT);
    d.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);

    Button btnOK = (Button)d.findViewById(R.id.buttonPropOK);
    Button btnCancel = (Button)d.findViewById(R.id.buttonPropCancel);
    btnCancel.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            d.dismiss();
        }
    });
    btnOK.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            d.dismiss();

        }
    });
    return d;
}

对话框布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="50dp" >

        <EditText
            android:id="@+id/editTextDiscount"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:ems="10"
            android:hint="Sconto proposto"
            android:inputType="number"
            android:textAppearance="?android:attr/textAppearanceLarge" >

            <requestFocus />
        </EditText>

        <Spinner
            android:id="@+id/spinnerScuse"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:visibility="gone" />

        <EditText
            android:id="@+id/editText1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="30dp"
            android:ems="10"
            android:gravity="top"
            android:hint="Note"
            android:inputType="textMultiLine"
            android:textAppearance="?android:attr/textAppearanceLarge" />
    </LinearLayout>

    <View
        android:id="@+id/view2"
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:layout_marginTop="30dp"
        android:background="@android:color/holo_blue_light" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/buttonPropCancel"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@android:color/transparent"
            android:text="Annulla"
            android:textColor="@android:color/holo_blue_light" />

        <View
            android:id="@+id/view1"
            android:layout_width="1dp"
            android:layout_height="match_parent"
            android:background="@android:color/holo_blue_light" />

        <Button
            android:id="@+id/buttonPropOK"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@android:color/transparent"
            android:text="Ok"
            android:textColor="@android:color/holo_blue_light" />

    </LinearLayout>

</LinearLayout>

【问题讨论】:

  • 发布您的 ListAdapter 实现、列表项布局 XML 文件以及可能的 Dialog 实现及其布局。你也熟悉列表项视图回收的概念吗?
  • 我添加了代码。对于第二个问题,不,我不熟悉列表项视图回收的概念。

标签: android listview keyboard radio-button radio-group


【解决方案1】:

您已部分了解列表项视图回收过程。

ListView 组件不会为列表中的每个项目生成视图。所以,在你的情况下不会有15。屏幕上将有尽可能多的内容。当您滚动列表时,不再可见的旧项目被回收。然后用convertView != null 调用getView,适配器为您提供了更新这个回收项目视图的机会。这样做是出于性能原因 - 想象一下一个具有 10000 个项目的适配器(在商业应用中并不罕见)。它应该创建所有 10000 个列表项视图吗?想象一下滚动这样一个列表时的性能......

在您的 getView() 代码中,您只更新了部分项目视图 - 您始终在此行中设置项目标题:

cih.getTvItemTitle().setText(ci.getDescItem());

当创建一个新的项目视图(即convertView == null)时,单选组有一个默认选择,这在您的情况下可能没问题。

但是,当项目视图被回收时(即convertView != null),那么你:

  • 在这一行设置一个更改监听器:

    cih.getRgItemStatus().setOnCheckedChangeListener(...);
    
  • 设置项目标题:

    cih.getTvItemTitle().setText(ci.getDescItem());
    

但您从未设置选中的单选组项目。这意味着,它将有一个最后为该项目视图实例设置的值 - 不是为那个位置。您应该存储该信息 - 可能在 ContractItem 中,在选择无线电组项目时更新它,最后 - 在 convertView != null 时检索它并将无线电组的选定项目设置为正确的值。

当您打开一个对话框时,您可能会看到这个缺陷——ListView 的可见区域随着软键盘的打开而变小。这会导致ListView 删除不必要的(技术上:不再可见)项目视图。当您隐藏软键盘时,ListView 区域再次变大,从而导致它创建缺少的项目视图。不幸的是,您没有保存和恢复单选组的最后一个选定项目,因此在创建新可见项目后,在单选组中选择了默认项目。

【讨论】:

  • 我知道问题出在哪里,现在我可以解决了。但是在仔细查看了我的布局设计之后,我最终决定放弃在列表中包含 4 个单选按钮的想法,因为这是一个非常糟糕的布局:D 所以,我将使用 android 设计的 Multi-Pane 实现。谢谢你的帮助!!
猜你喜欢
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 2015-10-26
  • 1970-01-01
  • 1970-01-01
  • 2012-04-21
  • 1970-01-01
  • 2014-04-23
相关资源
最近更新 更多