Tecnologías Móviles
clase 10
Ejercicio de la clase anterior
SERVICE
Settings
Ejercicio de la clase anterior
...
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.2.1'
compile 'com.android.support:design:23.2.1'
compile 'org.apache.commons:commons-io:1.3.2'
compile 'com.android.support:support-v4:23.2.1'
compile 'com.android.support:preference-v7:23.3.0'
compile 'com.android.support:preference-v14:23.3.0'
}
build.gradle (app)
Ejercicio de la clase anterior
public class MainActivity extends AppCompatActivity {
...
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
//startActivity(new Intent(this, SettingsActivity.class));
SettingsFragment settings = new SettingsFragment();
if(isPort) {
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.container, settings);
transaction.addToBackStack("settings");
transaction.commit();
} else {
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.listContainer, settings);
transaction.replace(R.id.formContainer, null);
transaction.addToBackStack("settings");
transaction.commit();
}
return true;
}
return super.onOptionsItemSelected(item);
}
}
MainActivity
Ejercicio de la clase anterior
public class SettingsFragment extends PreferenceFragmentCompat {
...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.settings);
// Bind the summaries of EditText/List/Dialog/Ringtone preferences
// to their values. When their values change, their summaries are
// updated to reflect the new value, per the Android Design
// guidelines.
bindPreferenceSummaryToValue(findPreference("interval"), getString(R.string.seconds));
bindPreferenceSummaryToValue(findPreference("url"));
}
private static void bindPreferenceSummaryToValue(Preference preference) {
bindPreferenceSummaryToValue("", preference, "");
}
private static void bindPreferenceSummaryToValue(Preference preference, String suffix) {
bindPreferenceSummaryToValue("", preference, suffix);
}
private static void bindPreferenceSummaryToValue(String preffix, Preference preference) {
bindPreferenceSummaryToValue(preffix, preference, "");
}
public interface OnExtendedPreferenceChaneListener extends Preference.OnPreferenceChangeListener {
public void setPreffix(String preffix);
public void setSuffix(String suffix);
}
}
SettingsFragment
Ejercicio de la clase anterior
public class SettingsFragment extends PreferenceFragmentCompat {
...
private static void bindPreferenceSummaryToValue(String preffix, Preference preference,
String suffix) {
// Set the listener to watch for value changes.
OnExtendedPreferenceChaneListener sBindPreferenceSummaryToValueListener =
new OnExtendedPreferenceChaneListener() {
String mPreffix="";
String mSuffix="";
public void setPreffix(String preffix) {
mPreffix=preffix+" ";
}
public void setSuffix(String suffix) {
mSuffix = " "+suffix;
}
public boolean onPreferenceChange(Preference preference, Object value) {
String stringValue = value.toString();
if (preference instanceof ListPreference) {
// For list preferences, look up the correct display value in
// the preference's 'entries' list.
ListPreference listPreference = (ListPreference) preference;
int index = listPreference.findIndexOfValue(stringValue);
// Set the summary to reflect the new value.
preference.setSummary(
index >= 0
? mPreffix+listPreference.getEntries()[index]+mSuffix
: null);
} else {
...
SettingsFragment
Ejercicio de la clase anterior
public class SettingsFragment extends PreferenceFragmentCompat {
...
private static void bindPreferenceSummaryToValue(String preffix, Preference preference,
String suffix) {
// Set the listener to watch for value changes.
OnExtendedPreferenceChaneListener sBindPreferenceSummaryToValueListener =
new OnExtendedPreferenceChaneListener() {
...
} else {
// For all other preferences, set the summary to the value's
// simple string representation.
preference.setSummary(mPreffix+stringValue+mSuffix);
}
return true;
}
};
sBindPreferenceSummaryToValueListener.setPreffix(preffix);
sBindPreferenceSummaryToValueListener.setSuffix(suffix);
preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
// Trigger the listener immediately with the preference's
// current value.
sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
PreferenceManager
.getDefaultSharedPreferences(preference.getContext())
.getString(preference.getKey(), ""));
}
}
SettingsFragment
Ejercicio de la clase anterior
public class ApiClientService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener {
...
protected void setTimer() {
Integer sec = Integer.valueOf(mPreferences.getString("interval","5"));
timer.schedule(new TimerTask() {
@Override
public void run() {
mBinder.resolvePending();
mBinder.findUsers();
}
}, 0, sec * 1000);
}
protected void setUrl() {
mUrl = mPreferences.getString("url", "http://tm5-agmoyano.rhcloud.com/");
}
public void onCreate() {
...
mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
setTimer();
setUrl();
mPreferences.registerOnSharedPreferenceChangeListener(this);
}
...
}
ApiClientService
Ejercicio de la clase anterior
public class ApiClientService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener {
...
public void onDestroy() {
timer.cancel();
mPreferences.unregisterOnSharedPreferenceChangeListener(this);
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals("interval")) {
setTimer();
}
if (key.equals("url")) {
setUrl();
}
}
...
}
ApiClientService
Menúes
-
Options menu and app bar
Opciones generales de la aplicación, ej: Buscar, Configuraciones, etc. -
Context menu and contextual action mode
Menú flotante que aparece cuando se hace un click largo sobre un elemento. Provee acciones que afectan a los elementos seleccionados. -
Popup menu
Provee una lista de items que se despliegan a partir del elemento que invocó el menú. No debe proveer acciones que afecten al elemento seleccionado, sino pueden proveer acciones extendidas de un comando, o acciones que se relacionan al elemento seleccionado
Menúes
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/new_game"
android:icon="@drawable/ic_new_game"
android:title="@string/new_game"
android:showAsAction="ifRoom"/>
<item android:id="@+id/help"
android:icon="@drawable/ic_help"
android:title="@string/help" />
</menu>
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/file"
android:title="@string/file" >
<!-- "file" submenu -->
<menu>
<item android:id="@+id/create_new"
android:title="@string/create_new" />
<item android:id="@+id/open"
android:title="@string/open" />
</menu>
</item>
</menu>
Menúes
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.game_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.new_game:
newGame();
return true;
case R.id.help:
showHelp();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Options menu and app bar
Menúes
Options menu and app bar
Para modificar el menú en runtime se debe implementar el método onPrepareOptionsMenu()
Dentro del método se pueden agregar, eliminar y deshabilitar elementos.
Para avisar que el menú debería cambiarse, hay que llamar al método invalidateOptionsMenu()
Menúes
Contextual action mode
Vistas individuales
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
// Called when the action mode is created; startActionMode() was called
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate a menu resource providing context menu items
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
return true;
}
// Called each time the action mode is shown. Always called after onCreateActionMode, but
// may be called multiple times if the mode is invalidated.
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false; // Return false if nothing is done
}
// Called when the user selects a contextual menu item
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_share:
shareCurrentItem();
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
// Called when the user exits the action mode
@Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
}
};
Menúes
Contextual action mode
Menú contextual para vistas individuales
someView.setOnLongClickListener(new View.OnLongClickListener() {
// Called when the user long-clicks on someView
public boolean onLongClick(View view) {
if (mActionMode != null) {
return false;
}
// Start the CAB using the ActionMode.Callback defined above
mActionMode = getActivity().startActionMode(mActionModeCallback);
view.setSelected(true);
return true;
}
});
Menúes
Contextual action mode
GridView y ListView
ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position,
long id, boolean checked) {
// Here you can do something when items are selected/de-selected,
// such as update the title in the CAB
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// Respond to clicks on the actions in the CAB
switch (item.getItemId()) {
case R.id.menu_delete:
deleteSelectedItems();
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate the menu for the CAB
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context, menu);
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
// Here you can make any necessary updates to the activity when
// the CAB is removed. By default, selected items are deselected/unchecked.
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// Here you can perform updates to the CAB due to
// an invalidate() request
return false;
}
});
Menúes
Popup menu
public void showMenu(View v) {
PopupMenu popup = new PopupMenu(this, v);
// This activity implements OnMenuItemClickListener
popup.setOnMenuItemClickListener(this);
popup.inflate(R.menu.actions);
popup.show();
}
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.archive:
archive(item);
return true;
case R.id.delete:
delete(item);
return true;
default:
return false;
}
}
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_overflow_holo_dark"
android:contentDescription="@string/descr_overflow_button"
android:onClick="showPopup" />
Ejercicio
Basado en el ejercicio de la clase anterior, realizar los siguientes puntos:
- Agregar al menú general, una acción de búsqueda. Cuando se haga click sobre dicha acción, se debe mostrar un Fragment que contenga un EditText y un ListView. Mientras se escribe en el EditText (addTextChangedListener) se debe modificar el contenido de la lista.
-
Quitar el boton eliminar dentro de los items del listado de usuarios.
- Generar un menú contextual para el ListView que contiene el listado de usuarios, y que permita eliminar varios usuarios al mismo tiempo.
Tecnologías Móviles - Clase 10
By Agustin Moyano
Tecnologías Móviles - Clase 10
- 659