Camada das Funções
A primeira camada que vamos criar corresponde as funções que necessitamos. No caso deste projeto, funções de tratamento com Datas. Criamos uma nova classe no pacote projeto.livro.faltam chamada UtilData com a seguinte codificação:public class UtilData {
private static Date dataAtual = new Date();
private static String formatarData(final Date data) {
DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy", Locale.UK);
return sdf.format(data);
}
private static Date strToDate(final String dataStr) {
DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy", Locale.UK);
try {
return sdf.parse(dataStr);
} catch (Exception e) {
Log.e("Faltam", "Erro na data: " + e.getMessage());
}
return null;
}
public static Date convDiaMesToDate(final String diaMes) {
Calendar original = new GregorianCalendar();
original.setTime(dataAtual);
int anoAtual = original.get(Calendar.YEAR);
String montaData = diaMes.substring(0, 2) + "/" + diaMes.substring(2) + "/"
+ anoAtual;
return strToDate(montaData);
}
public static Date convDiaToDate(final String dia) {
Calendar original = new GregorianCalendar();
original.setTime(dataAtual);
int diaAtual = original.get(Calendar.DAY_OF_MONTH);
int mesAtual = original.get(Calendar.MONTH);
int anoAtual = original.get(Calendar.YEAR);
if (diaAtual > Integer.parseInt(dia)) {
mesAtual++;
if (mesAtual > 11) {
mesAtual = 0;
anoAtual++;
}
}
mesAtual++;
String montaData = dia + "/"
+ ((mesAtual < 10) ? "0" + mesAtual : mesAtual) + "/" + anoAtual;
return strToDate(montaData);
}
public static String retornarDiferencaComAtual(final Date dataOri) {
// Data é hoje
if (formatarData(dataAtual).equals(formatarData(dataOri))) {
return "É hoje";
}
Calendar diaCirc = new GregorianCalendar();
diaCirc.setTime(dataAtual);
int dia = 0;
while (!formatarData(diaCirc.getTime()).equals(formatarData(dataOri))) {
diaCirc.add(Calendar.DAY_OF_MONTH, 1);
dia++;
}
return dia + (dia > 2 ? " dias" : " dia");
}
}
Os métodos desta classe são:
- formatarData(final Date data): converter um objeto do tipo Date para um objeto tipo String no formato DD/MM/AAAA.
- strToDate(final String dataStr): converter um objeto tipo String no formato DD/MM/AAAA para um objeto tipo Date.
- convDiaMesToDate(final String diaMes): converter um objeto tipo String no formato DDMM (Dia e Mês) para um objeto tipo Date.
- convDiaToDate(final String dia): converter um objeto tipo String no formato DD (Dia) para um objeto tipo Date. Se o dia informado for menor que o dia atual o mês será o atual, caso contrário o mês será o seguinte.
- retornarDiferencaComAtual(final Date dataOri): retornar quantos dias faltam para chegar até o dia atual, recomenda-se que este método seja utilizado somente para períodos de um ano.
Java trata objetos tipo Date com duas classes: Calendar e GregorianCalendar. Se observamos veremos que todos os métodos contidos na própria Date estão depreciados, então usamos basicamente essas duas classes para lidar com esse tipo de objeto. Já as conversões para o tipo String são tratadas pela classe: SimpleDateFormat.
Camada de Dados
Precisamos realizar uma pequena modificação no método toString() da classe Registro, modificá-lo para a seguinte codificação: @Override
public String toString() {
if (dia.length() == 2) {
return descricao + ": "
+ UtilData.retornarDiferencaComAtual(UtilData.convDiaToDate(dia));
} else {
return descricao + ": "
+ UtilData.retornarDiferencaComAtual(UtilData.convDiaMesToDate(dia));
}
}
Agora a diferença de dias já pode ser visualizada sem problemas na lista.Uma boa prática é separar os métodos de Gravação e Leitura de arquivo e isolá-los em uma nova classe no pacote projeto.livro.faltam chamada UtilArquivo com a seguinte codificação:
public class UtilArquivo {
protected static void carregarLista(final List<registro> lista,
final FileInputStream arquivo) throws Exception {
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(arquivo);
Registro reg;
do {
reg = (Registro) ois.readObject();
lista.add(reg);
} while (true);
} catch (EOFException e) {
} finally {
ois.close();
}
}
protected static void gravarLista(final List<registro> lista,
final FileOutputStream arquivo) throws Exception {
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(arquivo);
for (Registro regs : lista) {
oos.writeObject(regs);
oos.flush();
}
} finally {
oos.close();
}
}
}
São os mesmos métodos que já vimos na postagem anterior. Isolados aqui, foram mais simplificados, ou seja, o método carregarLista() carrega todos os objetos do arquivo para a lista, enquanto que o método gravarLista() grava todos os objetos da lista para o arquivo.Atividade Principal
Para finalizarmos nosso aplicativo, procederemos mudanças na classe MainActivity:public class MainActivity extends ListActivity {
private EditText edDescricao;
private EditText edDia;
private final List<registro> lista = new ArrayList<registro>();
private ListView listaRegs;
private void eliminarRegistro() {
for (int i = listaRegs.getCount(); i > -1; i--) {
if (listaRegs.isItemChecked(i)) {
lista.remove(i);
}
}
mostrarLista();
}
private void guardarRegistro() {
lista.add(new Registro(edDescricao.getText().toString(), edDia.getText()
.toString()));
mostrarLista();
edDescricao.setText("");
edDia.setText("");
edDescricao.requestFocus();
}
private void mostrarLista() {
ArrayAdapter adaptador = new ArrayAdapter(this,
android.R.layout.simple_list_item_checked, lista);
listaRegs.setAdapter(adaptador);
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edDescricao = (EditText) findViewById(R.id.descricao);
edDia = (EditText) findViewById(R.id.dia);
listaRegs = getListView();
listaRegs.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
findViewById(R.id.guardar).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
guardarRegistro();
}
});
findViewById(R.id.eliminar).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
eliminarRegistro();
}
});
}
@Override
protected void onStart() {
super.onStart();
try {
UtilArquivo.carregarLista(lista, openFileInput("dias.reg"));
} catch (Exception e) {
Log.e("Faltam", "Erro Leitura: " + e.getMessage());
}
mostrarLista();
}
@Override
protected void onStop() {
super.onStop();
try {
UtilArquivo.gravarLista(lista,
openFileOutput("dias.reg", Context.MODE_PRIVATE));
} catch (Exception e) {
Log.e("Faltam", "Erro Leitura: " + e.getMessage());
}
}
}
Vamos começar pelo método onCreate() que é chamado assim que o aplicativo é iniciado, a lista da tela é associada a um objeto do tipo ListView, sua visão também foi modificada permitindo que o usuário possa selecionar os registros que deseja excluir. Através do ciclo de vida o próximo método chamado é o onStart() que será responsável por carregar a lista do arquivo texto, e esta lista agora só será gravada quando o método onStop() for chamado (assim evitamos I/O desnecessários). O método mostrarLista() procede a atualização da lista na tela (devemos lembrar que estamos trabalhando com dois objetos o ListView e um List que não estão sincronizados).
Finalmente os dois métodos responsáveis pelas ações de Gravar e Eliminar os registros da lista através do pressionamento dos botões pelo usuário. O método guardarRegistro() adiciona um novo registro a lista e o método eliminarRegistro() verifica qual registro da lista foi selecionado pelo usuário e procede sua retirada (observe que o laço anda de trás para frente eliminando os registros, isso é feito pois tudo é posicional).

Pronto, podemos rodar sem problemas nosso projeto e inclusive passá-lo para o celular (não esqueça da diretiva android:installLocation=”auto” que permitirá que a aplicação seja colocada no cartão de memória.
Utilize este projeto para descobrir como:
- Realizar gravações de objetos em arquivos;
- Realizar a leitura de objetos em arquivos;
- Utilizar o objeto tipo Date e suas conversões para o tipo String;
- Utilizar lista com marcadores tipo Check;
- Incluir e eliminar dinamicamente registros em listas.
Fernando Anselmo
0 comentários:
Postar um comentário