Tecnologías Móviles
clase 5
Ejercicio de la clase anterior
Vertical
Horizontal
Ejercicio de la clase anterior - MainActivity
public class MainActivity extends AppCompatActivity {
FragmentManager manager;
ListFragment list = new ListFragment();
FormFragment form = new FormFragment();
Boolean isPort = null;
protected void onCreate(Bundle savedInstanceState) {
...
View container = findViewById(R.id.container);
isPort = container!=null;
manager = getSupportFragmentManager();
if(isPort) {
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.container, list);
transaction.commit();
} else {
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.listContainer, list);
transaction.replace(R.id.formContainer, form);
transaction.commit();
}
}
...
Ejercicio de la clase anterior - ListFragment
public class ListFragment extends Fragment {
static UserAdapter adapter = null;
View root;
...
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if(adapter==null) {
adapter = new UserAdapter(getActivity());
}
root = inflater.inflate(R.layout.fragment_list, container, false);
FloatingActionButton fab = (FloatingActionButton) root.findViewById(R.id.fab);
if(((MainActivity) getActivity()).isPort()) {
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
((MainActivity) getActivity()).selectUser(null, null);
}
});
} else {
fab.setVisibility(View.INVISIBLE);
}
...
}
Ejercicio de la clase anterior - ListFragment
public class ListFragment extends Fragment {
static UserAdapter adapter = null;
View root;
...
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
ListView list = (ListView) root.findViewById(R.id.userList);
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
((MainActivity) getActivity()).selectUser(adapter.getItem(position), position);
}
});
return root;
}
Ejercicio de la clase anterior - FormFragment
public class FormFragment extends Fragment {
static View mRoot;
static Integer mPos = null;
static User mUser = null;
public FormFragment() {
// Required empty public constructor
}
private void setUser(User user) {
EditText nombre = (EditText) mRoot.findViewById(R.id.nombre);
EditText apellido = (EditText) mRoot.findViewById(R.id.apellido);
EditText mail = (EditText) mRoot.findViewById(R.id.mail);
if(user==null) {
nombre.setText("");
apellido.setText("");
mail.setText("");
} else {
nombre.setText(user.getNombre());
apellido.setText(user.getApellido());
mail.setText(user.getMail());
}
}
...
Ejercicio de la clase anterior - FormFragment
public class FormFragment extends Fragment {
...
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if(mRoot==null) {
mRoot = inflater.inflate(R.layout.fragment_form, container, false);
}
if(mUser!=null) {
setUser(mUser);
}
Button aceptar = (Button) mRoot.findViewById(R.id.aceptar);
Button cancelar = (Button) mRoot.findViewById(R.id.cancelar);
aceptar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EditText nombre = (EditText) mRoot.findViewById(R.id.nombre);
EditText apellido = (EditText) mRoot.findViewById(R.id.apellido);
EditText mail = (EditText) mRoot.findViewById(R.id.mail);
User user = new User(
nombre.getText().toString(),
apellido.getText().toString(),
mail.getText().toString());
setUser(null);
((MainActivity) getActivity()).setUser(user, mPos);
mPos = null;
mUser=null;
}
});
...
Ejercicio de la clase anterior - FormFragment
public class FormFragment extends Fragment {
...
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
cancelar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setUser(null);
mPos = null;
mUser=null;
((MainActivity) getActivity()).setUser(null, null);
}
});
return mRoot;
}
Ejercicio de la clase anterior - Agregar/Editar Usuario
1. List
((MainActivity) getActivity()).selectUser(null, null);
((MainActivity) getActivity()).selectUser(adapter.getItem(position), position);
Nuevo (click en FAB)
Editar (clic en la lista)
2. Main
public void selectUser(User user, Integer pos) {
if(user!=null) form.selectUser(user, pos);
if(isPort) {
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.container, form);
transaction.commit();
}
}
public void selectUser(User user, Integer pos) {
setUser(user);
mUser = user;
mPos = pos;
}
3. Form
Ejercicio de la clase anterior - Agregar/Editar Usuario
4. Form
((MainActivity) getActivity()).setUser(user, mPos);
((MainActivity) getActivity()).setUser(null, null);
Aceptar
Cancelar
5. Main
public void setUser(User user, Integer pos) {
if(user != null) {
if (pos == null) list.addUser(user);
else list.setUser(pos, user);
}
if(isPort) {
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.container, list);
transaction.commit();
}
}
Ejercicio de la clase anterior - Agregar/Editar Usuario
6. List
public void addUser(User user) {
adapter.addItem(user);
}
public void setUser(Integer pos, User user) {
adapter.setItem(pos, user);
}
7. Adapter
public void addItem(User usuario) {
usrs.add(usuario);
notifyDataSetChanged();
}
public void setItem(Integer pos, User user) {
usrs.set(pos, user);
notifyDataSetChanged();
}
Ejercicio de la clase anterior - UserAdapter
public class UserAdapter extends BaseAdapter {
...
@Override
public View getView(int position, View convertView, ViewGroup parent) {
...
ImageView delete = (ImageView) convertView.findViewById(R.id.delete);
delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new AlertDialog.Builder(mContext)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(R.string.deleteUserTitle)
.setMessage(R.string.deleteUserMessage)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which) {
rmItem(position);
}
})
.setNegativeButton(R.string.no, null)
.show();
}
});
...
return convertView;
}
public void rmItem(int position) {
usrs.remove(position);
notifyDataSetChanged();
}
}
AsyncTask
Permite ejecutar operaciones en segundo plano, sin afectar al thread que controla la UI.
Se debe utilizar para operaciones cortas.
Para utilizarlo se debe extender la clase AsyncTask e implementar como mínimo los métodos doInBackground() y onPostExcecute()
Todos los métodos se ejecutan en el UI Thread, excepto doInBackground()
AsyncTask
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
DownloadFilesTask downloadFilesTask = new DownloadFilesTask();
downloadFilesTask.execute(url1, url2, url3);
Conectar a API REST
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
...
}
AndroidManifest
Chequear el estado de conexión
Conectar a API REST
protected String doInBackground(String... urlStrings) {
String myurl = urlStrings[0];
InputStream is = null;
// Only display the first 500 characters of the retrieved
// web page content.
int len = 500;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
int response = conn.getResponseCode();
Log.d(DEBUG_TAG, "The response is: " + response);
is = conn.getInputStream();
// Convert the InputStream into a string
String contentAsString = readIt(is, len);
return contentAsString;
// Makes sure that the InputStream is closed after the app is
// finished using it.
} finally {
if (is != null) {
is.close();
}
}
}
Conectar a API REST
protected String doInBackground(String... urlStrings) {
...
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setChunkedStreamingMode(0);
// Starts the query
conn.connect();
OutputStream out = new BufferedOutputStream(conn.getOutputStream());
writeStream(out);
...
}
Enviar contenido con el pedido
Ejercicio
A la aplicación creada en el ejercicio de la clase anterior, agregarle las siguientes características:
- El listado de usuarios debe obtenerse haciendo GET a http://tm5-agmoyano.rhcloud.com/
- Si se agrega un usuario, se debe enviar un pedido POST a http://tm5-agmoyano.rhcloud.com/ con los parámetros nombre, apellido y mail en el body.
- Si se modifica un usuario, se debe enviar un pedido PUT a http://tm5-agmoyano.rhcloud.com/:index con los parámetros nombre, apellido y mail en el body (reemplazar :index por el número de posición en el array de usuarios).
- Si se elimina un usuario, se debe enviar un pedido DELETE a http://tm5-agmoyano.rhcloud.com/:index (reemplazar :index por el número de posición en el array de usuarios).
- Todas las acciones cargan nuevamente el listado.
- Todos los pedidos deben realizarse en un thread separado al de UI.
Tecnologías Móviles - Clase 5
By Agustin Moyano
Tecnologías Móviles - Clase 5
- 763