Para
crear una aplicación utilizando AndroidStudio vamos a hacer
click en File -> New Project. Con lo que se nos mostrara un
formulario como el siguiente:
En
en el sdk mínimo requerido seleccionamos la versión api versión
11, en la versión destino la versión de api 14 y en compilado la
más actual hasta este momento la api versión 17 y el tema de la
aplicación Holo Light with Dark Action Bar.
Posteriormente
vamos a seleccionar la imagen para el icono para el launcher
de nuestra aplicación, el launcher de la aplicación es aquel
icono que al presionarlo inicia la aplicación.
Yo
he seleccionado uno les recomiendo sitios como iconfinder.com o
vectorarchive también deviantart.com siempre y cuando respetando las
licencias que proveen las imágenes.
Posteriormente
vamos a indicar el tipo de Activity para
nuestra aplicacion en este caso seleccionamos una actividad en
blanco.
Para
la navegación de nuestra aplicación vamos a seleccionar Dropdown
esto ya que estamos pensado
que nuestra aplicación de libreta presente entre diversos documentos
utilizando este Dropdown.
Una
vez hecho esto se nos presenta la pantalla con la estructura inicial
del proyecto.
Esta
pantalla nos indica que aun no tenemos seleccionado ningún elemento
de nuestro proyecto vamos a iniciar creando la clase que representara
y almacenara los archivos de texto, nuestra libreta tomara el texto y
lo almacenara en un archivo de texto. Los archivos de texto
usualmente tienen terminación .txt
(pero se puede utilizar cualquier terminación para los archivos en
realidad); para mantener los archivos con una terminación utilizada
generalmente vamos a utilizar esta.
Para
esto vamos a crear una clase que nos permita generar un archivo de
texto a partir del texto, y también que nos obtenga el texto a
partir de un archivo (operación inversa).
Vamos
a ir a nuestro arbol del proyecto y vamos a agregar una nueva clase.
Vamos
a hace click derecho en nuestra carpeta com.roque.rueda.notepad (o
como le nombraron) y agregar una nueva clase. Le vamos a nombrar
TextFile.
La
clase debe tener la funcionalidad para permitirnos la generación de
los archivos de texto. Vamos a iniciar con la parte que a mi parecer
es la mas importante de la aplicación que es la generación de los
archivos de texto. La clase que vamos a generar sera algo como lo
siguiente.
/*
* Copyright 2013 Roque Rueda.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.roque.rueda.notepad;
import android.content.Context;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
/**
* Save a file using a text input also gets the text of a file
* and presents as a string.
* Created by Roque Rueda on 25/06/13.
*/
public class TextFile {
private Context mContext;
private static final String ENCODING = "utf8";
public TextFile(Context ctx) {
mContext = ctx;
}
/**
* Create a file in the device file system.
* @param path Path where a new text file is going to be created.
* @param content Text content of the file.
* @return True if the file can be created.
* @throws IOException if there's a problem creating the new file.
*/
public boolean createFile(String path, String content)
throws IOException {
FileOutputStream fileOutputStream = mContext.openFileOutput(path, Context.MODE_PRIVATE);
OutputStreamWriter osw = new OutputStreamWriter(fileOutputStream, ENCODING);
osw.write(content);
osw.flush();
osw.close();
return true;
}
/**
* Read the contents of the file and returns as a string.
* @param path Path of the file that is going to be read.
* @return Content of the file.
* @throws IOException if the file can't be found or if there's a problem
* reading the content of he file.
*/
public String getFileContent(String path)
throws IOException{
StringBuilder content = new StringBuilder(350);
FileInputStream fileInputStream = mContext.openFileInput(path);
InputStreamReader isr = new InputStreamReader(fileInputStream, ENCODING);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null){
content.append(line).append("\n");
}
return content.toString();
}
}
Esta
clase ofrece la funcionalidad de la creación de archivo de texto,
para la creación del archivo de texto se requiere del método
openFileOutput el cual proviene de la clase Context es por eso
necesario que en el constructor de la clase se requiera de una
instancia de esta clase para poder realizar las operaciones, (para
que android studio nos genere el constructor utilize las teclas alt +
insert). La creacion del archivo es una operacion sencilla
utilizando los métodos de la clase Context.
Para
extraer el contenido del archivo se utiliza el metodo openFileInput
pasando la ruta del archivo una vez realizado se lee el archivo linea
por linea y se almacena en un StringBuilder, finalmente se regresa
toda la cadena generada en el archivo. De momento se omiten el manejo
de excepciones y las verificaciones de datos.
Ahora
vamos a regresar a nuestra clase NoteActivity que fue generada
con el proyecto. La cual contiene lo siguiente:
package com.roque.rueda.notepad;
import android.annotation.TargetApi;
import android.app.ActionBar;
import android.os.Bundle;
import android.content.Context;
import android.os.Build;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.NavUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class NoteActivity extends FragmentActivity implements ActionBar.OnNavigationListener {
/**
* The serialization (saved instance state) Bundle key representing the
* current dropdown position.
*/
private static final String STATE_SELECTED_NAVIGATION_ITEM = "selected_navigation_item";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_note);
// Set up the action bar to show a dropdown list.
final ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
// Set up the dropdown list navigation in the action bar.
actionBar.setListNavigationCallbacks(
// Specify a SpinnerAdapter to populate the dropdown list.
new ArrayAdapter(
getActionBarThemedContextCompat(),
android.R.layout.simple_list_item_1,
android.R.id.text1,
new String[] {
getString(R.string.title_section1),
getString(R.string.title_section2),
getString(R.string.title_section3),
}),
this);
}
/**
* Backward-compatible version of {@link ActionBar#getThemedContext()} that
* simply returns the {@link android.app.Activity} if
* getThemedContext is unavailable.
*/
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private Context getActionBarThemedContextCompat() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return getActionBar().getThemedContext();
} else {
return this;
}
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Restore the previously serialized current dropdown position.
if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
getActionBar().setSelectedNavigationItem(
savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
// Serialize the current dropdown position.
outState.putInt(STATE_SELECTED_NAVIGATION_ITEM,
getActionBar().getSelectedNavigationIndex());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.note, menu);
return true;
}
@Override
public boolean onNavigationItemSelected(int position, long id) {
// When the given dropdown item is selected, show its contents in the
// container view.
Fragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, fragment)
.commit();
return true;
}
/**
* A dummy fragment representing a section of the app, but that simply
* displays dummy text.
*/
public static class DummySectionFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
public static final String ARG_SECTION_NUMBER = "section_number";
public DummySectionFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_note_dummy, container, false);
TextView dummyTextView = (TextView) rootView.findViewById(R.id.section_label);
dummyTextView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER)));
return rootView;
}
}
}
En
nuestro metodo onCreate modificaremos el titulo de “Section 1”
a “New document”, androidStudio nos muestra el valor del
metodo getString pasando el identificador del string de nuestro
archivo strings, por lo tanto para poder realizar la modificacion nos
movemos al archivo strings.xml y modificaremos el valor de
“title_section1”, quedando algo como lo siguiente:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Notepad</string>
<string name="action_settings">Settings</string>
<string name="title_section1">New document</string>
<string name="title_section2">Section 2</string>
<string name="title_section3">Section 3</string>
</resources>
Adicional
vamos a agregar la final de nuestro método onCreate la creación de
nuestra clase TextFile e invocaremos la creación del archivo con un
contenido por defecto de momento.
mTextFile = new TextFile(this);
try {
mTextFile.createFile("test.txt", "Hello World");
} catch (IOException e) {
e.printStackTrace();
}
Una
vez hecho esto solo tenemos que mostrar el contenido de nuestro
archivo en la pantalla. Debido a que el diseño de nuestra actividad
se compone de Fragments, vamos a modificar el código que se
genero por nosotros en el método onNavigationItemSelected de
la siguiente manera.
@Override
public boolean onNavigationItemSelected(int position, long id) {
// When the given dropdown item is selected, show its contents in the
// container view.
Fragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
switch (position){
case 0:{
String content = null;
try {
content = mTextFile.getFileContent("test.txt");
} catch (IOException e) {
e.printStackTrace();
}
args.putString(DummySectionFragment.ARG_TEXT_FILE, content);
break;
}
default:{
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
break;
}
}
fragment.setArguments(args);
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, fragment)
.commit();
return true;
}
Estas
modificación también implican modificación a la clase interna
generada DummySectionFragment agregando una constante:
ARG_TEXT_FILE la cual se utiliza como llave para recuperar los
datos que se obtienen del archivo de texto. Para lo que tambien vamos
a modificar el metodo onCreateView. Teniendo como resultado lo
siguiente:
/**
* A dummy fragment representing a section of the app, but that simply
* displays dummy text.
*/
public static class DummySectionFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
public static final String ARG_SECTION_NUMBER = "section_number";
public static final String ARG_TEXT_FILE = "myTextFile";
public DummySectionFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_note_dummy, container, false);
TextView dummyTextView = (TextView) rootView.findViewById(R.id.section_label);
if (getArguments().containsKey(ARG_TEXT_FILE)){
dummyTextView.setText(getArguments().getString(ARG_TEXT_FILE));
}
else {
dummyTextView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER)));
}
return rootView;
}
}
El
resultado de la clase es el siguiente:
package com.roque.rueda.notepad;
import android.annotation.TargetApi;
import android.app.ActionBar;
import android.os.Bundle;
import android.content.Context;
import android.os.Build;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.NavUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.io.IOException;
public class NoteActivity extends FragmentActivity implements ActionBar.OnNavigationListener {
/**
* The serialization (saved instance state) Bundle key representing the
* current dropdown position.
*/
private static final String STATE_SELECTED_NAVIGATION_ITEM = "selected_navigation_item";
private TextFile mTextFile;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_note);
// Set up the action bar to show a dropdown list.
final ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
// Set up the dropdown list navigation in the action bar.
actionBar.setListNavigationCallbacks(
// Specify a SpinnerAdapter to populate the dropdown list.
new ArrayAdapter(
getActionBarThemedContextCompat(),
android.R.layout.simple_list_item_1,
android.R.id.text1,
new String[] {
getString(R.string.title_section1),
getString(R.string.title_section2),
getString(R.string.title_section3),
}),
this);
mTextFile = new TextFile(this);
try {
mTextFile.createFile("test.txt", "Hello World");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Backward-compatible version of {@link ActionBar#getThemedContext()} that
* simply returns the {@link android.app.Activity} if
* getThemedContext is unavailable.
*/
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private Context getActionBarThemedContextCompat() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return getActionBar().getThemedContext();
} else {
return this;
}
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Restore the previously serialized current dropdown position.
if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) {
getActionBar().setSelectedNavigationItem(
savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM));
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
// Serialize the current dropdown position.
outState.putInt(STATE_SELECTED_NAVIGATION_ITEM,
getActionBar().getSelectedNavigationIndex());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.note, menu);
return true;
}
@Override
public boolean onNavigationItemSelected(int position, long id) {
// When the given dropdown item is selected, show its contents in the
// container view.
Fragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
switch (position){
case 0:{
String content = null;
try {
content = mTextFile.getFileContent("test.txt");
} catch (IOException e) {
e.printStackTrace();
}
args.putString(DummySectionFragment.ARG_TEXT_FILE, content);
break;
}
default:{
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
break;
}
}
fragment.setArguments(args);
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, fragment)
.commit();
return true;
}
/**
* A dummy fragment representing a section of the app, but that simply
* displays dummy text.
*/
public static class DummySectionFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
public static final String ARG_SECTION_NUMBER = "section_number";
public static final String ARG_TEXT_FILE = "myTextFile";
public DummySectionFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_note_dummy, container, false);
TextView dummyTextView = (TextView) rootView.findViewById(R.id.section_label);
if (getArguments().containsKey(ARG_TEXT_FILE)){
dummyTextView.setText(getArguments().getString(ARG_TEXT_FILE));
}
else {
dummyTextView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER)));
}
return rootView;
}
}
}
Y
cuando ejecutemos en el emulador obtendremos el siguiente resultado.
Saludos dudas o comentarios abajo.








No hay comentarios:
Publicar un comentario