Resposta alternativa
A seguir está o código para um exemplo bem básico, mas funcional. No entanto, vai um pouco mais longe ao incorporar um ListView e permitir a exclusão por LongClicking em um item na ListView .
No entanto, isso não usa fragmentos.
Há 3 partes de código, a MainActivity (
MainActivity.java
), A subclasse SQLiteOpenHelper CrimeDBHelper (CrimeDBHelper.java
) e o layout da MainActivity, activity_main.xml
:- activity_main.xml
Isso é bem direto. Observe que ele inclui um ListView no final.
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="The Crime Thing"
android:layout_gravity="center"
android:textStyle="bold"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="Crime Title"
/>
<EditText
android:id="@+id/crimetitle"
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="Crime Date"
/>
<EditText
android:id="@+id/crimedate"
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="Suspect"
/>
<EditText
android:id="@+id/crimesuspect"
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="Crime Solved?"
/>
<CheckBox
android:id="@+id/crimesolved"
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="wrap_content" />
</LinearLayout>
<Button
android:id="@+id/addcrime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ADD CRIME"/>
<Button
android:id="@+id/dltcrime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="DLT CRIME (ID=?)"/>
<ListView
android:id="@+id/crimelist"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
CrimeDBHelper.java
A maioria é semelhante, exceto o método adicional
getCrimeList()
, isso retorna um Cursor que contém todos os dados da tabela de crimes (usada para preencher o ListView). public class CrimeDBHelper extends SQLiteOpenHelper {
public static final String DBNAME = "crimesdb";
public static final int DBVERSION = 1;
public static final String CRIMESTABLE = "crimes";
public static final String CRIMEID_COL = "_id";
public static final String CRIMETITLE_COL = "crimetitle";
public static final String CRIMEDATE_COL = "crimedate";
public static final String CRIMESUSPECT_COL = "crimesuspect";
public static final String CRIMESOLVED_COL = "crimesolved";
public static final String TABLECRTSQL =
"CREATE TABLE " + CRIMESTABLE + "(" +
CRIMEID_COL + " INTEGER PRIMARY KEY," +
CRIMETITLE_COL + " TEXT," +
CRIMEDATE_COL + " TEXT, " +
CRIMESUSPECT_COL + " TEXT, " +
CRIMESOLVED_COL + " INTEGER" +
");";
public CrimeDBHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(TABLECRTSQL);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldversion, int newversion) {
}
public long addCrime(String crimetitle, String crimedate, String crimesuspect, int crimesolved) {
SQLiteDatabase db = getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(CRIMETITLE_COL,crimetitle);
cv.put(CRIMEDATE_COL,crimedate);
cv.put(CRIMESUSPECT_COL,crimesuspect);
cv.put(CRIMESOLVED_COL,crimesolved);
return db.insert(CRIMESTABLE,null,cv);
}
public int deleteCrime(long crimeid) {
SQLiteDatabase db = getWritableDatabase();
String whereclause = CRIMEID_COL + "=?";
String[] whereargs = {Long.toString(crimeid)};
return db.delete(CRIMESTABLE,whereclause,whereargs);
}
public Cursor getCrimeList() {
SQLiteDatabase db = getWritableDatabase();
return db.query(CRIMESTABLE,null,null,null,null,null,null,null);
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
EditText mCrimeTitle;
EditText mCrimeDate;
EditText mCrimeSuspect;
CheckBox mCrimeSolved;
Button mAddCrime;
Button mDltCrime;
ListView mCrimeList;
CrimeDBHelper dbhlpr = new CrimeDBHelper(this);
Cursor crimelist;
SimpleCursorAdapter sca;
long lastcrimeid;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mCrimeTitle = (EditText) findViewById(R.id.crimetitle);
mCrimeDate = (EditText) findViewById(R.id.crimedate);
mCrimeSuspect = (EditText) findViewById(R.id.crimesuspect);
mCrimeSolved = (CheckBox) findViewById(R.id.crimesolved);
mCrimeList = (ListView) findViewById(R.id.crimelist);
mAddCrime = (Button) findViewById(R.id.addcrime);
mDltCrime = (Button) findViewById(R.id.dltcrime);
crimelist = dbhlpr.getCrimeList();
// Setup Button to Add a crime
mAddCrime.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int solved = 0;
if (mCrimeSolved.isChecked()) {
solved = 1;
}
lastcrimeid = dbhlpr.addCrime(
mCrimeTitle.getText().toString(),
mCrimeDate.getText().toString(),
mCrimeSuspect.getText().toString(),
solved
);
mDltCrime.setText("DLT CRIME (ID=" + Long.toString(lastcrimeid) + ")");
mDltCrime.setTag(lastcrimeid);
crimelist = dbhlpr.getCrimeList();
sca.swapCursor(crimelist);
}
});
// Setup button to delete the latest Crime added
mDltCrime.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//dbhlpr.deleteCrime(lastcrimeid); can do it this way
if (view.getTag() != null) {
dbhlpr.deleteCrime((long)view.getTag());
crimelist = dbhlpr.getCrimeList();
sca.swapCursor(crimelist);
}
}
});
sca = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1,
crimelist,
new String[]{CrimeDBHelper.CRIMETITLE_COL},
new int[]{android.R.id.text1},
0
);
mCrimeList.setAdapter(sca);
mCrimeList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
dbhlpr.deleteCrime(l);
crimelist = dbhlpr.getCrimeList();
sca.swapCursor(crimelist);
return true;
}
});
}
protected void onDestroy() {
super.onDestroy();
if (crimelist != null) {
crimelist.close();
}
}
}
A primeira coisa a notar é a linha
long lastcrimeid;
, isso é declarado no nível da classe, portanto, está muito disponível por toda parte (o problema que você estava tendo com long databaseID
). Você também pode notar
SimpleCursorAdapter sca;
isso será usado para o ListView
(basicamente coloca os dados do cursor no ListView ). Você deve estar familiarizado com grande parte do código a seguir. Em resumo:-
- super.onCreate é chamado.
- A atividade está definida para usar o layout activity_main.xml.
- À medida que o layout é carregado, os id's associados às visualizações são obtidos.
-
Um Cursor é obtido obtendo os crimes atuais do banco de dados (pode ser nenhum, isso não é um problema).
-
o botão listener para adicionar um crime é adicionado. Observe que isso usa o _id retornado da linha adicionada duas vezes (na verdade 3 vezes, pois altera o texto dos botões de exclusão de acordo ).
lastcrimeid
é definido pelo retorno doaddCrime()
método.-
mDltCrime.setTag(lastcrimeid);
define a tag do botão de exclusão para o_id
da linha adicionada.
-
Observe também que existem duas linhas adicionais:crimelist = dbhlpr.getCrimeList();
esca.swapCursor(crimelist);
.
- O primeiro substitui o cursor pelo que está agora no banco de dados (ou seja, inclui a linha que foi adicionada), o segundo diz ao ListView para usar o novo cursor, então faz com que o ListView mostre o que está agora no banco de dados ( isso é usado novamente ao excluir uma linha).
-
o listener de botão para o botão de exclusão é então adicionado. Isso pode funcionar de duas maneiras. Olastcrimeid
pode ser usado ou, alternativamente, a tag do botão pode ser usada, pois ambos mantêm o _id da linha a ser excluída. O código tem o primeiro comentado, então o último método é usado (ou seja, o valor na tag do botão é recuperado).
- Observe que este último método tem a desvantagem de que o valor pode ser nulo, o que causaria uma exceção de ponteiro nulo, daí o
if (view.getTag != null)
.
- Observe que este último método tem a desvantagem de que o valor pode ser nulo, o que causaria uma exceção de ponteiro nulo, daí o
-
Como acima para atualizar o ListView .
-
Em seguida, o SimpleCursorAdapter é configurado, leva 5 parâmetros:-
- o layout a ser usado (android.R.layout.simple_list_item_1) é um layout de estoque.
- os dados a serem usados na forma de um Cursor. NOTA! uma coluna chamada _id DEVE existir (geralmente é uma boa ideia usar sempre
_id INTEGER PRIMARY KEY
por esse motivo. ) Observe que temos um Cursorcrimelist
através dogetCrimeList
método. - As colunas no cursor das quais os dados devem ser recuperados.
- As visualizações no layout em que os dados recuperados serão colocados.
- Um valor do qual não me lembro o propósito. No entanto, 0 é bom para usar. Não codificar este 5º parâmetro provavelmente resultará em uma mensagem obsoleta.
- (Observe que normalmente uso CursorAdapters personalizados, pois são muito mais flexíveis, portanto, raramente uso Simples).
-
Em seguida, o ListView é instruído a usar o Adaptador conformemCrimeList.setAdapter(sca);
.
-
Em seguida, umonItemLongClickListener
é adicionado ao ListView, que excluirá o crime que foi clicado por muito tempo (l longo é o _id valor, daí uma razão pela qual um CursorAdapter precisa de _id e, portanto, por quedbhlpr.deleteCrime(l);
).
- Novamente a ListView é atualizado.
-
Finalmente, como o cursor é usado enquanto a atividade permanece em uso,onDestory
é usado para fechar o Cursor (os cursores devem sempre ser fechados quando terminar).
É assim que fica (não bonito, mas funcional), com três Crimes adicionados (O botão excluir removeria o O Crime do Século crime). Clicar por muito tempo em qualquer crime listado excluirá esse crime. Clicar em adicionar adicionaria outra entrada para Crime do Século, a menos que os dados fossem alterados.