Android程式設計權威指南(第2版)—第14章挑戰練習

魚香青椒絲發表於2017-09-10

14.8 挑戰練習:刪除Crime記錄

修改CrimeLab的deleteCrime方法

public void deleteCrime(Crime c) {
        //mCrimes.remove(c);

        mDatabase.delete(
                CrimeTable.NAME,
                CrimeTable.Cols.UUID + " = ?",
                new String[] { c.getId().toString() }
        );
    }

前面的練習都做了並修改程式新增新功能的同學會發現,直接修改這個deleteCrime方法,執行刪除後,app會意外終止,

RecyclerView 報IndexOutOfBoundsException。那是因為我們之前為了實現修改crime內容返回後,更新列表裡的單一crime而不是全部更新的程式碼報錯了

private void updateUI() {
        CrimeLab crimeLab = CrimeLab.get(getActivity());
        List<Crime> crimes = crimeLab.getCrimes();

        if (mAdapter == null) {
            mAdapter = new CrimeAdapter(crimes);
            mCrimeRecyclerView.setAdapter(mAdapter);
        } else {
            mAdapter.setCrimes(crimes);
            mAdapter.notifyDataSetChanged(); //全量更新
            //mAdapter.notifyItemChanged(mIndex); //單例更新 -- 此行報錯
        }

        if (crimes.size() != 0) {
            mNoCrimeTextView.setVisibility(View.INVISIBLE);
            mNoCrimeButton.setVisibility(View.INVISIBLE);
        } else {
            mNoCrimeTextView.setVisibility(View.VISIBLE);
            mNoCrimeButton.setVisibility(View.VISIBLE);
        }


        updateSubtitle();

    }

呼叫deleteCrime方法後,該Crime例項已經從資料庫中刪除了。

改回原來的notifyDataSetChanged()方法就不會報錯,但是會犧牲效率。

建議可以弄一個變數記錄是否為刪除動作,再根據判斷具體呼叫不同的更新方法。


相關文章