0

ListFragment にアイテムを表示するアプリを構築しています。現在、各アイテムにはタイトルと作成日が表示されています。他に 2 つのフラグメントがあります。アイテムを作成し、タイトルを編集できる EditText フィールドを持つもの。もう 1 つは、個々の項目の内容を単純に表示するものです。

私が抱えている問題は、EditText フィールドに文字を入力するたびにアプリが閉じてしまうことです。エラー メッセージは、TextChangedListener の onTextChanged でエラーが発生したことを示しています。すべてをJSONファイルとして保存しているときにこの機能が機能していたため、データベースを更新し、モデルレイヤーを更新しているためにエラーが発生する必要があります。

このファイルは、すべてのデータベース操作を実行し、カスタム カーソルを作成します。

public class SnapDatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "FeedFragment";

private static final String DB_NAME = "snap.sqlite";
private static final int VERSION = 1;

private static final String TABLE_SNAP = "snap";

private static final String COLUMN_SNAP_ID = "_id";
private static final String COLUMN_SNAP_DATE = "snap_date";
private static final String COLUMN_SNAP_UUID = "snap_uuid";
private static final String COLUMN_SNAP_TITLE = "snap_title";

public SnapDatabaseHelper(Context context){
    super(context, DB_NAME, null, VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
    // Create SNAP table
    db.execSQL("create table snap(" + 
    "_id integer primary key autoincrement, " +
    //"snap_uuid text, " +
    "snap_date integer, " +
    "snap_title text) ");
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // 
}

public long insertSnap(Snap snap){
    ContentValues cv = new ContentValues();
    //cv.put(COLUMN_SNAP_UUID, snap.getUniqueId().toString());
    cv.put(COLUMN_SNAP_DATE, snap.getDate().getTime());
    cv.put(COLUMN_SNAP_TITLE, "");
    return getWritableDatabase().insert(TABLE_SNAP, null, cv);

}
public boolean updateTitle(long snapId, String text)
{
 ContentValues cv = new ContentValues();
 cv.put(COLUMN_SNAP_ID, snapId);          
 cv.put(COLUMN_SNAP_TITLE, text);

 int i= getWritableDatabase().update(TABLE_SNAP, cv, COLUMN_SNAP_ID+ "=" + snapId, null);
 return i>0;
}
 public SnapCursor querySnap(long id) {
        Cursor wrapped = getReadableDatabase().query(TABLE_SNAP, 
                null, // all columns 
                COLUMN_SNAP_ID + " = ?", // look for a run ID
                new String[]{ String.valueOf(id) }, // with this value
                null, // group by
                null, // order by
                null, // having
                "1"); // limit 1 row
        return new SnapCursor(wrapped);
 }
 public SnapCursor querySnaps() {
        // equivalent to "select * from run order by start_date asc"
        Cursor wrapped = getReadableDatabase().query(TABLE_SNAP,
                null, null, null, null, null, COLUMN_SNAP_DATE + " asc");
        return new SnapCursor(wrapped);
    }

public static class SnapCursor extends CursorWrapper{
    public SnapCursor(Cursor c){
        super(c);
    }
    public Snap getSnap() {
        if (isBeforeFirst() || isAfterLast())
            return null;

        Snap s = new Snap();
        s.setId(getLong(getColumnIndex(COLUMN_SNAP_ID)));
        //s.setUniqueId(UUID(getString(getColumnIndex(COLUMN_SNAP_UUID))));
        s.setDate(new Date(getLong(getColumnIndex(COLUMN_SNAP_DATE))));
        s.setTitle(getString(getColumnIndex(COLUMN_SNAP_TITLE)));
        return s;
    }
}

}

このファイルは、フラグメントを DatabaseHelper にリンクします。

public class SnapLab {

private static SnapLab sSnapLab;
private Context mAppContext;
private SnapDatabaseHelper mHelper;

// private constructor
private SnapLab(Context appContext){
    mAppContext = appContext;
    mHelper = new SnapDatabaseHelper(mAppContext);
}
public static SnapLab get(Context c){
    if(sSnapLab == null){
        sSnapLab = new SnapLab(c.getApplicationContext());
    }
    return sSnapLab;
}
public Snap insertSnap() {
    Snap s = new Snap();
    s.setId(mHelper.insertSnap(s));

    return s;
}
public boolean updateTitle(long snapId, String text){


    return  mHelper.updateTitle(snapId, text);

}

public SnapCursor querySnaps() {
    return mHelper.querySnaps();
}

public Snap getSnap(long id) {
    Snap s = null;
    SnapCursor cursor = mHelper.querySnap(id);
    cursor.moveToFirst();
    // if we got a row, get a run
    if (!cursor.isAfterLast())
        s = cursor.getSnap();
    cursor.close();
    return s;
}

}

EditText フィールドを含むフラグメントを次に示します。

public class EditPageFragment extends Fragment {
private static final String TAG = "EditPageFragment";
public static final String EXTRA_SNAP_ID = "SNAP_ID";

private SnapLab mSnapLab;
private Snap mSnap;
private SnapDatabaseHelper mHelper;
private EditText mSnapText;
private Button mUploadButton;
private TextView mDateText;
private Long snapId;

public static EditPageFragment newInstance(Long snapId){
    Bundle args = new Bundle();
    args.putLong(EXTRA_SNAP_ID, snapId);
    EditPageFragment fragment = new EditPageFragment();
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);
    mSnapLab = SnapLab.get(getActivity());

    Bundle args = getArguments();
    if (args != null){
        long snapId = args.getLong(EXTRA_SNAP_ID, -1);
        if (snapId != -1){
            mSnap = mSnapLab.getSnap(snapId);
        }
    }
    mSnap = new Snap();
    mSnap = mSnapLab.insertSnap();
}   

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle   savedInstanceState){
    View v = inflater.inflate(R.layout.edit_fragment, parent, false);


    mDateText = (TextView)v.findViewById(R.id.edit_dateText);
    mDateText.setText(mSnap.getDate().toString());

    mSnapText = (EditText)v.findViewById(R.id.edit_snapText);
    mSnapText.addTextChangedListener(new TextWatcher(){
        @Override
        public void afterTextChanged(Editable s) {
            //leave blank for now
        }
        @Override
        public void beforeTextChanged(CharSequence c, int start, int count,
                int after) {
            //leave blank for now
        }
        @Override
        public void onTextChanged(CharSequence c, int start, int before,
                int count) {
            mSnap.setTitle(c.toString());
            mSnapLab.updateTitle(snapId, c.toString());

            Log.i(TAG, "text saved");
        }
    });

    return v;
}
}

コードのインポート部分は updateTitle() 関数です。私は何が間違っているのでしょうか。データベースをより適切に更新する方法についての提案はありますか。タイトルの更新を除いて、すべてがうまく機能します。少しでもお役に立てば幸いです。

4

1 に答える 1

0

snapId が割り当てられていないようです

private Long snapId; //field

数行後

long snapId = args.getLong(EXTRA_SNAP_ID, -1); //local variable

数行後

mSnapLab.updateTitle(snapId, c.toString()); //field

次回はスタックトレースを追加してください。

于 2013-10-24T14:34:48.460 に答える