• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
ProTips DroidCon Paris 2013
 

ProTips DroidCon Paris 2013

on

  • 1,458 views

La conférence « ProTips » de Mathias Seguy (Android2EE). ...

La conférence « ProTips » de Mathias Seguy (Android2EE).
Cette conférence a eu lieu lors du BarCamp de la DroidCon Paris, Lundi 17 Juin 2013.
Si vous êtes un JUG ou un AUG et que cette conférence vous interesse, n'hésitez pas à me contacter.

Si vous souhaitez apprendre la technologie Android, contacter moi: mathias.seguy@android2ee.com, je suis formateur Android et les formations Android que je dispense sont exceptionnelles.

Speaker:Mathias est le fondateur de la société Android2ee spécialisée dans la technologie Android.
Il est :
• formateur Android,
• expert logiciel Android,
• speaker Android sur de grandes conférences Java : AndroidCon, Devoxx France, Eclipse Day Toulouse, JCertif Africa, Toulouse JUG, CocoAhead,…
• Rédacteur Android sur Developpez.com ;
• Programmateur Android : MyLight, MyTorch, MySensors, JCertifMobile disponibles sur GooglePlay ;
• Docteur en Mathématiques Fondamentales et Ingénieur de l’ENSEEIHT ;
• Expert technique de l’agence nationale de la recherche française ;
Il présentera au cours de cette conférence sa vision sur la mise en place d’une architecture d’une application Android pertinente et partagera les meilleurs pro-tips (astuces de pro) de sa connaissance. A ne pas manquez.

Mathias Séguy
mathias.seguy@android2ee.com
Fondateur Android2EE
Formation – Expertise – Consulting Android.
Ebooks pour apprendre la programmation sous Android.

Statistics

Views

Total Views
1,458
Views on SlideShare
1,332
Embed Views
126

Actions

Likes
2
Downloads
0
Comments
0

7 Embeds 126

http://www.android2ee.com 95
https://twitter.com 14
http://android2ee.com 10
http://www.paug.fr 3
https://web.tweetdeck.com 2
http://localhost 1
http://181.224.130.6 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    ProTips DroidCon Paris 2013 ProTips DroidCon Paris 2013 Presentation Transcript

    • vous présente :Spécialiste Android1
    • Android2EE est référencé en tant qu’organisme de formation, vous pouvez faire prendre en charge tout ou partiedu montant de cette formation par votre OPCA. Cette formation Initiation avancée à Android est éligible au titredu DIF et CIF.Lieu : Paris, Toulouse, LyonDurée : 3 joursPrix : 1680 €Lieu : Paris, Toulouse, LyonDurée : 5 joursPrix : 2980 €Lieu : Paris, Toulouse, LyonDurée : 3 joursPrix : 1780 €
    • Android2ee.comFormations:http://www.android2ee.com/fr/formations-android/inter-entrepriseshttp://www.android2ee.com/fr/formations-android/formation-completeOpen Ressourceshttp://www.android2ee.com/fr/videos/devoxx-android-a-quick-course-1http://www.android2ee.com/fr/livre-en-consultation/introduction-openbookhttp://www.android2ee.com/tutoriaux/appwidget.htmlmathias.seguy@android2ee.comhttps://github.com/MathiasSeguy-Android2EEhttp://fr.linkedin.com/pub/mathias-seguy/37/a71/a59https://plus.google.com/115788770291974884100/abouthttps://plus.google.com/b/109641731378552898326/109641731378552898326/abouthttp://fr.slideshare.net/Android2EEhttps://play.google.com/store/apps/developer?id=ANDROID2EEhttp://fr.twitter.com/#%21/android2ee@deprectaed use linkedInhttp://mathias-seguy.developpez.com/homepage/index.phphttp://blog.developpez.com/android2ee-mathias-seguy/To GDGVous souhaitez que je vienne faire une conférence dans votre AndroidUser Group.Contactez moi, je suis preneur.
    • 4
    • 5From Google I/O And DevoxxCe chapitre est un extrait des « meilleurs » proTips donnés par les équipes Google lors des GoogleI/O, notamment :•Android ProTips, Reto Meier, Google I/O 2011•Making Good Apps Great , Reto Meier, Google I/O 2012•Google I_O 2013 - Android Protips_ Making Apps Work Like Magic , Reto Meier, Google I/O 2013•Android Graphics, Animations and Tips & Tricks, Romain Guy & Chet Haase, Devoxx 2010Merci à eux pour ces présentations.
    • 6Statics as TemporariesUtiliser des variables statiques pour vos variablestemporairespublic boolean pointInArea(int x, int y, Area area) {Point testPoint = new Point(x, y);return area.intersect(testPoint);}static final Point tmpPoint = new Point();public boolean pointInArea(int x, int y, Area area) {tmpPoint.x = x;tmpPoint.y = y;return area.intersect(tmpPoint.yPoint);}Autoboxing creates ObjectsUtiliser les types primitifs, l’AutoBoxing créé desobjets!Est équivalent àfloat x = 5;Float y = x;doSomething(x);void doSomething(Float z) {}float x = 5;Float y = new Float(x);doSomething(new Float(x));void doSomething(Float z) {}Recycle those BitmapsLes ressources sont limitées,recyclez vos Bitmaps le plus tôtpossible (n’attendez pas laméthode finalize())Vous pensez que cela aide:Mais en fait vous souhaitez:// done using this one, clearreferencemyBitmap = null;// done using this one, recycle itmyBitmap.recycle();From Android Graphics, Animations and Tips & Tricks, Romain Guy & Chet Haase, Devoxx 2010
    • 7Use ViewStubLa ViewStub permet le lazy loading de layouts.<ViewStubandroid:id="@+id/stub_import"android:inflatedId="@+id/panel_import"android:layout="@layout/progress_overlay"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_gravity="bottom" />findViewById(R.id.stub_import).setVisibility(View.VISIBLE);// orView importPanel = ((ViewStub)findViewById(R.id.stub_import)).inflate();id/stub_importid/panel_importFrom Android Graphics, Animations and Tips & Tricks, Romain Guy & Chet Haase, Devoxx 2010
    • 8Use merge et include<!-- The merge tag must be the root tag --><mergexmlns:android="http://schemas.android.com/apk/res/android"><!-- Content --></merge><!– The include tag is the one to use--><LinearLayout …><include layout="@layout/subLayout" /><LinearLayout> .. </LinearLayout></LinearLayout>Without merge With mergeFrom Android Graphics, Animations and Tips & Tricks, Romain Guy & Chet Haase, Devoxx 2010
    • 9Compounds DrawablesUtiliser les balises android:drawable*** pour mettre desimages à droite, à gauche … de vos composants héritantde TextView (TextView, Button, EditText,…)<LinearLayoutandroid:orientation="horizontal"android:layout_width="fill_parent"android:layout_height="wrap_content"><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/icon" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/hello" /></LinearLayout><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/hello"android:drawableLeft="@drawable/icon" />Balisesandroid:drawableBottomandroid:drawableEndandroid:drawablePaddingandroid:drawableRightandroid:drawableStartandroid:drawableTopFrom Android Graphics, Animations and Tips & Tricks, Romain Guy & Chet Haase, Devoxx 2010
    • 10ListView and ArrayAdpater : Use ViewHolder and convertViewpublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder;if (convertView == null) {convertView = mInflater.inflate(R.layout.list_item_icon_text, parent, false);holder = new ViewHolder();holder.text = (TextView) convertView.findViewById(R.id.text);holder.icon = (ImageView) convertView.findViewById(R.id.icon);convertView.setTag(holder);} else {holder = (ViewHolder) convertView.getTag();}holder.text.setText(DATA[position]);holder.icon.setImageBitmap((position & 1) ==? mIcon1 : mIcon2);return convertView;}static class ViewHolder {TextView text;ImageView icon;}From Android Graphics, Animations and Tips & Tricks, Romain Guy & Chet Haase, Devoxx 2010
    • 11UUID : Unique User IDL’ UUID Pattern permet détecter lutilisateur plutôt que les installations. Si vous avez besoin d’identifier de manière unique lutilisateur quipossède l’application, ce pattern est à utiliser.private static String uniqueID = null;private static final String PREF_UNIQUE_ID = "PREF_UNIQUE_ID";public synchronized static String id(Context context) {if (uniqueID == null) {SharedPreferences sharedPrefs =context.getSharedPreferences(PREF_UNIQUE_ID, Context.MODE_PRIVATE);uniqueID = sharedPrefs.getString(PREF_UNIQUE_ID, null);if (uniqueID == null) {uniqueID = UUID.randomUUID().toString();Editor editor = sharedPrefs.edit();editor.putString(PREF_UNIQUE_ID, uniqueID);editor.commit();}}return uniqueID;}Android ProTips, Reto Meier, Google I/O 2011
    • 12Know your Network and Battery context<receiver android:name="DeviceStateReceiever" ><action android:name="android.intent.action.ACTION_DOCK_EVENT" /><action android:name="android.intent.action.ACTION_BATTERY_LOW" /><action android:name="android.intent.action.ACTION_POWER_CONNECTED" /><action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" /><action android:name="android.net.conn.CONNECTIVITY_CHANGE" /><action android:name="android.intent.action.BOOT_COMPLETED" /><action android:name="android.net.conn.CONNECTIVITY_CHANGE" /><action android:name="android.net.wifi.STATE_CHANGE" /></receiver>Android ProTips, Reto Meier, Google I/O 2011ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo activeNetwork = cm.getActiveNetworkInfo();boolean isConnected = activeNetwork.isConnectedOrConnecting();boolean isMobile = activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE;
    • 13KeyBoard and EditText : Customize KeyBoard and set ActionQuand vous définissez un champ de type EditText vous devez définir :• Son type de clavier 7• L’action IME• (et le Hint)<EditTextandroid:id="@+id/editEmailInput"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="@string/compose_email_hint"android:imeOptions="actionSend|flagNoEnterAction"android:inputType="textShortMessage|textAutoCorrect|textCapSentences" />Android ProTips, Reto Meier, Google I/O 2011EditText.OnEditorActionListener myActionListener = newEditText.OnEditorActionListener() {@Overridepublic boolean onEditorAction(EditText v, int actionId, KeyEvent event) {if (actionId == EditorInfo.IME_ACTION_DONE) {// do here your stuff freturn true;}return false;}};
    • 14Always be asynchronousRendez tout asynchrone en utilisant lesHandler, Asynctask, IntentService (le systèmedes Intents quoi), AsyncQueryHandler (leGetContentResolver en un sens), Loader(abstractClass) and CursorLoader (HoneyCombonly).public class TutoActivity extends Activity implements LoaderManager.LoaderCallbacks<Cursor> {SimpleCursorAdapter mAdapter;/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);// …// Create an empty adapter we will use to display the loaded data.mAdapter = new SimpleCursorAdapter(this,android.R.layout.simple_list_item_2, null,new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS },new int[] { android.R.id.text1, android.R.id.text2 }, 0);listView.setAdapter(mAdapter);// Prepare the loader. Either re-connect with an existing one,// or start a new one.getLoaderManager().initLoader(0, null, this);}// Callbackspublic Loader<Cursor> onCreateLoader(int id, Bundle args) {Uri baseUri = MyContentProvider.CONTENT_URI;return new CursorLoader(this, baseUri, null, null, null, null);}public void onLoadFinished(Loader<Cursor> loader, Cursor data) {mAdapter.swapCursor(data);}public void onLoaderReset(Loader<Cursor> loader) {mAdapter.swapCursor(null);}}Android ProTips, Reto Meier, Google I/O 2011
    • 15Use the big cookies strategy when possiblePréférez transférer un gros paquet de données au travers d’internet quand c’est possible plutôt que plein de petits paquets.Making Good Apps Great, Reto Meier, Google I/O 2012int prefetchCacheSize = DEFAULT_PREFETCH_CACHE;switch (activeNetwork.getType()) {case ConnectivityManager.TYPE_WIFI:prefetchCacheSize = MAX_PREFETCH_CACHE;break;case ConnectivityManager.TYPE_MOBILE): {switch (telephonyManager.getNetworkType()) {case TelephonyManager.NETWORK_TYPE_LTE:case TelephonyManager.NETWORK_TYPE_HSPAP:prefetchCacheSize *= 4; break;case TelephonyManager.NETWORK_TYPE_EDGE:case TelephonyManager.NETWORK_TYPE_GPRS:prefetchCacheSize /= 2; break;default: break;} break;}default: break;}
    • Use AndroidBeamParce que cest tout simple déchanger des données entre deux devices.Send Receive16Android Protips_ Making Apps Work Like Magic, Reto Meier, Google I/O 2013public void onResume() {super.onResume();NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);nfcAdapter.setNdefPushMessageCallback(new CreateNdefMessageCallback() {public NdefMessage createNdefMessage(NfcEvent event) {NdefMessage message = createMessage();return message;}}, this);// ...}private void createMessage() {String mimeType = "application/com.myapp.nfcbeam";byte[] mimeBytes = mimeType.getBytes(Charset.forName("US-ASCII"));String payLoad = ""; // TODO Contextualized payload.;NdefMessage nfcMessage = new NdefMessage(new NdefRecord[] {new NdefRecord(ndefRecord.TNF_MIME_MEDIA, mimeByes, newbyte[], payload.getBytes()),NdefRecord.createApplicationRecord("com.myapp.nfcbeam") });}private void extractPayload(Intent beamIntent) {Parcelable[] messages = beamIntent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);NdefAdapter message = (NdefMessage)message[0];NdefRecord record = message.getRecords()[0];String payload = new String(record.getPayload());navigateTo(payload);}<intent-filter><action android:name="android.nfc.action.NDEF_DISCOVERED"/><category android:name="android.intent.category.DEFAULT"/><data android:mimeType="application/com.myapp.nfcbeam"/></intent-filter>
    • LocationUtiliser le ServiceGooglePlay, il connait vos utilisateurs mieux que vous.17Android Protips_ Making Apps Work Like Magic, Reto Meier, Google I/O 2013private void connectLBS() {int gpsExists = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);if (gpsExists == ConnectionResult.SUCCESS) {mLocationClient = new LocationClient(this, this, this);mlocationClient.connect();}}@Overridepublic void onConnected(Bundle connectionHint) {requestUpdates(mlocationClient);}private void requestUpdates(LocationClient mlocationClient) {LocationRequest request = LocationRequest.create();request.setInterval(minTime);request.setPriority(lowPowerMoreImportantThanAccuracy ?LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY :LocationRequest.PRIORITY_HIGH_ACCURACY);mlocationClient.requestLocationUpdates(request, new LocationListener() {@Overridepublic void onLocationChanged(Location location) {updateLocation(location);}});}
    • Activity RecognitionAdapter vos applications au contexte utilisateur (devant la télé, en voiture, en vélo, à pied...).18Android Protips_ Making Apps Work Like Magic, Reto Meier, Google I/O 2013Intent intent = new Intent(this, ActivityRecognitionIntentService.class);intent.setAction(MyActivity.ACTION_STRING);PendingIntent pi =PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);mActivityRecognitionClient.requestActivityUpdates(interval, pi);@Overrideprotected void onHandleIntent(Intent intent) {if (intent.getAction() == MyActivity.ACTION_STRING) {if (ActivityRecognitionResult.hasResult(intent)) {ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);DetectedActivity detectedActivity = result.getMostProbableActivity();int activityType = detectedActivity.getType();if (activityType == DetectedActivity.STILL)setUpdateSpeed(PAUSED);else if (activityType == DetectedActivity.IN_VEHICLE)setUpdateSpeed(FASTER);elsesetUpdateSpeed(REGULAR);}}}
    • TextToSpeech : TTSDe parlez à vos utilisateurs, parfois cest super.Initialize Use19Android Protips_ Making Apps Work Like Magic, Reto Meier, Google I/O 2013private void initTextToSpeech() {Intent intent = new Intent(Engine.ACTION_CHECK_TTS_DATA);startActivityForResult(intent, TTS_DATA_CHECK);}protected void onActivityResult(int request, int result, Intent data) {if (request == TTS_DATA_CHECK &&result == Engine.CHECK_VOICE_DATA_PASS) {tts = new TextToSpeech(this, new OnInitListener() {public void onInit(int status) {if (status == TextToSpeech.SUCCESS)ttsIsInit = true;}});} elsestartActivity(new Intent(Engine.ACTION_INSTALL_TTS_DATA);}private void say(String text) {if (tts != null && ttisIsInit)tts.speak(text, TextToSpeech.QUEUE_ADD, null);}
    • Speech RecognitionDécouter vos utilisateurs, parfois cest encore plus super.Record Consume20Android Protips_ Making Apps Work Like Magic, Reto Meier, Google I/O 2013private void requestVoiceInput() {Intent intent = newIntent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);intent.putExtra(RecognizerIntent.EXTRA_PROMPT,getString(R.String.voice_input_prompt);intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE,Locale.ENGLISH);startActivityForResult(intent, VOICE_RECOGNITION);}@Overrideprotected void onActivityResult(int request, int result, Intent data){if (request == VOICE_RECOGNITION && result ==RESULT_OK) {ArrayList<String> results =data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);String mostLikelyResult = results[0];useSpeechInput(mostLikelyResult);}}
    • 21
    • 22From Google I/O 2012Ce chapitre est un extrait de la conférence des Google I/O 2012 :•Multiversioning Android, Bruno Oliveira & Adam Powell , Google I/O 2012Qui est exceptionnel sur la lutte contre la fragmentation, un très grand moment, merci à eux.
    • 23Be LazyUtiliser une classe abstraite qui sera instanciée par une factory et renverra l’implémentation correspondant à le version du système.Multiversioning Android, Bruno Oliveira & Adam Powell , Google I/O 2012public abstract class VersionedLoremIpsum {public abstract String doLorem();public abstract int doIpsum();}public class EclairLoremIpsumextends VersionedLoremIpsum {public String doLorem() {// do lorem, Eclair-style}public abstract int doIpsum() {// deliver ipsum, a là Eclair}}public class FroyoLoremIpsumextends EclairLoremIpsum {public String doLorem() {String l = super.doLorem();// additional processingreturn l;}public abstract int doIpsum() {...ActivityVersionedLoremIpsum li;li=VLIFactory.get()VLIFactorypublic static VersionedLoremIpsum get(int sdk = Build.VERSION.SDK_INT;if (sdk <= Build.VERSION_CODES.ECLAIR) {li = new EclairLoremIpsum();} else if (sdk <=Build.VERSION_CODES.FROYO) {li = new FroyoLoremIpsum();} else {li = new GingerbreadLoremIpsum();})
    • 24Resources are your best friend, use them.Utilisez des booléens pour savoir quelle est la version du système. Ils s’utilisent dans le code et dans le Manifest.xml.Multiversioning Android, Bruno Oliveira & Adam Powell , Google I/O 2012Manifest<receiver android:name="MyPreICSAppWidget"android:enabled="@bool/preICS">...</receiver><receiver android:name="MyPostICSAppWidget"android:enabled="@bool/postICS">...</receiver>SomeWhere in javaResources res = getResources();boolean postICS =res.getBoolean(R.bool.postICS);if (postICS) {// do something cool and cutting-edge} else {// do something old-school but elegant!}Resvalues-v14bools.xml<?xml version="1.0" encoding="utf-8"?><resources><bool name="postICS">true</bool><bool name="preICS">false</bool></resources>Resvaluesbools.xml<?xml version="1.0" encoding="utf-8"?><resources><bool name="postICS">false</bool><bool name="preICS">true</bool></resources>
    • 25Construisez vos Layouts dynamiquement en fonction de la version système.Utilisez merge et include pour construire des IHM qui s’adaptent à la version de manière transparente.Multiversioning Android, Bruno Oliveira & Adam Powell , Google I/O 2012Reslayoutmain.xml<?xml version="1.0" encoding="utf-8"?><LinearLayout ...<!-- non multi-versioned stuff here --><include layout="@layout/desserts" /><!-- more non multi-versioned stuff here --></LinearLayout>Reslayoutdesserts.xml<?xml ... ?><merge xmlns:android="..."><CheckBox ... /><CheckBox ... /><CheckBox ... />...</merge>Reslayout-v11desserts.xml<?xml ... ?><merge xmlns:android="..."><Switch ... /><Switch ... /><Switch ... />...</merge>
    • 26Hériter du thème de la version.Restez cohérent avec le thème du SDK de l’appareil cible, conservez une application cohérente avec l’appareil.Multiversioning Android, Bruno Oliveira & Adam Powell , Google I/O 2012MyThemeresvaluestheme.xml<style name=" MyBaseTheme" parent="@android:style/Theme" /><style name="MyTheme" parent="MyBaseTheme"><style name="MyButtonStyle" parent="@android:style/Widget.Button">resvalues-v11theme.xml<style name=" MyBaseTheme" parent="@android:style/Theme.Holo" /><style name="MyButtonStyle" parent="@android:style/Widget.Holo.Button">MyBaseThemeTheme Theme.Holo
    • 27Utiliser les Fragments et l’ActionBar sur toutes vos versions.Ayez une application identique quelque soit la version du système et utilisez le même fichier de layout.Multiversioning Android, Bruno Oliveira & Adam Powell , Google I/O 2012public class SpeakerDetailFragmentHC extends Fragment {public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {View view = inflater.inflate(R.layout.speaker_detail, container, false);return view;}public class SpeakerDetailFragment extends android.support.v4.app.Fragment {public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {View view = inflater.inflate(R.layout.speaker_detail, container, false);return view;}public class BaseActivityHC extends Activity{...}public class BaseActivityLegacy extends android.support.v4.app.FragmentActivity {...}android.support.v4.app.ActionBarActivity
    • private void pushInboxNotifications() {Notification notification = new Notification.Builder(this).setContentTitle("10 New emails for me").setContentText("subject").setSmallIcon(android.R.drawable.ic_menu_agenda).setStyle(Notification.InboxStyle).addLine("Line 1, i can add more if i want").addAction(R.drawable.icon,R.string.notification_message,new PendingIntent(....)).setSound(aSound).build();NotificationManagernotificationManager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);notificationManager.notify(0, notification);}28Utiliser les notifications PreJB, PostJB.Multiversioning Android, Bruno Oliveira & Adam Powell , Google I/O 2012if version >= JellyBeanuse Notification.Builderelseuse NotificationCompat.Builder
    • 29L’ordre des boutons a changé depuis ICS.Avant ICS le bouton OK est à gauche, le bouton non ou cancel à droite.Après ICS le bouton OK est à droite, le bouton non ou cancel à gauche.Multiversioning Android, Bruno Oliveira & Adam Powell , Google I/O 2012
    • <uses-sdkandroid:maxSdkVersion="16"android:minSdkVersion="8"android:targetSdkVersion="17" />30Min et target SDK importe.Multiversioning Android, Bruno Oliveira & Adam Powell , Google I/O 2012
    • 31
    • 32MinSDK=11 ?o? Utiliser le parrallel pattern.Deux types danimation incompatibles : Avant (TweenAnimation) Après (ObjectAnimator, ViewProperty) HoneyComb.CodeDependent Chet Haase http://graphics-geek.blogspot.fr/.Be short.Le temps danimation par défaut est de 300 ms.Cela dépend de lobjet à animer (une vue, une activité ce nest pas un bouton).Be Amazing... but once.Les animations longues, belles et délirantes deviennent ennuyeuses au bout de 3.Remplacer les par des animations efficaces au bout de 3.Si en développement votre animation ne vous pourrit pas la vie alors elle ne pourrira pas celle de vos utilisateurs.Thanks Chet.Depuis HoneyComb, les animations sont améliorées, simplifiées et super flexibles.Dev.Bytes nous poste des tutos de 3 minutes pour nous les apprendre.Merci à Chet Haase pour tout ça.
    • <LinearLayoutandroid:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"android:animateLayoutChanges="true"android:id="@+id/container"/>33MinSDK=16.Ajoutez cette balise à vos Layouts.Dès quun changement est détecté, il sera automatiquement animé pour le plaisir de vos utilisateurs.Dev.Bytes Chet Haase LayoutTransChanging https://www.youtube.com/watch?v=55wLsaWpQ4g.// Note that this assumes a LayoutTransition is set on the container, which is the// case here because the container has the attribute "animateLayoutChanges" set to true// in the layout file. You can also call setLayoutTransition(new LayoutTransition()) in// code to set a LayoutTransition on any container.LayoutTransition transition = container.getLayoutTransition();// New capability as of Jellybean; monitor the container for *all* layout changes// (not just add/remove/visibility changes) and animate these changes as well.transition.enableTransitionType(LayoutTransition.CHANGING);
    • // Create bitmap to be re-used, based on the size of one of the bitmapsmBitmapOptions = new BitmapFactory.Options();//Set for asking only the width and height of the bitmap, not the bitmap itselfmBitmapOptions.inJustDecodeBounds = true;//With that option, bitMap is not load, but its size is set in mBitmapOptions.outWidthand mBitmapOptions.outHeightBitmapFactory.decodeResource(getResources(), R.drawable.a, mBitmapOptions);//Then create bitmap object (still not displaying any drawable)mCurrentBitmap = Bitmap.createBitmap(mBitmapOptions.outWidth,mBitmapOptions.outHeight, Bitmap.Config.ARGB_8888);//Then change the inJustDecode for asking the bitmap itselfmBitmapOptions.inJustDecodeBounds = false;//Then define where the loaded bitmap will be drop in themBitmapOptions.inSampleSize = 1;//and finally load it (as mBitmapOptions.inBitmap = mCurrentBitmap, the loaded bitmapwill be in mCurrentBitmap)BitmapFactory.decodeResource(getResources(), R.drawable.a, mBitmapOptions);imageview.setImageBitmap(mCurrentBitmap);34MinSDK=15.Créer un objet BitMap et réutilisé le pour charger les images suivantes.Dev.Bytes Chet Haase Bitmap Allocation https://www.youtube.com/watch?v=rsQet4nBVi8mCurrentIndex = (mCurrentIndex + 1) % imageIDs.length;BitmapFactory.Options bitmapOptions = null;if (reuseBitmapAllocation) {}long startTime = System.currentTimeMillis();mCurrentBitmap = BitmapFactory.decodeResource(getResources(),imageIDs[mCurrentIndex], bitmapOptions);imageview.setImageBitmap(mCurrentBitmap);Premier chargement Chargements SuivantsmBitmapOptions.inBitmap = mCurrentBitmap;// Re-use the bitmap by using BitmapOptions.inBitmapbitmapOptions = mBitmapOptions;bitmapOptions.inBitmap = mCurrentBitmap;Allocation Mémoire et Garbage optimisésRapidité de chargement accrue
    • Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.jellybean_statue);originalImageView.setImageBitmap(bitmap);for (int i = 2; i < 10; ++i) {addScaledImageView(bitmap, i, container);}35MinSDK=15.Créer un objet BitMap et réutilisé le pour charger les images suivantes.Dev.Bytes Chet Haase LayoutTransChangingprivate Bitmap addScaledImageView(Bitmap original, int sampleSize, LinearLayout container) {// inSampleSize tells the loader how much to scale the final image, which it does at// load time by simply reading less pixels for every pixel value in the final bitmap.// Note that it only scales by powers of two, so a value of two results in a bitmap// 1/2 the size of the original and a value of four results in a bitmap 1/4 the original// size. Intermediate values are rounded down, so a value of three results in a bitmap 1/2// the original size.BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();Bitmap scaledBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.jellybean_statue, bitmapOptions);return scaledBitmap;}Chargement normalbitmapOptions.inSampleSize = sampleSize;Chargement réduit
    • static class MyView extends View {Bitmap mBitmap;Paint paint = new Paint();int mShapeX, mShapeY;int mShapeW, mShapeH;public MyView(Context context, AttributeSet attrs, int defStyle) {...; setupShape();}public MyView(Context context, AttributeSet attrs) {...; setupShape();}public MyView(Context context) {{...; setupShape();}private void setupShape() {Initialisation des objets graphiques...}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {//Initialisation des tailles des composants et des positionsmShapeX = (w - mBitmap.getWidth()) / 2;}36MinSDK=14.Animer vos vues. Vous pouvez en redéfinir une ou bien le mettre en place directement dans votre activité.Dev.Bytes Chet Haase Bouncer https://www.youtube.com/watch?v=vCTcmPIKgpMInitialisation de votre custom View
    • Dev.Bytes Chet Haase Bouncer https://www.youtube.com/watch?v=vCTcmPIKgpM37MinSDK=14.Mise en place de lanimation.1. Définir et lancer lanimation.void startAnimation() {// This variation uses an ObjectAnimator. The ObjectAnimator automatically animate the target object forus, so we no longer need to listen for frame updates and do that work ourselves.ObjectAnimator anim = getObjectAnimator();anim.setRepeatCount(ValueAnimator.INFINITE);anim.setRepeatMode(ValueAnimator.REVERSE);anim.setInterpolator(new AccelerateInterpolator());anim.start();}ObjectAnimator getObjectAnimator() {}public void setShapeY(int shapeY) {//Set the new valuemShapeY = shapeY;//Calculate the dirty area and ask to redraw itint minY = mShapeY;int maxY = mShapeY + mShapeH;minY = Math.min(mShapeY, minY);maxY = Math.max(mShapeY + mShapeH, maxY);//ask to redraw the rectangle areainvalidate(mShapeX, minY, mShapeX + mShapeW, maxY);}@Overrideprotected void onDraw(Canvas canvas) {canvas.drawBitmap(mBitmap, mShapeX, mShapeY, paint);}return ObjectAnimator.ofInt(this, "shapeY", 0, (getHeight() - mShapeH));2. Construire lObjectAnimator3. Mettre a jour les données graphiquesCalculer la zone a redessinerDemander le redraw4. Dessiner lobjet
    • // Create the AnimationDrawable in which we will store all frames of the animationfinal AnimationDrawable animationDrawable = new AnimationDrawable();for (int i = 0; i < 10; ++i) {animationDrawable.addFrame(createDrawableForFrameNumber(i), 300);}// Run until we say stopanimationDrawable.setOneShot(false);imageview.setImageDrawable(animationDrawable);animationDrawable.start();38MinSDK=14.Animer vos vues. Vous pouvez en redéfinir une ou bien le mettre en place directement dans votre activité.Dev.Bytes Chet Haase KeyframeAnimation https://www.youtube.com/watch?v=V3ksidLf7vAAnimationDrawableprivate BitmapDrawable createDrawableForFrameNumber(int frameNumber) {Bitmap bitmap = Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);canvas.drawColor(Color.GRAY);Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);paint.setTextSize(80);paint.setColor(Color.BLACK);canvas.drawText("Frame " + frameNumber, 40, 220, paint);return new BitmapDrawable(getResources(), bitmap);}Building a Bitmap from scratch
    • 39From Google I/O 2013By Chet Haase and Romain GuyGoogle I/o 2013 Romain Guy - Chet Haase "A Moving Experience" http://graphics-geek.blogspot.fr/2013/06/devbytes-animating-listview-deletion.htmlmListView.setEnabled(false);v.animate().setDuration(duration).alpha(endAlpha).translationX(endX).withEndAction(new Runnable() {@Overridepublic void run() {// Restore animated valuesv.setAlpha(1);v.setTranslationX(0);}});0.Lancement de lanimation dans View.OnTouchListener# MotionEvent.ACTION_UPanimateRemoval(mListView, v);
    • Google I/o 2013 Romain Guy - Chet Haase "A Moving Experience" http://graphics-geek.blogspot.fr/2013/06/devbytes-animating-listview-deletion.html40From Google I/O 2013By Chet Haase and Romain Guyprivate void animateRemoval(final ListView listview, View viewToRemove) {observer.removeOnPreDrawListener(this);for (int i = 0; i < listview.getChildCount(); ++i) {child.setTranslationY(delta);if (firstAnimation) {child.animate().withEndAction(new Runnable() {public void run() {mBackgroundContainer.hideBackground();mSwiping = false;mListView.setEnabled(true);}});mItemIdTopMap.clear();return true;}});final ViewTreeObserver observer = listview.getViewTreeObserver();observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {public boolean onPreDraw() {child.animate().setDuration(MOVE_DURATION).translationY(0);1.Récupération du ViewTreeObserver2.Ajout du Listener PreDraw3.Mise en place de lanimation dans le preDraw
    • 41And of course thanks to
    • Merci pour votre attention.android2ee.com.#android2eemathias.seguy@android2ee.com42MyTorchMyLightMySensor My GooglePublic Profile