【问题标题】:How to get Spinner inside ListView work in Android?如何让 ListView 内的 Spinner 在 Android 中工作?
【发布时间】:2013-03-26 18:27:50
【问题描述】:

我正在开发一个应用程序,其中我需要一个 ListView,它的行有一个 TextView、2 个 CheckBox 和一个 Spinner。

但是,我遇到了 Spinner 的 onItemSelected() 的问题,因为每次显示每一行时都会调用它。在这种方法中,我使用所选选项更新数据库记录,但由于 Android 会自动调用它,每次项目都会重置,因为 Android 使用位置 0 调用它,这是数据库中更新的值。

我已经阅读了很多关于onItemSelected() 问题的链接和一些技巧,但所有这些链接都是在没有 ListView 的情况下使用的。这里有什么要点吗?

我试图在列表中跟踪实际显示哪些位置以使其工作,但它没有。我认为这是因为 Android 中的回收导致调用了已显示的 Spinners 的故障排除方法!

所以重点是:我如何区分对onItemSelected() 的真实调用,因为在显示 Spinner 时用户选择了 Android 调用?

这是我扩展 SimpleCursorAdapter 的适配器的代码。

非常感谢您。

public ParticipationAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
    super(context, layout, c, from, to);
    mActivity = (Activity)context;
    ParticipationComment.ParticipationCommentManager commentManager = new ParticipationComment.ParticipationCommentManager(mActivity);
    mParticipationCommentsCursor = commentManager.get();
    mActivity.startManagingCursor(mParticipationCommentsCursor);
    commentManager.detach();
    mPositionsOfCursorIds = getPositionsOfCursorIds(mParticipationCommentsCursor);
    mSpinnerPositionsDisplayed = new ArrayList<Integer>();
}

@Override
public View getView(final int participationPosition, View convertView, ViewGroup parent) {
    final Cursor participationsCursor = getCursor();
    mActivity.startManagingCursor(participationsCursor);
    participationsCursor.moveToPosition(participationPosition);
    View participationRow;
    if (convertView == null) {
        participationRow = LayoutInflater.from(mActivity).inflate(R.layout.participation_row_student, null);
    } else {
        mSpinnerPositionsDisplayed.remove((Integer)convertView.getTag());
        participationRow = convertView;
    }
    participationRow.setTag(participationPosition);
    Spinner commentSpinner = (Spinner)participationRow.findViewById(R.id.participation_comment_id_spinner);
    SimpleCursorAdapter commentSpinnerAdapter = new SimpleCursorAdapter(
            mActivity,
            android.R.layout.simple_spinner_item,
            mParticipationCommentsCursor,
            new String[] {DatabaseManager.NAME},
            new int[] {android.R.id.text1}
    );
    commentSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    commentSpinner.setAdapter(commentSpinnerAdapter);
    long participationCommentId = participationsCursor.getLong(participationsCursor.getColumnIndex(DatabaseManager.PARTICIPATION_COMMENT_ID));
    if (participationCommentId != 0) {
        commentSpinner.setSelection(mPositionsOfCursorIds.get(participationCommentId));
    }
    commentSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            participationsCursor.moveToPosition(participationPosition);
            if (!mSpinnerPositionsDisplayed.contains(participationPosition)) {
                // Android calls this method the first time a Spinner is displayed,
                // to differentiate from a real user click we check if the current Spinner's position
                // in the ListView is being shown
                mSpinnerPositionsDisplayed.add(participationPosition);
            } else {
                ParticipationComment participationComment = new ParticipationComment((Cursor)parent.getItemAtPosition(position));
                Participation.ParticipationManager participationManager = new Participation.ParticipationManager(mActivity);
                Participation participation = new Participation(participationsCursor);
                participation.setConnectionProfileParticipationCommentId(participationComment.getConnectionProfileId());
                participation.setParticipationCommentId(participationComment.getIdOpenErp());
                participation.setChanged(true);
                participationManager.update(participation);
                participationManager.detach();
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
            // Not used
        }
    });
    TextView studentName = (TextView)participationRow.findViewById(R.id.participation_student_name);
    studentName.setText(participationsCursor.getString(participationsCursor.getColumnIndex(DatabaseManager.NAME)));
    CheckBox expectedPresent = (CheckBox)participationRow.findViewById(R.id.participation_expected_present_value);
    expectedPresent.setChecked(participationsCursor.getInt(participationsCursor.getColumnIndex(DatabaseManager.EXPECTED_PRESENT)) == 1);
    CheckBox present = (CheckBox)participationRow.findViewById(R.id.participation_present_value);
    present.setChecked(participationsCursor.getInt(participationsCursor.getColumnIndex(DatabaseManager.PRESENT)) == 1);
    return participationRow;
}

【问题讨论】:

    标签: android listview spinner


    【解决方案1】:

    更好的方法是使用 AlertDialog Variant.. 像 this.. 并创建一个按钮,该按钮最初将第一个选择作为其文本并根据 AlertDialog 选择进行更改..

    【讨论】:

    • 非常感谢您的回答!明天我会试试,对你说点什么!但我会改用public AlertDialog.Builder setCursor (Cursor cursor, DialogInterface.OnClickListener listener, String labelColumn),因为我在数据库表中有原始数据。我认为通过这种方法,我将能够允许用户不选择任何选项,这是我真正需要的,并且使用 Spinner 是不可能的。
    • 非常感谢!我终于按照您的建议使用按钮和 alertDialogs 在 ListView 中实现了选择。这很好用!我在对话框中使用了setSingleChoiceItems() 方法,因为它允许您定义默认选择。我已经投票并接受了你的回答,给你 +25 代表! :)
    • @Caumons .. 这是很好的补充...:)
    【解决方案2】:

    如果使用一个小标志来丢弃 ItemSelected 的第一次调用呢?

    【讨论】:

    • 我在哪里以及如何做到这一点?我没有想法...... :(我已经在跟踪显示位置的列表......所以,如果当前位置不存在并且调用onItemSelected(),那么它是由Android制作的,否则它是用户点击但是......似乎Android在已经显示时会想起它,这让我很受伤!我认为这是因为Android(convertView)完成的回收模式
    • 我认为每次创建或回收视图时都应该重置计数器(适配器的 getView 方法)。为每个视图保留一个计数器,在 getView 方法询问视图时将其重置。丢弃每个视图的第一个事件。
    • 我认为这种方法会帮我解决问题,因为我不知道回收是如何实现的以及我应该在哪里重置计数器。我将尝试@sandy 提出的其他解决方案,这似乎更容易。我一直认为谷歌男孩应该改进这种不受欢迎的方法行为......无论如何,谢谢! :)
    • @Snicolas:如何检查 ItemSelected 的第一次调用?
    • @lordzen 带有布尔标志。
    猜你喜欢
    • 2015-03-05
    • 1970-01-01
    • 2012-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多