0

更新:Galaxy S2(デバッグモードの有無にかかわらず)で毎回この問題を再現できますが、エミュレータでは決して再現できません!

ListView(のカスタム実装を使用する)のコンテキストメニューを使用して、ユーザーが「すべて削除CursorAdapter」オプションを選択できるようにしています。このオプションを選択すると、リストに表示されるすべての項目がデータベースから完全に削除され、続いてアダプタで が呼び出され、リストが強制的に更新されます。changeCursor(..)

ただし、データベースからレコードを削除して を呼び出した後でもchangeCursor(..)、アイテムは表示されます。アイテムの仕切りだけが消えます。リストのどこかに触れた後でのみ、これらのアイテムはクリアされます。

ユーザーがコンテキスト メニューをアクティブにすると: http://i.stack.imgur.com/ivFvJ.png

データベースから削除して呼び出した後changeCursor(..): http://i.stack.imgur.com/CX6BM.png

ListView (スクロール中に Android ListView アイテムが重なる) に別の問題があり、同じ ListView を使用しているので、問題が関連している可能性がありますか? ListViewデータベースの更新後に再描画を強制する手順はありますか? それとも、ソリューションの実装方法が間違っているために自動的に発生していませんか? 前もって感謝します!

の XML は次のとおりです。ListView

<ListView
        android:id="@+id/all_reminders_list"
        android:paddingLeft="4dp"
        android:paddingRight="4dp"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:layout_alignParentLeft="true"
        android:clickable="true"
        android:dividerHeight="1.0sp"
        android:animateLayoutChanges="true">

newView(..)私のカスタム方法はこちらCursorAdapter

public View newView(Context context, Cursor cursor, ViewGroup parent) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View view = inflater.inflate(R.layout.view_list_item, parent, false);
    return view;
}

私のbindView(..)方法はCursorAdapter

public void bindView(View view, Context context, Cursor cursor) {

        TextView whatTextView = (TextView) view.findViewById(R.id.item_what_text);
        whatTextView.setText(cursor.getString(1));
        TextView whenTextView = (TextView) view.findViewById(R.id.item_when_text);


        if(cursor.getInt(9) != 0) // DONE_FLAG = 1 (completed)
        {
            //Arrow visibility
            ImageView arrow = (ImageView)view.findViewById(R.id.list_item_arrow);
            arrow.setVisibility(View.INVISIBLE);

            //Text color
            whatTextView.setTextColor(Color.LTGRAY);
            whenTextView.setTextColor(Color.LTGRAY);

            //WHEN text
            whenTextView.setText(TimeCalculationHelper.getCompletedTimeString(cursor.getLong(2)));
        }
        else // DONE_FLAG = 0
        {
            //Arrow visibility
            ImageView arrow = (ImageView)view.findViewById(R.id.list_item_arrow);
            arrow.setVisibility(View.VISIBLE);

            //Text color
            whatTextView.setTextColor(Color.BLACK);
            whenTextView.setTextColor(Color.BLACK);

            //WHEN text
            whenTextView.setText(TimeCalculationHelper.getTimeRemainingString(cursor.getLong(2)));


        }
}

を含むからの私のonContextItemSelected(..)メソッドは次のとおりですActivityListView

public boolean onContextItemSelected(MenuItem item)
    {
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
        ListView allRemindersList = (ListView)findViewById(R.id.all_reminders_list);

        switch (item.getItemId()) {
        case R.id.delete_item:
            //Delete the selected reminder from the database
            databaseHelper.deleteRowByID(info.id);

            //Refresh the main activity list
            ((ActiveRemindersAdapter) allRemindersList.getAdapter()).changeCursor(databaseHelper.getAllRemindersForList());
            return true;

        case R.id.delete_done:
            //Delete all reminders with DONE_FLAG = 1
            databaseHelper.deleteDoneReminders();

            //Refresh the main activity list
            ((ActiveRemindersAdapter) allRemindersList.getAdapter()).changeCursor(databaseHelper.getAllRemindersForList());
        }
        return false;
    }
4

1 に答える 1

1

カーソルを変更した後、アダプタでnotifyDataSetChanged()を呼び出して、ビューをリロードします。また、ハニカム前のデバイスを実行している場合は、 SupportLibraryのCursorAdapterを使用することをお勧めします。

コードを調べたところです。新しいコンテンツオブザーバーを自動的に登録し、notifyDataSetChanged()を呼び出すswapCursor ()を使用することをお勧めします。

CursorAdapterのソースコードから。

/**
 * Change the underlying cursor to a new cursor. If there is an existing cursor it will be
 * closed.
 * 
 * @param cursor The new cursor to be used
 */
public void changeCursor(Cursor cursor) {
    Cursor old = swapCursor(cursor);
    if (old != null) {
        old.close();
    }
}

/**
 * Swap in a new Cursor, returning the old Cursor.  Unlike
 * {@link #changeCursor(Cursor)}, the returned old Cursor is <em>not</em>
 * closed.
 *
 * @param newCursor The new cursor to be used.
 * @return Returns the previously set Cursor, or null if there wasa not one.
 * If the given new Cursor is the same instance is the previously set
 * Cursor, null is also returned.
 */
public Cursor swapCursor(Cursor newCursor) {
    if (newCursor == mCursor) {
        return null;
    }
    Cursor oldCursor = mCursor;
    if (oldCursor != null) {
        if (mChangeObserver != null) oldCursor.unregisterContentObserver(mChangeObserver);
        if (mDataSetObserver != null) oldCursor.unregisterDataSetObserver(mDataSetObserver);
    }
    mCursor = newCursor;
    if (newCursor != null) {
        if (mChangeObserver != null) newCursor.registerContentObserver(mChangeObserver);
        if (mDataSetObserver != null) newCursor.registerDataSetObserver(mDataSetObserver);
        mRowIDColumn = newCursor.getColumnIndexOrThrow("_id");
        mDataValid = true;
        // notify the observers about the new cursor
        notifyDataSetChanged();
    } else {
        mRowIDColumn = -1;
        mDataValid = false;
        // notify the observers about the lack of a data set
        notifyDataSetInvalidated();
    }
    return oldCursor;
}
于 2013-02-07T11:19:34.580 に答える