diff --git a/samples/devbytes/animation/Bouncer/AndroidManifest.xml b/samples/devbytes/animation/Bouncer/AndroidManifest.xml new file mode 100644 index 000000000..ff10b726f --- /dev/null +++ b/samples/devbytes/animation/Bouncer/AndroidManifest.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/devbytes/animation/Bouncer/res/drawable-hdpi/ic_launcher.png b/samples/devbytes/animation/Bouncer/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 000000000..96a442e5b Binary files /dev/null and b/samples/devbytes/animation/Bouncer/res/drawable-hdpi/ic_launcher.png differ diff --git a/samples/devbytes/animation/Bouncer/res/drawable-mdpi/ic_launcher.png b/samples/devbytes/animation/Bouncer/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 000000000..359047dfa Binary files /dev/null and b/samples/devbytes/animation/Bouncer/res/drawable-mdpi/ic_launcher.png differ diff --git a/samples/devbytes/animation/Bouncer/res/drawable-nodpi/electricsheep.png b/samples/devbytes/animation/Bouncer/res/drawable-nodpi/electricsheep.png new file mode 100644 index 000000000..22b224ab8 Binary files /dev/null and b/samples/devbytes/animation/Bouncer/res/drawable-nodpi/electricsheep.png differ diff --git a/samples/devbytes/animation/Bouncer/res/drawable-xhdpi/ic_launcher.png b/samples/devbytes/animation/Bouncer/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 000000000..71c6d760f Binary files /dev/null and b/samples/devbytes/animation/Bouncer/res/drawable-xhdpi/ic_launcher.png differ diff --git a/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer.xml b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer.xml new file mode 100644 index 000000000..543951b03 --- /dev/null +++ b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer.xml @@ -0,0 +1,28 @@ + + + + + + diff --git a/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer1.xml b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer1.xml new file mode 100644 index 000000000..765f6aefd --- /dev/null +++ b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer1.xml @@ -0,0 +1,28 @@ + + + + + + diff --git a/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer2.xml b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer2.xml new file mode 100644 index 000000000..db21eee3d --- /dev/null +++ b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer2.xml @@ -0,0 +1,28 @@ + + + + + + diff --git a/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer3.xml b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer3.xml new file mode 100644 index 000000000..a1a6911cf --- /dev/null +++ b/samples/devbytes/animation/Bouncer/res/layout/activity_bouncer3.xml @@ -0,0 +1,28 @@ + + + + + + diff --git a/samples/devbytes/animation/Bouncer/res/values-v11/styles.xml b/samples/devbytes/animation/Bouncer/res/values-v11/styles.xml new file mode 100644 index 000000000..c16b77bf8 --- /dev/null +++ b/samples/devbytes/animation/Bouncer/res/values-v11/styles.xml @@ -0,0 +1,19 @@ + + + + + + diff --git a/samples/devbytes/animation/ListViewAnimations/res/values-v14/styles.xml b/samples/devbytes/animation/ListViewAnimations/res/values-v14/styles.xml new file mode 100644 index 000000000..8ac452213 --- /dev/null +++ b/samples/devbytes/animation/ListViewAnimations/res/values-v14/styles.xml @@ -0,0 +1,26 @@ + + + + + + + diff --git a/samples/devbytes/animation/ListViewAnimations/res/values/strings.xml b/samples/devbytes/animation/ListViewAnimations/res/values/strings.xml new file mode 100644 index 000000000..5b41f5b66 --- /dev/null +++ b/samples/devbytes/animation/ListViewAnimations/res/values/strings.xml @@ -0,0 +1,21 @@ + + + + ListViewAnimations + ViewPropertyAnimator + Transient State + + diff --git a/samples/devbytes/animation/ListViewAnimations/res/values/styles.xml b/samples/devbytes/animation/ListViewAnimations/res/values/styles.xml new file mode 100644 index 000000000..f9460a7e5 --- /dev/null +++ b/samples/devbytes/animation/ListViewAnimations/res/values/styles.xml @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/samples/devbytes/animation/ListViewAnimations/src/com/example/android/listviewanimations/Cheeses.java b/samples/devbytes/animation/ListViewAnimations/src/com/example/android/listviewanimations/Cheeses.java new file mode 100644 index 000000000..69c027db1 --- /dev/null +++ b/samples/devbytes/animation/ListViewAnimations/src/com/example/android/listviewanimations/Cheeses.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * 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.example.android.listviewanimations; + +public class Cheeses { + + public static final String[] sCheeseStrings = { + "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi", + "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale", + "Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese", + "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell", + "Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc", + "Asadero", "Asiago", "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss", + "Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", "Banon", + "Barry's Bay Cheddar", "Basing", "Basket Cheese", "Bath Cheese", "Bavarian Bergkase", + "Baylough", "Beaufort", "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese", + "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir", "Bierkase", "Bishop Kennedy", + "Blarney", "Bleu d'Auvergne", "Bleu de Gex", "Bleu de Laqueuille", + "Bleu de Septmoncel", "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore", + "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini", "Bocconcini (Australian)", + "Boeren Leidenkaas", "Bonchester", "Bosworth", "Bougon", "Boule Du Roves", + "Boulette d'Avesnes", "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur", + "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois", "Brebis du Puyfaucon", + "Bresse Bleu", "Brick", "Brie", "Brie de Meaux", "Brie de Melun", "Brillat-Savarin", + "Brin", "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)", + "Briquette de Brebis", "Briquette du Forez", "Broccio", "Broccio Demi-Affine", + "Brousse du Rove", "Bruder Basil", "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza", + "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase", "Button (Innes)", + "Buxton Blue", "Cabecou", "Caboc", "Cabrales", "Cachaille", "Caciocavallo", "Caciotta", + "Caerphilly", "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie", + "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux", "Capricorn Goat", + "Capriole Banon", "Carre de l'Est", "Casciotta di Urbino", "Cashel Blue", "Castellano", + "Castelleno", "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain", + "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou", "Chabichou du Poitou", + "Chabis de Gatine", "Chaource", "Charolais", "Chaumes", "Cheddar", + "Cheddar Clothbound", "Cheshire", "Chevres", "Chevrotin des Aravis", "Chontaleno", + "Civray", "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby", "Cold Pack", + "Comte", "Coolea", "Cooleney", "Coquetdale", "Corleggy", "Cornish Pepper", + "Cotherstone", "Cotija", "Cottage Cheese", "Cottage Cheese (Australian)", + "Cougar Gold", "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese", + "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza", + "Croghan", "Crottin de Chavignol", "Crottin du Chavignol", "Crowdie", "Crowley", + "Cuajada", "Curd", "Cure Nantais", "Curworthy", "Cwmtawe Pecorino", + "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo", "Danish Fontina", + "Daralagjazsky", "Dauphin", "Delice des Fiouves", "Denhany Dorset Drum", "Derby", + "Dessertnyj Belyj", "Devon Blue", "Devon Garland", "Dolcelatte", "Doolin", + "Doppelrhamstufel", "Dorset Blue Vinney", "Double Gloucester", "Double Worcester", + "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra", "Dunlop", "Dunsyre Blue", + "Duroblando", "Durrus", "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz", + "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne", "Esbareich", + "Esrom", "Etorki", "Evansdale Farmhouse Brie", "Evora De L'Alentejo", "Exmoor Blue", + "Explorateur", "Feta", "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle", + "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis", "Flor de Guia", + "Flower Marie", "Folded", "Folded cheese with mint", "Fondant de Brebis", + "Fontainebleau", "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus", + "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire", "Fourme de Montbrison", + "Fresh Jack", "Fresh Mozzarella", "Fresh Ricotta", "Fresh Truffles", "Fribourgeois", + "Friesekaas", "Friesian", "Friesla", "Frinault", "Fromage a Raclette", "Fromage Corse", + "Fromage de Montagne de Savoie", "Fromage Frais", "Fruit Cream Cheese", + "Frying Cheese", "Fynbo", "Gabriel", "Galette du Paludier", "Galette Lyonnaise", + "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail", "Garrotxa", "Gastanberra", + "Geitost", "Gippsland Blue", "Gjetost", "Gloucester", "Golden Cross", "Gorgonzola", + "Gornyaltajski", "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost", + "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel", + "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh", "Greve", + "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny", "Halloumi", + "Halloumy (Australian)", "Haloumi-Style Cheese", "Harbourne Blue", "Havarti", + "Heidi Gruyere", "Hereford Hop", "Herrgardsost", "Herriot Farmhouse", "Herve", + "Hipi Iti", "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster", + "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu", "Isle of Mull", "Jarlsberg", + "Jermi Tortes", "Jibneh Arabieh", "Jindi Brie", "Jubilee Blue", "Juustoleipa", + "Kadchgall", "Kaseri", "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine", + "Kikorangi", "King Island Cape Wickham Brie", "King River Gold", "Klosterkaese", + "Knockalara", "Kugelkase", "L'Aveyronnais", "L'Ecir de l'Aubrac", "La Taupiniere", + "La Vache Qui Rit", "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire", + "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin", "Le Fium Orbo", "Le Lacandou", + "Le Roule", "Leafield", "Lebbene", "Leerdammer", "Leicester", "Leyden", "Limburger", + "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer", "Little Rydings", + "Livarot", "Llanboidy", "Llanglofan Farmhouse", "Loch Arthur Farmhouse", + "Loddiswell Avondale", "Longhorn", "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam", + "Macconais", "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego", + "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses", "Maredsous", "Margotin", + "Maribo", "Maroilles", "Mascares", "Mascarpone", "Mascarpone (Australian)", + "Mascarpone Torta", "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse", + "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)", "Meyer Vintage Gouda", + "Mihalic Peynir", "Milleens", "Mimolette", "Mine-Gabhar", "Mini Baby Bells", "Mixte", + "Molbo", "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio", + "Monterey Jack", "Monterey Jack Dry", "Morbier", "Morbier Cru de Montagne", + "Mothais a la Feuille", "Mozzarella", "Mozzarella (Australian)", + "Mozzarella di Bufala", "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster", + "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais", "Neufchatel", + "Neufchatel (Australian)", "Niolo", "Nokkelost", "Northumberland", "Oaxaca", + "Olde York", "Olivet au Foin", "Olivet Bleu", "Olivet Cendre", + "Orkney Extra Mature Cheddar", "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty", + "Oszczypek", "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer", "Panela", + "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)", "Parmigiano Reggiano", + "Pas de l'Escalette", "Passendale", "Pasteurized Processed", "Pate de Fromage", + "Patefine Fort", "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac", "Pave du Berry", + "Pecorino", "Pecorino in Walnut Leaves", "Pecorino Romano", "Peekskill Pyramid", + "Pelardon des Cevennes", "Pelardon des Corbieres", "Penamellera", "Penbryn", + "Pencarreg", "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse", + "Picodon de Chevre", "Picos de Europa", "Piora", "Pithtviers au Foin", + "Plateau de Herve", "Plymouth Cheese", "Podhalanski", "Poivre d'Ane", "Polkolbin", + "Pont l'Eveque", "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre", + "Pourly", "Prastost", "Pressato", "Prince-Jean", "Processed Cheddar", "Provolone", + "Provolone (Australian)", "Pyengana Cheddar", "Pyramide", "Quark", + "Quark (Australian)", "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit", + "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango", "Queso de Murcia", + "Queso del Montsec", "Queso del Tietar", "Queso Fresco", "Queso Fresco (Adobera)", + "Queso Iberico", "Queso Jalapeno", "Queso Majorero", "Queso Media Luna", + "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette", "Ragusano", "Raschera", + "Reblochon", "Red Leicester", "Regal de la Dombes", "Reggianito", "Remedou", + "Requeson", "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata", "Ridder", + "Rigotte", "Rocamadour", "Rollot", "Romano", "Romans Part Dieu", "Roncal", "Roquefort", + "Roule", "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu", "Saaland Pfarr", + "Saanenkaese", "Saga", "Sage Derby", "Sainte Maure", "Saint-Marcellin", + "Saint-Nectaire", "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre", + "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza", "Schabzieger", "Schloss", + "Selles sur Cher", "Selva", "Serat", "Seriously Strong Cheddar", "Serra da Estrela", + "Sharpam", "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene", "Smoked Gouda", + "Somerset Brie", "Sonoma Jack", "Sottocenare al Tartufo", "Soumaintrain", + "Sourire Lozerien", "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese", + "Stilton", "Stinking Bishop", "String", "Sussex Slipcote", "Sveciaost", "Swaledale", + "Sweet Style Swiss", "Swiss", "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie", + "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea", "Testouri", + "Tete de Moine", "Tetilla", "Texas Goat Cheese", "Tibet", "Tillamook Cheddar", + "Tilsit", "Timboon Brie", "Toma", "Tomme Brulee", "Tomme d'Abondance", + "Tomme de Chevre", "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans", "Tommes", + "Torta del Casar", "Toscanello", "Touree de L'Aubier", "Tourmalet", + "Trappe (Veritable)", "Trois Cornes De Vendee", "Tronchon", "Trou du Cru", "Truffe", + "Tupi", "Turunmaa", "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa", + "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco", "Vendomois", + "Vieux Corse", "Vignotte", "Vulscombe", "Waimata Farmhouse Blue", + "Washed Rind Cheese (Australian)", "Waterloo", "Weichkaese", "Wellington", + "Wensleydale", "White Stilton", "Whitestone Farmhouse", "Wigmore", "Woodside Cabecou", + "Xanadu", "Xynotyro", "Yarg Cornish", "Yarra Valley Pyramid", "Yorkshire Blue", + "Zamorano", "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano" + }; + +} diff --git a/samples/devbytes/animation/ListViewAnimations/src/com/example/android/listviewanimations/ListViewAnimations.java b/samples/devbytes/animation/ListViewAnimations/src/com/example/android/listviewanimations/ListViewAnimations.java new file mode 100644 index 000000000..2d2cc683f --- /dev/null +++ b/samples/devbytes/animation/ListViewAnimations/src/com/example/android/listviewanimations/ListViewAnimations.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * 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.example.android.listviewanimations; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; +import android.app.Activity; +import android.content.Context; +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.CheckBox; +import android.widget.ListView; + +/** + * This example shows how animating ListView items can lead to problems as views are recycled, + * and how to perform these types of animations correctly with new API added in Jellybean. + * + * Watch the associated video for this demo on the DevBytes channel of developer.android.com + * or on YouTube at https://www.youtube.com/watch?v=8MIfSxgsHIs. + */ +public class ListViewAnimations extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_list_view_animations); + + final CheckBox vpaCB = (CheckBox) findViewById(R.id.vpaCB); + final CheckBox setTransientStateCB = (CheckBox) findViewById(R.id.setTransientStateCB); + final ListView listview = (ListView) findViewById(R.id.listview); + final ArrayList cheeseList = new ArrayList(); + for (int i = 0; i < Cheeses.sCheeseStrings.length; ++i) { + cheeseList.add(Cheeses.sCheeseStrings[i]); + } + final StableArrayAdapter adapter = new StableArrayAdapter(this, + android.R.layout.simple_list_item_1, cheeseList); + listview.setAdapter(adapter); + + listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { + + @Override + public void onItemClick(AdapterView parent, final View view, int position, long id) { + final String item = (String) parent.getItemAtPosition(position); + if (vpaCB.isChecked()) { + view.animate().setDuration(1000).alpha(0). + withEndAction(new Runnable() { + @Override + public void run() { + cheeseList.remove(item); + adapter.notifyDataSetChanged(); + view.setAlpha(1); + } + }); + } else { + // Here's where the problem starts - this animation will animate a View object. + // But that View may get recycled if it is animated out of the container, + // and the animation will continue to fade a view that now contains unrelated + // content. + ObjectAnimator anim = ObjectAnimator.ofFloat(view, View.ALPHA, 0); + anim.setDuration(1000); + if (setTransientStateCB.isChecked()) { + // Here's the correct way to do this: if you tell a view that it has + // transientState, then ListView ill avoid recycling it until the + // transientState flag is reset. + // A different approach is to use ViewPropertyAnimator, which sets the + // transientState flag internally. + view.setHasTransientState(true); + } + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + cheeseList.remove(item); + adapter.notifyDataSetChanged(); + view.setAlpha(1); + if (setTransientStateCB.isChecked()) { + view.setHasTransientState(false); + } + } + }); + anim.start(); + + } + } + + }); + } + + private class StableArrayAdapter extends ArrayAdapter { + + HashMap mIdMap = new HashMap(); + + public StableArrayAdapter(Context context, int textViewResourceId, + List objects) { + super(context, textViewResourceId, objects); + for (int i = 0; i < objects.size(); ++i) { + mIdMap.put(objects.get(i), i); + } + } + + @Override + public long getItemId(int position) { + String item = getItem(position); + return mIdMap.get(item); + } + + @Override + public boolean hasStableIds() { + return true; + } + + } + +} diff --git a/samples/devbytes/animation/PictureViewer/AndroidManifest.xml b/samples/devbytes/animation/PictureViewer/AndroidManifest.xml new file mode 100644 index 000000000..6cb909eda --- /dev/null +++ b/samples/devbytes/animation/PictureViewer/AndroidManifest.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + diff --git a/samples/devbytes/animation/PictureViewer/res/drawable-hdpi/ic_launcher.png b/samples/devbytes/animation/PictureViewer/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 000000000..96a442e5b Binary files /dev/null and b/samples/devbytes/animation/PictureViewer/res/drawable-hdpi/ic_launcher.png differ diff --git a/samples/devbytes/animation/PictureViewer/res/drawable-mdpi/ic_launcher.png b/samples/devbytes/animation/PictureViewer/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 000000000..359047dfa Binary files /dev/null and b/samples/devbytes/animation/PictureViewer/res/drawable-mdpi/ic_launcher.png differ diff --git a/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p1.jpg b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p1.jpg new file mode 100644 index 000000000..974581894 Binary files /dev/null and b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p1.jpg differ diff --git a/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p2.jpg b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p2.jpg new file mode 100644 index 000000000..db8731f01 Binary files /dev/null and b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p2.jpg differ diff --git a/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p3.jpg b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p3.jpg new file mode 100644 index 000000000..b240b3a02 Binary files /dev/null and b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p3.jpg differ diff --git a/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p4.jpg b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p4.jpg new file mode 100644 index 000000000..4de929221 Binary files /dev/null and b/samples/devbytes/animation/PictureViewer/res/drawable-nodpi/p4.jpg differ diff --git a/samples/devbytes/animation/PictureViewer/res/drawable-xhdpi/ic_launcher.png b/samples/devbytes/animation/PictureViewer/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 000000000..71c6d760f Binary files /dev/null and b/samples/devbytes/animation/PictureViewer/res/drawable-xhdpi/ic_launcher.png differ diff --git a/samples/devbytes/animation/PictureViewer/res/layout/activity_picture_viewer.xml b/samples/devbytes/animation/PictureViewer/res/layout/activity_picture_viewer.xml new file mode 100644 index 000000000..599c770b6 --- /dev/null +++ b/samples/devbytes/animation/PictureViewer/res/layout/activity_picture_viewer.xml @@ -0,0 +1,35 @@ + + + + + + + + diff --git a/samples/devbytes/animation/PictureViewer/res/values-v11/styles.xml b/samples/devbytes/animation/PictureViewer/res/values-v11/styles.xml new file mode 100644 index 000000000..c16b77bf8 --- /dev/null +++ b/samples/devbytes/animation/PictureViewer/res/values-v11/styles.xml @@ -0,0 +1,19 @@ + + + + + + diff --git a/samples/devbytes/ui/ListViewDeletion/res/values-v14/styles.xml b/samples/devbytes/ui/ListViewDeletion/res/values-v14/styles.xml new file mode 100644 index 000000000..8ac452213 --- /dev/null +++ b/samples/devbytes/ui/ListViewDeletion/res/values-v14/styles.xml @@ -0,0 +1,26 @@ + + + + + + + diff --git a/samples/devbytes/ui/ListViewDeletion/res/values/strings.xml b/samples/devbytes/ui/ListViewDeletion/res/values/strings.xml new file mode 100644 index 000000000..7801d600a --- /dev/null +++ b/samples/devbytes/ui/ListViewDeletion/res/values/strings.xml @@ -0,0 +1,21 @@ + + + + ListViewDeletion + Use Positions + Delete Selected + + diff --git a/samples/devbytes/ui/ListViewDeletion/res/values/styles.xml b/samples/devbytes/ui/ListViewDeletion/res/values/styles.xml new file mode 100644 index 000000000..f9460a7e5 --- /dev/null +++ b/samples/devbytes/ui/ListViewDeletion/res/values/styles.xml @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/samples/devbytes/ui/ListViewDeletion/src/com/example/android/listviewdeletion/Cheeses.java b/samples/devbytes/ui/ListViewDeletion/src/com/example/android/listviewdeletion/Cheeses.java new file mode 100644 index 000000000..4bdd858e8 --- /dev/null +++ b/samples/devbytes/ui/ListViewDeletion/src/com/example/android/listviewdeletion/Cheeses.java @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * 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.example.android.listviewdeletion; + +public class Cheeses { + + public static final String[] sCheeseStrings = { + "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi", + "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale", + "Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese", + "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell", + "Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc", + "Asadero", "Asiago", "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss", + "Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", "Banon", + "Barry's Bay Cheddar", "Basing", "Basket Cheese", "Bath Cheese", "Bavarian Bergkase", + "Baylough", "Beaufort", "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese", + "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir", "Bierkase", "Bishop Kennedy", + "Blarney", "Bleu d'Auvergne", "Bleu de Gex", "Bleu de Laqueuille", + "Bleu de Septmoncel", "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore", + "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini", "Bocconcini (Australian)", + "Boeren Leidenkaas", "Bonchester", "Bosworth", "Bougon", "Boule Du Roves", + "Boulette d'Avesnes", "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur", + "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois", "Brebis du Puyfaucon", + "Bresse Bleu", "Brick", "Brie", "Brie de Meaux", "Brie de Melun", "Brillat-Savarin", + "Brin", "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)", + "Briquette de Brebis", "Briquette du Forez", "Broccio", "Broccio Demi-Affine", + "Brousse du Rove", "Bruder Basil", "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza", + "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase", "Button (Innes)", + "Buxton Blue", "Cabecou", "Caboc", "Cabrales", "Cachaille", "Caciocavallo", "Caciotta", + "Caerphilly", "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie", + "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux", "Capricorn Goat", + "Capriole Banon", "Carre de l'Est", "Casciotta di Urbino", "Cashel Blue", "Castellano", + "Castelleno", "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain", + "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou", "Chabichou du Poitou", + "Chabis de Gatine", "Chaource", "Charolais", "Chaumes", "Cheddar", + "Cheddar Clothbound", "Cheshire", "Chevres", "Chevrotin des Aravis", "Chontaleno", + "Civray", "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby", "Cold Pack", + "Comte", "Coolea", "Cooleney", "Coquetdale", "Corleggy", "Cornish Pepper", + "Cotherstone", "Cotija", "Cottage Cheese", "Cottage Cheese (Australian)", + "Cougar Gold", "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese", + "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza", + "Croghan", "Crottin de Chavignol", "Crottin du Chavignol", "Crowdie", "Crowley", + "Cuajada", "Curd", "Cure Nantais", "Curworthy", "Cwmtawe Pecorino", + "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo", "Danish Fontina", + "Daralagjazsky", "Dauphin", "Delice des Fiouves", "Denhany Dorset Drum", "Derby", + "Dessertnyj Belyj", "Devon Blue", "Devon Garland", "Dolcelatte", "Doolin", + "Doppelrhamstufel", "Dorset Blue Vinney", "Double Gloucester", "Double Worcester", + "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra", "Dunlop", "Dunsyre Blue", + "Duroblando", "Durrus", "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz", + "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne", "Esbareich", + "Esrom", "Etorki", "Evansdale Farmhouse Brie", "Evora De L'Alentejo", "Exmoor Blue", + "Explorateur", "Feta", "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle", + "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis", "Flor de Guia", + "Flower Marie", "Folded", "Folded cheese with mint", "Fondant de Brebis", + "Fontainebleau", "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus", + "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire", "Fourme de Montbrison", + "Fresh Jack", "Fresh Mozzarella", "Fresh Ricotta", "Fresh Truffles", "Fribourgeois", + "Friesekaas", "Friesian", "Friesla", "Frinault", "Fromage a Raclette", "Fromage Corse", + "Fromage de Montagne de Savoie", "Fromage Frais", "Fruit Cream Cheese", + "Frying Cheese", "Fynbo", "Gabriel", "Galette du Paludier", "Galette Lyonnaise", + "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail", "Garrotxa", "Gastanberra", + "Geitost", "Gippsland Blue", "Gjetost", "Gloucester", "Golden Cross", "Gorgonzola", + "Gornyaltajski", "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost", + "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel", + "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh", "Greve", + "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny", "Halloumi", + "Halloumy (Australian)", "Haloumi-Style Cheese", "Harbourne Blue", "Havarti", + "Heidi Gruyere", "Hereford Hop", "Herrgardsost", "Herriot Farmhouse", "Herve", + "Hipi Iti", "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster", + "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu", "Isle of Mull", "Jarlsberg", + "Jermi Tortes", "Jibneh Arabieh", "Jindi Brie", "Jubilee Blue", "Juustoleipa", + "Kadchgall", "Kaseri", "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine", + "Kikorangi", "King Island Cape Wickham Brie", "King River Gold", "Klosterkaese", + "Knockalara", "Kugelkase", "L'Aveyronnais", "L'Ecir de l'Aubrac", "La Taupiniere", + "La Vache Qui Rit", "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire", + "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin", "Le Fium Orbo", "Le Lacandou", + "Le Roule", "Leafield", "Lebbene", "Leerdammer", "Leicester", "Leyden", "Limburger", + "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer", "Little Rydings", + "Livarot", "Llanboidy", "Llanglofan Farmhouse", "Loch Arthur Farmhouse", + "Loddiswell Avondale", "Longhorn", "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam", + "Macconais", "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego", + "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses", "Maredsous", "Margotin", + "Maribo", "Maroilles", "Mascares", "Mascarpone", "Mascarpone (Australian)", + "Mascarpone Torta", "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse", + "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)", "Meyer Vintage Gouda", + "Mihalic Peynir", "Milleens", "Mimolette", "Mine-Gabhar", "Mini Baby Bells", "Mixte", + "Molbo", "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio", + "Monterey Jack", "Monterey Jack Dry", "Morbier", "Morbier Cru de Montagne", + "Mothais a la Feuille", "Mozzarella", "Mozzarella (Australian)", + "Mozzarella di Bufala", "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster", + "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais", "Neufchatel", + "Neufchatel (Australian)", "Niolo", "Nokkelost", "Northumberland", "Oaxaca", + "Olde York", "Olivet au Foin", "Olivet Bleu", "Olivet Cendre", + "Orkney Extra Mature Cheddar", "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty", + "Oszczypek", "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer", "Panela", + "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)", "Parmigiano Reggiano", + "Pas de l'Escalette", "Passendale", "Pasteurized Processed", "Pate de Fromage", + "Patefine Fort", "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac", "Pave du Berry", + "Pecorino", "Pecorino in Walnut Leaves", "Pecorino Romano", "Peekskill Pyramid", + "Pelardon des Cevennes", "Pelardon des Corbieres", "Penamellera", "Penbryn", + "Pencarreg", "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse", + "Picodon de Chevre", "Picos de Europa", "Piora", "Pithtviers au Foin", + "Plateau de Herve", "Plymouth Cheese", "Podhalanski", "Poivre d'Ane", "Polkolbin", + "Pont l'Eveque", "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre", + "Pourly", "Prastost", "Pressato", "Prince-Jean", "Processed Cheddar", "Provolone", + "Provolone (Australian)", "Pyengana Cheddar", "Pyramide", "Quark", + "Quark (Australian)", "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit", + "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango", "Queso de Murcia", + "Queso del Montsec", "Queso del Tietar", "Queso Fresco", "Queso Fresco (Adobera)", + "Queso Iberico", "Queso Jalapeno", "Queso Majorero", "Queso Media Luna", + "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette", "Ragusano", "Raschera", + "Reblochon", "Red Leicester", "Regal de la Dombes", "Reggianito", "Remedou", + "Requeson", "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata", "Ridder", + "Rigotte", "Rocamadour", "Rollot", "Romano", "Romans Part Dieu", "Roncal", "Roquefort", + "Roule", "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu", "Saaland Pfarr", + "Saanenkaese", "Saga", "Sage Derby", "Sainte Maure", "Saint-Marcellin", + "Saint-Nectaire", "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre", + "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza", "Schabzieger", "Schloss", + "Selles sur Cher", "Selva", "Serat", "Seriously Strong Cheddar", "Serra da Estrela", + "Sharpam", "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene", "Smoked Gouda", + "Somerset Brie", "Sonoma Jack", "Sottocenare al Tartufo", "Soumaintrain", + "Sourire Lozerien", "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese", + "Stilton", "Stinking Bishop", "String", "Sussex Slipcote", "Sveciaost", "Swaledale", + "Sweet Style Swiss", "Swiss", "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie", + "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea", "Testouri", + "Tete de Moine", "Tetilla", "Texas Goat Cheese", "Tibet", "Tillamook Cheddar", + "Tilsit", "Timboon Brie", "Toma", "Tomme Brulee", "Tomme d'Abondance", + "Tomme de Chevre", "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans", "Tommes", + "Torta del Casar", "Toscanello", "Touree de L'Aubier", "Tourmalet", + "Trappe (Veritable)", "Trois Cornes De Vendee", "Tronchon", "Trou du Cru", "Truffe", + "Tupi", "Turunmaa", "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa", + "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco", "Vendomois", + "Vieux Corse", "Vignotte", "Vulscombe", "Waimata Farmhouse Blue", + "Washed Rind Cheese (Australian)", "Waterloo", "Weichkaese", "Wellington", + "Wensleydale", "White Stilton", "Whitestone Farmhouse", "Wigmore", "Woodside Cabecou", + "Xanadu", "Xynotyro", "Yarg Cornish", "Yarra Valley Pyramid", "Yorkshire Blue", + "Zamorano", "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano" + }; + +} diff --git a/samples/devbytes/ui/ListViewDeletion/src/com/example/android/listviewdeletion/ListViewDeletion.java b/samples/devbytes/ui/ListViewDeletion/src/com/example/android/listviewdeletion/ListViewDeletion.java new file mode 100644 index 000000000..d3538231c --- /dev/null +++ b/samples/devbytes/ui/ListViewDeletion/src/com/example/android/listviewdeletion/ListViewDeletion.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * 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.example.android.listviewdeletion; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import android.app.Activity; +import android.content.Context; +import android.os.Bundle; +import android.util.SparseBooleanArray; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.ListView; + +/** + * This example shows how animating ListView views can lead to artifacts if those views are + * recycled before you animate them. + * + * Watch the associated video for this demo on the DevBytes channel of developer.android.com + * or on YouTube at https://www.youtube.com/watch?v=NewCSg2JKLk. + */ +public class ListViewDeletion extends Activity { + + final ArrayList mCheckedViews = new ArrayList(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_list_view_deletion); + + final Button deleteButton = (Button) findViewById(R.id.deleteButton); + final CheckBox usePositionsCB = (CheckBox) findViewById(R.id.usePositionsCB); + final ListView listview = (ListView) findViewById(R.id.listview); + final ArrayList cheeseList = new ArrayList(); + for (int i = 0; i < Cheeses.sCheeseStrings.length; ++i) { + cheeseList.add(Cheeses.sCheeseStrings[i]); + } + final StableArrayAdapter adapter = new StableArrayAdapter(this, + android.R.layout.simple_list_item_multiple_choice, cheeseList); + listview.setAdapter(adapter); + listview.setItemsCanFocus(false); + listview.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); + + // Clicking the delete button fades out the currently selected views + deleteButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + SparseBooleanArray checkedItems = listview.getCheckedItemPositions(); + int numCheckedItems = checkedItems.size(); + for (int i = numCheckedItems - 1; i >= 0; --i) { + if (!checkedItems.valueAt(i)) { + continue; + } + int position = checkedItems.keyAt(i); + final String item = adapter.getItem(position); + if (!usePositionsCB.isChecked()) { + // Remove the actual data after the time period that we're going to run + // the fading animation + v.postDelayed(new Runnable() { + @Override + public void run() { + adapter.remove(item); + } + }, 300); + } else { + // This is the correct way to do this: first wee whether the item is + // actually visible, and don't bother animating it if it's not. + // Next, get the view associated with the item at the time of deletion + // (not some old view chosen when the item was clicked). + mCheckedViews.clear(); + int positionOnScreen = position - listview.getFirstVisiblePosition(); + if (positionOnScreen >= 0 && + positionOnScreen < listview.getChildCount()) { + final View view = listview.getChildAt(positionOnScreen); + // All set to fade this view out. Using ViewPropertyAnimator accounts + // for possible recycling of views during the animation itself + // (see the ListViewAnimations example for more on this). + view.animate().alpha(0).withEndAction(new Runnable() { + @Override + public void run() { + view.setAlpha(1); + adapter.remove(item); + } + }); + } else { + // Not animating the view, but don't delete it yet to avoid making the + // list shift due to offscreen deletions + v.postDelayed(new Runnable() { + @Override + public void run() { + adapter.remove(item); + } + }, 300); + } + } + } + // THIS IS THE WRONG WAY TO DO THIS + // We're basing our decision of the views to be animated based on outdated + // information at selection time. Then we're going ahead and running an animation + // on those views even when the selected items might not even be in view (in which + // case we'll probably be mistakenly fading out something else that is on the + // screen and is re-using that recycled view). + for (int i = 0; i < mCheckedViews.size(); ++i) { + final View checkedView = mCheckedViews.get(i); + checkedView.animate().alpha(0).withEndAction(new Runnable() { + @Override + public void run() { + checkedView.setAlpha(1); + } + }); + } + mCheckedViews.clear(); + adapter.notifyDataSetChanged(); + } + }); + + listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { + + @Override + public void onItemClick(AdapterView parent, final View view, int position, long id) { + boolean checked = listview.isItemChecked(position); + if (checked) { + mCheckedViews.add(view); + } else { + mCheckedViews.remove(view); + } + } + }); + } + + private class StableArrayAdapter extends ArrayAdapter { + + HashMap mIdMap = new HashMap(); + + public StableArrayAdapter(Context context, int textViewResourceId, + List objects) { + super(context, textViewResourceId, objects); + for (int i = 0; i < objects.size(); ++i) { + mIdMap.put(objects.get(i), i); + } + } + + @Override + public long getItemId(int position) { + String item = getItem(position); + return mIdMap.get(item); + } + + @Override + public boolean hasStableIds() { + return true; + } + + } + +} diff --git a/samples/devbytes/ui/RequestDuringLayout/AndroidManifest.xml b/samples/devbytes/ui/RequestDuringLayout/AndroidManifest.xml new file mode 100644 index 000000000..219e0145f --- /dev/null +++ b/samples/devbytes/ui/RequestDuringLayout/AndroidManifest.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + diff --git a/samples/devbytes/ui/RequestDuringLayout/res/drawable-hdpi/ic_launcher.png b/samples/devbytes/ui/RequestDuringLayout/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 000000000..fba1ff058 Binary files /dev/null and b/samples/devbytes/ui/RequestDuringLayout/res/drawable-hdpi/ic_launcher.png differ diff --git a/samples/devbytes/ui/RequestDuringLayout/res/drawable-mdpi/ic_launcher.png b/samples/devbytes/ui/RequestDuringLayout/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 000000000..72a445d04 Binary files /dev/null and b/samples/devbytes/ui/RequestDuringLayout/res/drawable-mdpi/ic_launcher.png differ diff --git a/samples/devbytes/ui/RequestDuringLayout/res/drawable-xhdpi/ic_launcher.png b/samples/devbytes/ui/RequestDuringLayout/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 000000000..002e7b052 Binary files /dev/null and b/samples/devbytes/ui/RequestDuringLayout/res/drawable-xhdpi/ic_launcher.png differ diff --git a/samples/devbytes/ui/RequestDuringLayout/res/layout/activity_request_during_layout.xml b/samples/devbytes/ui/RequestDuringLayout/res/layout/activity_request_during_layout.xml new file mode 100644 index 000000000..b026db8ad --- /dev/null +++ b/samples/devbytes/ui/RequestDuringLayout/res/layout/activity_request_during_layout.xml @@ -0,0 +1,44 @@ + + + + + +