4. UI Design
http://developer.android.com/design/index.html
Ways to specify the size of an item:
dp/dip: Density independent pixel.
sp/sip: Scale independent pixel.Used in font
sizes.
pt: Point.
px: Pixel. Not use
layout_width,layout_height
match_parent:takes all the space
available.
wrap_content: uses the space needed
fill_parent:equivalent to match_parent
5. Android Asset Studio
Generate icons and graphic elements for each resolution
http://android-ui-utils.googlecode.com/hg/asset-studio/dist/index.html
6. Resources /Screen support
External elements you want to include and reference in the application.
Declaratively include in /res ,accesing by @<type>/<nname>
Are programmatically accessible via the R class
(compiled with Android Asset Packaging Tool)
Android automatically selects the resource that adapts to the environment
Each resource type in a folder / res.
drawable: Images, Icons.
layout: Layout to organize views.
values:
string.xml: Text strings
colors.xml
dimens.xml: font sizes,margins,paddings
anim: Animations
raw: Other resources like audio or video
menu: Menus and dialogs
xml: Other xml (preferences, app widget, …)
<supports-screens android:anyDensity="true"
android:xlargeScreens="true" android:largeScreens="true"
android:normalScreens="true" android:smallScreens="true" />
13. ACTION BAR PROGRESS
Avoid modal Dialogues and Activities
Always update the user on progress(ProgressBar and ProgressDialog)
Render the main view and fill in data as it arrives
14. ACTION BAR PROGRESS
Progress bar in Action Bar while url loading
private Activity activity = this;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getWindow().requestFeature(Window.
FEATURE_INDETERMINATE_PROGRESS);
ActionBar ab = getSupportActionBar();
………
}
activity.setProgressBarIndeterminateVisibility(true);
viewer.setWebViewClient(new WebViewClient() {
public void onPageFinished(WebView view, String url) {
activity.setProgressBarIndeterminateVisibility(false);
}
Show the progress bar to start loading and hide when finished.
20. Responsive
Avoid ANR(Application Not Responding)
No response to an input event (such as key press or
screen touch events) within 5 seconds.
Do not block the main UI thread with heavy work
Web Service call, Http Request
Communication with UI Thread is made with:
• Thread / Handler
• ThreadPoolExecutor
• AsyncTask
Goal of AsyncTask is to take care of thread management for you.
21. Asynctask
This class will allow us to perform background tasks without using neither directly nor
Handlers Threads, trying these elements in a fully transparent way to the programmer.
When we define a AsyncTask class must define the type of three elements, the input
parameters, its progress and outcome.
Override onPreExecute(),doInBackground(),onPostExecute(),onProgressUpdate()
class RequestTask extends AsyncTask<String, String, String>{
@Override
protected void onPreExecute() {
}
@Override
protected void onProgressUpdate(Integer... values) {
}
@Override
protected String doInBackground(String... uri) {
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
new RequestTask().execute(url);
22. Services
Perform the activity in an AsyncTask.
Kill the service when the task is complete.
Leaving a service running when it’s not needed is one of the
worst memory management mistakes an Android app can
make.
Service problem is always execute in main thread.
The best way to limit the lifespan of your service is to use an
IntentService, which finishes itself as soon as it's done
handling the intent that started it.
IntentService always execute in own thread.
Allows to launch a service in a new thread, avoiding blocking
the main thread.
Example:ActivityRecognitionService
23. Fragments
A fragment represents a certain behavior or a portion of a user
interface activity.
Multiple fragments can be combined.
A fragment must always be part of an activity.
They emerged to provide greater flexibility to build the user interface
Override methods
@Override
//called when finish onCreate method in activity
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public void onCreate(Bundle savedInstanceState) {//inicializar
componentes
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup
container,Bundle savedInstanceState) {
}
http://developer.android.com/guide/components/fragments.html
24. Fragments
Add a fragment to view
by layout xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<fragment
class="com.proyecto.spaincomputing.fragment.UniversidadesFragment"
android:id="@+id/FrgListado"
android:layout_width="375dp"
android:layout_height="match_parent"/>
<fragment
class="com.proyecto.spaincomputing.fragment.FragmentDetalle"
android:id="@+id/FrgDetalle"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
25. Fragments
Add a fragment to view
By code
//Fragments array
Fragment[] fragments = new Fragment[]{new PortadaFragment(),
new UniversityListFragment(),new
UniversidadesImagesFragment()};
FragmentManager manager = getSupportFragmentManager();
manager.beginTransaction()
.add(R.id.contentFrame, fragments[0])
.add(R.id.contentFrame, fragments[1])
.add(R.id.contentFrame, fragments[2])
.commit();
//show/hide
manager.beginTransaction().show(fragments[0]).commit();
manager.beginTransaction().hide(fragments[1]).commit();
manager.beginTransaction().hide(fragments[2]).commit();
38. Adapter Pattern
Link between the source data and the view
It works with ListView or GridView
There are many types of adapter
You can perform a custom adapter
The most used ArrayAdapter / CursorAdapter
The Adapter interacts with a collection of data objects for display in
View
ArrayList<UniversidadBean>
listado=newArrayList<UniversidadBean>();
private ListView lstListado;
lstListado=(ListView)getView().findViewById
(R.id.LstListado);
lstListado.setAdapter
(new UniversidadAdapter(this,listado));
39. View Holder/View Container Pattern
ViewContainer
static class ViewContainer{
public ImageView imagen;
public TextView nombre;
public TextView descripcion;
}
Improve the performance of listview
The viewholder is used to avoid calling findViewById whenever prompted a
new row to the adapter. Thus, instead of calling findViewById each time you
use the references to the fields you have stored in the viewholder.
This pattern will help us to limit the number of calls to findViewById method.
The idea would be to call it once, and then save the view daughter that refers
to the instance of ViewHolder to be associated with the object by the method
convertView View.setTag ()
Its recommend using a static class to store the items of each row in the view,
functioning as a kind of cache for our view.
40. View Holder/View Container Pattern
@Override
public View getView(int position, View convertView,ViewGroup parent) {
ViewContainer viewContainer;
//si es la primera vez que se imprime la fila
if(convertView==null){
LayoutInflater inflater = context.getLayoutInflater();
convertView = inflater.inflate(R.layout.row, null,true);
//crea una vista para el objeto contenedor
viewContainer=new ViewContainer()
//obtiene una referencia a todas las vistas de la fila
viewContainer.nombre=(TextView)convertView.findViewById(R.id.textView_superior);
viewContainer.descripcion=(TextView)convertView.findViewById(R.id.textView_inferior);
viewContainer.imagen=(ImageView)convertView.findViewById(R.id.imageView_imagen);
//asigna el contenedor de la vista a rowView
convertView.setTag(viewContainer);
}else{
viewContainer=(ViewContainer) convertView.getTag(); //recicling }
//personaliza el contenido de cada fila basándone en su posición
viewContainer.nombre.setText(listado.get(position).getNombre());
viewContainer.descripcion.setText(listado.get(position).getDescripcion());
viewContainer.imagen.setImageResource(listado.get(position).getIdImagen());
return(convertView);
}
45. Performance / Save Battery life
Useful for background tracking applications
Use “PASSIVE_PROVIDER” LocationProvider
(instead of “GPS_PROVIDER”)
LocationListener has three primary settings:
“provider” positioning technology (e.g. GPS, NETWORK)
“minTime” requested time (milliseconds) between location
updates
“minDistance” requested distance (m) that triggers updates
if (user_moving){
-Decrease LocationListener “minTime”
} else{
if(Stopped for a reasonable amount of time){
-Increase LocationListener “minTime”
}
}
47. DEPENDENCY INYECTION
RoboGuice / Dagger / ButterKnife
RoboGuice is a framework that brings the simplicity and ease of
Dependency Injection to Android.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
name = (TextView) findViewById(R.id.name);
myName = getString(R.string.app_name);
name.setText("Hello, " + myName);
}
@ ContentView(R.layout.main)
class MyActivity extends RoboActivity{
@InjectView(R.id.name) TextView name;
@InjectView(R.id.thumbnail) ImageView thumbnail;
@InjectResource(R.drawable.icon) Drawable icon;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
name.setText("Hello, " + myName);
}}
48. ButterKnife
Eliminate findViewById calls by using @InjectView
Eliminate anonymous inner-classes for listeners by annotating
methods with @OnClick
class ExampleActivity extends Activity {
@InjectView(R.id.name) EditText name;
@OnClick(R.id.submit) void submit() {
}
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_activity);
ButterKnife.inject(this);
}
}
https://github.com/JakeWharton/butterknife
49. Annotations
@EActivity(R.layout.translate) // Sets content view to R.layout.translate
public class TranslateActivity extends Activity {
@ViewById // Injects R.id.textInput
EditText textInput;
@ViewById(R.id.myTextView) // Injects R.id.myTextView
TextView result;
@AnimationRes // Injects android.R.anim.fade_in
Animation fadeIn;
@Click // When R.id.doTranslate button is clicked
void doTranslate() {
translateInBackground(textInput.getText().toString());
}
@Background // Executed in a background thread
void translateInBackground(String textToTranslate) {
String translatedText = callGoogleTranslate(textToTranslate);
showResult(translatedText);
}
@UiThread // Executed in the ui thread
void showResult(String translatedText) {
result.setText(translatedText);
result.startAnimation(fadeIn);
}
http://androidannotations.org/
50. Features
Check for API availability before using features
PackageManager pm = getPackageManager();
boolean hasCamera =
pm.hasSystemFeature(PackageManager.FEATURE_CAMERA);
if (hasCamera) {
// do things that require the camera
}
boolean hasBlueTooth =
pm.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
if (hasBlueTooth) {
// do things that require the blueTooth
}
<uses-feature android:name="android.hardware.bluetooth"/>
<uses-feature android:name="android.hardware.camera"/>
51. Restore state in activity
• If you support both orientations, save the instance state while
orientation changes for more responsiveness.
Before finish() an activity, onSaveInstanceState() is called to save UI
state.
Restore the Activity state after being created
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
}
52. LINT
Android comes with a tool called lint that can be used for
identifying and correcting structural problems with your code.
Each detection has an associated description and severity level
so it can be prioritized.
Can be invoked directly from the command-line, automated build
system or directly from Eclipse
53. VOLLEY
https://android.googlesource.com/platform/frameworks/volley
https://github.com/mcxiaoke/android-volley
Unzip and import from Eclipse as a new project with code available. Export
the project as Java Volley / jar checking only the "src" folder.
Volley is a library that facilitates and speeds up the creation of applications
that make use of networking in Android handling concurrency and network
requests.
The advantage is that volley is responsible for managing the request threads
transparently to the developer.
libsvolley.jar
Objects
RequestQueue
Request: Contains all the necessary details of API calls to Web. For example,
the method to use (GET or POST), application data, listeners, error listeners.
55. VOLLEY RESPONSE
//Callback that is executed once the request has completed
Response.Listener<JSONObject> successListener =
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
}
}
JSON Response by volley.Response object
More volley examples
https://github.com/PareshMayani/Android-Volley-Example
59. Libraries
Indicator in ViewPager
http://viewpagerindicator.com/
https://github.com/chrisbanes/ActionBar-PullToRefresh
Pager Sliding Tabstrip
https://github.com/astuetz/PagerSlidingTabStrip
Show routes in map.
https://github.com/tyczj/MapNavigator
60. Sliding Menu
Library to implement a sliding flyout with similar behavior to
navigation drawer
https://github.com/jfeinstein10/SlidingMenu
MessageBar
Library to improve toast messages
http://simonvt.github.io/MessageBar/
61. Fading Action Bar
Used in Google play music
https://github.com/ManuelPeinado/FadingActionBar
+
http://www.androidviews.net/ http://www.androidpatterns.com/