SlideShare ist ein Scribd-Unternehmen logo
1 von 38
Downloaden Sie, um offline zu lesen
Dinosaurs and Androids:The
ListView evolution
Jorge J. Barroso / Fernando Cejas
Tech Lead Android Core / Android Developer
jbarroso@tuenti.com / fcejas@tuenti.com
@flipper83 / @fernando_cejas / @TuentiEng

Code samples:
https://github.com/android10/Inside_Android_ListView
Sunday, November 10, 13
Sunday, November 10, 13
1

Morphology

Component or Layout?
Sunday, November 10, 13
public abstract class AbsListView
extends AdapterView<ListAdapter>
public abstract class AdapterView
<T extends Adapter> extends
ViewGroup

Sunday, November 10, 13
ScrapViews
view

ListView

Sunday, November 10, 13

view

view

Adapter
/**
* Obtain the view and add it to our list of children. The view can be made
* fresh, converted from an unused view, or used as is if it was in the
* recycle bin.
*
* @param position Logical position in the list
* @param y Top or bottom edge of the view to add
* @param flow If flow is true, align top edge to y. If false, align bottom
*
edge to y.
* @param childrenLeft Left edge where children should be positioned
* @param selected Is this position selected?
* @return View that was added
*/
private View makeAndAddView(int position, int y, boolean flow, int childrenLeft,
boolean selected) {
View child;
if (!mDataChanged) {
// Try to use an existing view for this position
child = mRecycler.getActiveView(position);
if (child != null) {
// Found it -- we're using an existing child
// This just needs to be positioned
setupChild(child, position, y, flow, childrenLeft, selected, true);
return child;
}
}
// Make a new view for this position, or convert an unused view if possible
child = obtainView(position, mIsScrap);
// This needs to be positioned and measured
setupChild(child, position, y, flow, childrenLeft, selected, mIsScrap[0]);
return child;
}

Sunday, November 10, 13

ListView
/**
* Get a view and have it show the data associated with the specified
* position. This is called when we have already discovered that the view is
* not available for reuse in the recycle bin. The only choices left are
* converting an old view or making a new one.
*
* @param position The position to display
* @param isScrap Array of at least 1 boolean, the first entry will become true if
*
the returned view was taken from the scrap heap, false if otherwise.
*
* @return A view displaying the data associated with the specified position
*/
View obtainView(int position, boolean[] isScrap) {
isScrap[0] = false;
View scrapView;
scrapView = mRecycler.getTransientStateView(position);
if (scrapView != null) {
return scrapView;
}
scrapView = mRecycler.getScrapView(position);
View child;
if (scrapView != null) {
child = mAdapter.getView(position, scrapView, this);
...
}

Sunday, November 10, 13

AbsListView
Sunday, November 10, 13
Demo
http://www.flickr.com/photos/farahmandnia/
Sunday, November 10, 13
2

ViewHolders

Is this really necessary?
http://www.flickr.com/photos/rojam/
Sunday, November 10, 13
Your code might call findViewById() frequently during the
scrolling of ListView, which can slow down performance. Even
when the Adapter returns an inflated view for recycling, you
still need to look up the elements and update them. A way
around repeated use of findViewById() is to use the "view
holder" design pattern.

Sunday, November 10, 13
@Override
protected View findViewTraversal(int id) {
if (id == mID) {
return this;
}
final View[] where = mChildren;
final int len = mChildrenCount;
for (int i = 0; i < len; i++) {
View v = where[i];
if ((v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) {
v = v.findViewById(id);
if (v != null) {
return v;
}
}
}
return null;
}

ViewGroup
Sunday, November 10, 13
Demo
http://www.flickr.com/photos/farahmandnia/
Sunday, November 10, 13
3

Optimization

Where are we wasting time?
http://www.flickr.com/photos/kabacchi/
Sunday, November 10, 13
ew
i
tV
e
G
Adapter

View

LruCache
<Bitmap>
Bitmap

Sunday, November 10, 13
Demo
http://www.flickr.com/photos/farahmandnia/
Sunday, November 10, 13
WHY
DOESN’T
IT
WORK?
Sunday, November 10, 13
View

dispatchDraw

onDraw

ViewGroup

ViewGroup

getDrawingCache

onDraw

onDraw

dispatchDraw

View
Sunday, November 10, 13

onDraw
/**
* This is where the invalidate() work actually happens. A full invalidate()
* causes the drawing cache to be invalidated, but this function can be called with
* invalidateCache set to false to skip that invalidation step for cases that do not
* need it (for example, a component that remains at the same dimensions with the same
* content).
*
* @param invalidateCache Whether the drawing cache for this view should be invalidated as
* well. This is usually true for a full invalidate, but may be set to false if the
* View's contents or dimensions have not changed.
*/
void invalidate(boolean invalidateCache) {
if (skipInvalidate()) {
return;
}
if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS) ||
(invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) ||
(mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED || isOpaque() != mLastIsOpaque) {
mLastIsOpaque = isOpaque();
mPrivateFlags &= ~PFLAG_DRAWN;
mPrivateFlags |= PFLAG_DIRTY;
if (invalidateCache) {
mPrivateFlags |= PFLAG_INVALIDATED;
mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
}
final AttachInfo ai = mAttachInfo;
final ViewParent p = mParent;
//noinspection PointlessBooleanExpression,ConstantConditions
if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
if (p != null && ai != null && ai.mHardwareAccelerated) {
// fast-track for GL-enabled applications; just invalidate the whole hierarchy
// with a null dirty rect, which tells the ViewAncestor to redraw everything
p.invalidateChild(this, null);
return;
}
}

}

}

if (p != null && ai != null) {
final Rect r = ai.mTmpInvalRect;
r.set(0, 0, mRight - mLeft, mBottom - mTop);
// Don't call invalidate -- we don't want to internally scroll
// our own bounds
p.invalidateChild(this, r);
}

Sunday, November 10, 13

View
4

Mixed List

Remember one convertView for each type. Headers and Footers
http://www.flickr.com/photos/keesey/
Sunday, November 10, 13
/**
* Sets the data behind this ListView.
*
* The adapter passed to this method may be wrapped by a {@link
WrapperListAdapter},
* depending on the ListView features currently in use. For instance, adding
* headers and/or footers will cause the adapter to be wrapped.
*
* @param adapter The ListAdapter which is responsible for maintaining the
*
data backing this list and for producing a view to represent an
*
item in that data set.
*
* @see #getAdapter()
*/
@Override
public void setAdapter(ListAdapter adapter) {
if (mAdapter != null && mDataSetObserver != null) {
mAdapter.unregisterDataSetObserver(mDataSetObserver);
}
resetList();
mRecycler.clear();
if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos,
adapter);
} else {
mAdapter = adapter;
}
...
}

ListView

Sunday, November 10, 13
public View getView(int position, View convertView, ViewGroup parent) {
// Header (negative positions will throw an ArrayIndexOutOfBoundsException)
int numHeaders = getHeadersCount();
if (position < numHeaders) {
return mHeaderViewInfos.get(position).view;
}
// Adapter
final int adjPosition = position - numHeaders;
int adapterCount = 0;
if (mAdapter != null) {
adapterCount = mAdapter.getCount();
if (adjPosition < adapterCount) {
return mAdapter.getView(adjPosition, convertView, parent);
}
}

}

// Footer (off-limits positions will throw an ArrayIndexOutOfBoundsException)
return mFooterViewInfos.get(adjPosition - adapterCount).view;

HeaderViewListAdapter
Sunday, November 10, 13
ListView - addFooterView

Sunday, November 10, 13
5

Animation

Let’s animate items...
Sunday, November 10, 13
- View Animation
- Drawable Animation
- Property Animation

Sunday, November 10, 13
Demo
http://www.flickr.com/photos/farahmandnia/
Sunday, November 10, 13
lv_list.setRecyclerListener(new AbsListView.RecyclerListener() {
@Override
public void onMovedToScrapHeap(View view) {
}
});

/**
* Sets the recycler listener to be notified whenever a View is set aside in
* the recycler for later reuse. This listener can be used to free resources
* associated to the View.
*
* @param listener The recycler listener to be notified of views set aside
*
in the recycler.
*
* @see android.widget.AbsListView.RecycleBin
* @see android.widget.AbsListView.RecyclerListener
*/
public void setRecyclerListener(RecyclerListener listener) {
mRecycler.mRecyclerListener = listener;
}

AbsListView
Sunday, November 10, 13
/**
* Set whether this view is currently tracking transient state that the
* framework should attempt to preserve when possible. This flag is reference counted,
* so every call to setHasTransientState(true) should be paired with a later call
* to setHasTransientState(false).
*
* <p>A view with transient state cannot be trivially rebound from an external
* data source, such as an adapter binding item views in a list. This may be
* because the view is performing an animation, tracking user selection
* of content, or similar.</p>
*
* @param hasTransientState true if this view has transient state
*/
public void setHasTransientState(boolean hasTransientState) {
mTransientStateCount = hasTransientState ? mTransientStateCount + 1 :
mTransientStateCount - 1;
if (mTransientStateCount < 0) {
mTransientStateCount = 0;
Log.e(VIEW_LOG_TAG, "hasTransientState decremented below 0: " +
"unmatched pair of setHasTransientState calls");
}
if ((hasTransientState && mTransientStateCount == 1) ||
(!hasTransientState && mTransientStateCount == 0)) {
// update flag if we've just incremented up from 0 or decremented down to 0
mPrivateFlags2 = (mPrivateFlags2 & ~PFLAG2_HAS_TRANSIENT_STATE) |
(hasTransientState ? PFLAG2_HAS_TRANSIENT_STATE : 0);
if (mParent != null) {
try {
mParent.childHasTransientStateChanged(this, hasTransientState);
} catch (AbstractMethodError e) {
Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
" does not fully implement ViewParent", e);
}
}
}
}

View

Sunday, November 10, 13
/**
* Starts the underlying Animator for a set of properties. We use a single animator that
* simply runs from 0 to 1, and then use that fractional value to set each property
* value accordingly.
*/
private void startAnimation() {
mView.setHasTransientState(true);
ValueAnimator animator = ValueAnimator.ofFloat(1.0f);
ArrayList<NameValuesHolder> nameValueList =
(ArrayList<NameValuesHolder>) mPendingAnimations.clone();
mPendingAnimations.clear();
int propertyMask = 0;
int propertyCount = nameValueList.size();
for (int i = 0; i < propertyCount; ++i) {
NameValuesHolder nameValuesHolder = nameValueList.get(i);
propertyMask |= nameValuesHolder.mNameConstant;
}
mAnimatorMap.put(animator, new PropertyBundle(propertyMask, nameValueList));
if (mPendingSetupAction != null) {
mAnimatorSetupMap.put(animator, mPendingSetupAction);
mPendingSetupAction = null;
}
if (mPendingCleanupAction != null) {
...
}

ViewPropertyAnimator
Sunday, November 10, 13
Demo
http://www.flickr.com/photos/farahmandnia/
Sunday, November 10, 13
Renders

6

Our solution
http://www.flickr.com/photos/toughkidcst/
Sunday, November 10, 13
time overhead
viewHolder

GetView
(RenderModel)

Adapter

Render
Builder

Abstract
Render

RenderModel

Render
Impl

Sunday, November 10, 13
7
Sunday, November 10, 13

DIFF IS FUN

http://www.flickr.com/photos/josephwuorigami/
Did someone notice it?

Sunday, November 10, 13
Sunday, November 10, 13
Test Coverage ^_^

Sunday, November 10, 13
They are also human!

Sunday, November 10, 13
http://jobs.tuenti.com
http://corporate.tuenti.com/en/dev/blog
jbarroso@tuenti.com / fcejas@tuenti.com
@flipper83 / @fernando_cejas
Sunday, November 10, 13

Weitere ähnliche Inhalte

Ähnlich wie Dinosaurs and Androids: The Listview Evolution

Android basic 4 Navigation Drawer
Android basic 4 Navigation DrawerAndroid basic 4 Navigation Drawer
Android basic 4 Navigation DrawerEakapong Kattiya
 
Drupal 8 configuration system for coders and site builders - Drupalaton 2013
Drupal 8 configuration system for coders and site builders - Drupalaton 2013Drupal 8 configuration system for coders and site builders - Drupalaton 2013
Drupal 8 configuration system for coders and site builders - Drupalaton 2013swentel
 
Pragmatic JavaScript
Pragmatic JavaScriptPragmatic JavaScript
Pragmatic JavaScriptJohn Hann
 
Android ListView and Custom ListView
Android ListView and Custom ListView Android ListView and Custom ListView
Android ListView and Custom ListView Sourabh Sahu
 
How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...Oursky
 
How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...Jane Chung
 
Don't Make Android Bad... Again
Don't Make Android Bad... AgainDon't Make Android Bad... Again
Don't Make Android Bad... AgainPedro Vicente
 
Day 8: Dealing with Lists and ListViews
Day 8: Dealing with Lists and ListViewsDay 8: Dealing with Lists and ListViews
Day 8: Dealing with Lists and ListViewsAhsanul Karim
 
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...Richard McIntyre
 
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...swentel
 
Deep Dive into React Hooks
Deep Dive into React HooksDeep Dive into React Hooks
Deep Dive into React HooksFelix Kühl
 
(AFF301) Fire Phone: The Dynamic Perspective API, Under the Hood | AWS re:Inv...
(AFF301) Fire Phone: The Dynamic Perspective API, Under the Hood | AWS re:Inv...(AFF301) Fire Phone: The Dynamic Perspective API, Under the Hood | AWS re:Inv...
(AFF301) Fire Phone: The Dynamic Perspective API, Under the Hood | AWS re:Inv...Amazon Web Services
 
Ember and containers
Ember and containersEmber and containers
Ember and containersMatthew Beale
 
Symfony War Stories
Symfony War StoriesSymfony War Stories
Symfony War StoriesJakub Zalas
 
Ruby on Rails Developer - Allerin
Ruby on Rails Developer - AllerinRuby on Rails Developer - Allerin
Ruby on Rails Developer - AllerinLauree R
 
Preparation Data Structures 05 chain linear_list
Preparation Data Structures 05 chain linear_listPreparation Data Structures 05 chain linear_list
Preparation Data Structures 05 chain linear_listAndres Mendez-Vazquez
 
dcs plus Catalogue 2015
dcs plus Catalogue 2015dcs plus Catalogue 2015
dcs plus Catalogue 2015dcs plus
 

Ähnlich wie Dinosaurs and Androids: The Listview Evolution (20)

Android basic 4 Navigation Drawer
Android basic 4 Navigation DrawerAndroid basic 4 Navigation Drawer
Android basic 4 Navigation Drawer
 
Drupal 8 configuration system for coders and site builders - Drupalaton 2013
Drupal 8 configuration system for coders and site builders - Drupalaton 2013Drupal 8 configuration system for coders and site builders - Drupalaton 2013
Drupal 8 configuration system for coders and site builders - Drupalaton 2013
 
Pragmatic JavaScript
Pragmatic JavaScriptPragmatic JavaScript
Pragmatic JavaScript
 
Android ListView and Custom ListView
Android ListView and Custom ListView Android ListView and Custom ListView
Android ListView and Custom ListView
 
How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...
 
How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...
 
Don't Make Android Bad... Again
Don't Make Android Bad... AgainDon't Make Android Bad... Again
Don't Make Android Bad... Again
 
Day 8: Dealing with Lists and ListViews
Day 8: Dealing with Lists and ListViewsDay 8: Dealing with Lists and ListViews
Day 8: Dealing with Lists and ListViews
 
What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...What is this DI and AOP stuff anyway...
What is this DI and AOP stuff anyway...
 
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
 
Deep Dive into React Hooks
Deep Dive into React HooksDeep Dive into React Hooks
Deep Dive into React Hooks
 
Dig1108 Lesson 3
Dig1108 Lesson 3Dig1108 Lesson 3
Dig1108 Lesson 3
 
(AFF301) Fire Phone: The Dynamic Perspective API, Under the Hood | AWS re:Inv...
(AFF301) Fire Phone: The Dynamic Perspective API, Under the Hood | AWS re:Inv...(AFF301) Fire Phone: The Dynamic Perspective API, Under the Hood | AWS re:Inv...
(AFF301) Fire Phone: The Dynamic Perspective API, Under the Hood | AWS re:Inv...
 
Ember and containers
Ember and containersEmber and containers
Ember and containers
 
Symfony War Stories
Symfony War StoriesSymfony War Stories
Symfony War Stories
 
Ruby on Rails Developer - Allerin
Ruby on Rails Developer - AllerinRuby on Rails Developer - Allerin
Ruby on Rails Developer - Allerin
 
Preparation Data Structures 05 chain linear_list
Preparation Data Structures 05 chain linear_listPreparation Data Structures 05 chain linear_list
Preparation Data Structures 05 chain linear_list
 
dcs plus Catalogue 2015
dcs plus Catalogue 2015dcs plus Catalogue 2015
dcs plus Catalogue 2015
 
List adapter with multiple objects
List adapter with multiple objectsList adapter with multiple objects
List adapter with multiple objects
 
DrupalCon jQuery
DrupalCon jQueryDrupalCon jQuery
DrupalCon jQuery
 

Mehr von Fernando Cejas

The Mayans Lost Guide to RxJava on Android
The Mayans Lost Guide to RxJava on AndroidThe Mayans Lost Guide to RxJava on Android
The Mayans Lost Guide to RxJava on AndroidFernando Cejas
 
It is about philosophy: culture of a good programmer
It is about philosophy: culture of a good programmerIt is about philosophy: culture of a good programmer
It is about philosophy: culture of a good programmerFernando Cejas
 
Material Design for Old Schoolers
Material Design for Old SchoolersMaterial Design for Old Schoolers
Material Design for Old SchoolersFernando Cejas
 
How to Become the MacGyver of Android Custom Views
How to Become the MacGyver of Android Custom ViewsHow to Become the MacGyver of Android Custom Views
How to Become the MacGyver of Android Custom ViewsFernando Cejas
 
Android UX-UI Design for Fun and Profit
Android UX-UI Design for Fun and ProfitAndroid UX-UI Design for Fun and Profit
Android UX-UI Design for Fun and ProfitFernando Cejas
 
How ANDROID TESTING changed how we think about Death - Second Edition
How ANDROID TESTING changed how we think about Death - Second EditionHow ANDROID TESTING changed how we think about Death - Second Edition
How ANDROID TESTING changed how we think about Death - Second EditionFernando Cejas
 
How ANDROID TESTING changed how we think about Death
How ANDROID TESTING changed how we think about DeathHow ANDROID TESTING changed how we think about Death
How ANDROID TESTING changed how we think about DeathFernando Cejas
 
Inside Android Testing
Inside Android TestingInside Android Testing
Inside Android TestingFernando Cejas
 
Webview: The fifth element
Webview: The fifth elementWebview: The fifth element
Webview: The fifth elementFernando Cejas
 
Android Design Patterns
Android Design PatternsAndroid Design Patterns
Android Design PatternsFernando Cejas
 
Android Cloud To Device Messaging
Android Cloud To Device MessagingAndroid Cloud To Device Messaging
Android Cloud To Device MessagingFernando Cejas
 
Android Quick Introduction
Android Quick IntroductionAndroid Quick Introduction
Android Quick IntroductionFernando Cejas
 
Desarrollo android almacenamiento de datos
Desarrollo android    almacenamiento de datosDesarrollo android    almacenamiento de datos
Desarrollo android almacenamiento de datosFernando Cejas
 
Android simple 2d Layout animation
Android simple 2d Layout animationAndroid simple 2d Layout animation
Android simple 2d Layout animationFernando Cejas
 

Mehr von Fernando Cejas (15)

The Mayans Lost Guide to RxJava on Android
The Mayans Lost Guide to RxJava on AndroidThe Mayans Lost Guide to RxJava on Android
The Mayans Lost Guide to RxJava on Android
 
It is about philosophy: culture of a good programmer
It is about philosophy: culture of a good programmerIt is about philosophy: culture of a good programmer
It is about philosophy: culture of a good programmer
 
Material Design for Old Schoolers
Material Design for Old SchoolersMaterial Design for Old Schoolers
Material Design for Old Schoolers
 
How to Become the MacGyver of Android Custom Views
How to Become the MacGyver of Android Custom ViewsHow to Become the MacGyver of Android Custom Views
How to Become the MacGyver of Android Custom Views
 
Android UX-UI Design for Fun and Profit
Android UX-UI Design for Fun and ProfitAndroid UX-UI Design for Fun and Profit
Android UX-UI Design for Fun and Profit
 
How ANDROID TESTING changed how we think about Death - Second Edition
How ANDROID TESTING changed how we think about Death - Second EditionHow ANDROID TESTING changed how we think about Death - Second Edition
How ANDROID TESTING changed how we think about Death - Second Edition
 
How ANDROID TESTING changed how we think about Death
How ANDROID TESTING changed how we think about DeathHow ANDROID TESTING changed how we think about Death
How ANDROID TESTING changed how we think about Death
 
Inside Android Testing
Inside Android TestingInside Android Testing
Inside Android Testing
 
Webview: The fifth element
Webview: The fifth elementWebview: The fifth element
Webview: The fifth element
 
Nfc on Android
Nfc on AndroidNfc on Android
Nfc on Android
 
Android Design Patterns
Android Design PatternsAndroid Design Patterns
Android Design Patterns
 
Android Cloud To Device Messaging
Android Cloud To Device MessagingAndroid Cloud To Device Messaging
Android Cloud To Device Messaging
 
Android Quick Introduction
Android Quick IntroductionAndroid Quick Introduction
Android Quick Introduction
 
Desarrollo android almacenamiento de datos
Desarrollo android    almacenamiento de datosDesarrollo android    almacenamiento de datos
Desarrollo android almacenamiento de datos
 
Android simple 2d Layout animation
Android simple 2d Layout animationAndroid simple 2d Layout animation
Android simple 2d Layout animation
 

Kürzlich hochgeladen

The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 

Kürzlich hochgeladen (20)

The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 

Dinosaurs and Androids: The Listview Evolution

  • 1. Dinosaurs and Androids:The ListView evolution Jorge J. Barroso / Fernando Cejas Tech Lead Android Core / Android Developer jbarroso@tuenti.com / fcejas@tuenti.com @flipper83 / @fernando_cejas / @TuentiEng Code samples: https://github.com/android10/Inside_Android_ListView Sunday, November 10, 13
  • 4. public abstract class AbsListView extends AdapterView<ListAdapter> public abstract class AdapterView <T extends Adapter> extends ViewGroup Sunday, November 10, 13
  • 6. /** * Obtain the view and add it to our list of children. The view can be made * fresh, converted from an unused view, or used as is if it was in the * recycle bin. * * @param position Logical position in the list * @param y Top or bottom edge of the view to add * @param flow If flow is true, align top edge to y. If false, align bottom * edge to y. * @param childrenLeft Left edge where children should be positioned * @param selected Is this position selected? * @return View that was added */ private View makeAndAddView(int position, int y, boolean flow, int childrenLeft, boolean selected) { View child; if (!mDataChanged) { // Try to use an existing view for this position child = mRecycler.getActiveView(position); if (child != null) { // Found it -- we're using an existing child // This just needs to be positioned setupChild(child, position, y, flow, childrenLeft, selected, true); return child; } } // Make a new view for this position, or convert an unused view if possible child = obtainView(position, mIsScrap); // This needs to be positioned and measured setupChild(child, position, y, flow, childrenLeft, selected, mIsScrap[0]); return child; } Sunday, November 10, 13 ListView
  • 7. /** * Get a view and have it show the data associated with the specified * position. This is called when we have already discovered that the view is * not available for reuse in the recycle bin. The only choices left are * converting an old view or making a new one. * * @param position The position to display * @param isScrap Array of at least 1 boolean, the first entry will become true if * the returned view was taken from the scrap heap, false if otherwise. * * @return A view displaying the data associated with the specified position */ View obtainView(int position, boolean[] isScrap) { isScrap[0] = false; View scrapView; scrapView = mRecycler.getTransientStateView(position); if (scrapView != null) { return scrapView; } scrapView = mRecycler.getScrapView(position); View child; if (scrapView != null) { child = mAdapter.getView(position, scrapView, this); ... } Sunday, November 10, 13 AbsListView
  • 10. 2 ViewHolders Is this really necessary? http://www.flickr.com/photos/rojam/ Sunday, November 10, 13
  • 11. Your code might call findViewById() frequently during the scrolling of ListView, which can slow down performance. Even when the Adapter returns an inflated view for recycling, you still need to look up the elements and update them. A way around repeated use of findViewById() is to use the "view holder" design pattern. Sunday, November 10, 13
  • 12. @Override protected View findViewTraversal(int id) { if (id == mID) { return this; } final View[] where = mChildren; final int len = mChildrenCount; for (int i = 0; i < len; i++) { View v = where[i]; if ((v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) { v = v.findViewById(id); if (v != null) { return v; } } } return null; } ViewGroup Sunday, November 10, 13
  • 14. 3 Optimization Where are we wasting time? http://www.flickr.com/photos/kabacchi/ Sunday, November 10, 13
  • 19. /** * This is where the invalidate() work actually happens. A full invalidate() * causes the drawing cache to be invalidated, but this function can be called with * invalidateCache set to false to skip that invalidation step for cases that do not * need it (for example, a component that remains at the same dimensions with the same * content). * * @param invalidateCache Whether the drawing cache for this view should be invalidated as * well. This is usually true for a full invalidate, but may be set to false if the * View's contents or dimensions have not changed. */ void invalidate(boolean invalidateCache) { if (skipInvalidate()) { return; } if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS) || (invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) || (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED || isOpaque() != mLastIsOpaque) { mLastIsOpaque = isOpaque(); mPrivateFlags &= ~PFLAG_DRAWN; mPrivateFlags |= PFLAG_DIRTY; if (invalidateCache) { mPrivateFlags |= PFLAG_INVALIDATED; mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID; } final AttachInfo ai = mAttachInfo; final ViewParent p = mParent; //noinspection PointlessBooleanExpression,ConstantConditions if (!HardwareRenderer.RENDER_DIRTY_REGIONS) { if (p != null && ai != null && ai.mHardwareAccelerated) { // fast-track for GL-enabled applications; just invalidate the whole hierarchy // with a null dirty rect, which tells the ViewAncestor to redraw everything p.invalidateChild(this, null); return; } } } } if (p != null && ai != null) { final Rect r = ai.mTmpInvalRect; r.set(0, 0, mRight - mLeft, mBottom - mTop); // Don't call invalidate -- we don't want to internally scroll // our own bounds p.invalidateChild(this, r); } Sunday, November 10, 13 View
  • 20. 4 Mixed List Remember one convertView for each type. Headers and Footers http://www.flickr.com/photos/keesey/ Sunday, November 10, 13
  • 21. /** * Sets the data behind this ListView. * * The adapter passed to this method may be wrapped by a {@link WrapperListAdapter}, * depending on the ListView features currently in use. For instance, adding * headers and/or footers will cause the adapter to be wrapped. * * @param adapter The ListAdapter which is responsible for maintaining the * data backing this list and for producing a view to represent an * item in that data set. * * @see #getAdapter() */ @Override public void setAdapter(ListAdapter adapter) { if (mAdapter != null && mDataSetObserver != null) { mAdapter.unregisterDataSetObserver(mDataSetObserver); } resetList(); mRecycler.clear(); if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) { mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter); } else { mAdapter = adapter; } ... } ListView Sunday, November 10, 13
  • 22. public View getView(int position, View convertView, ViewGroup parent) { // Header (negative positions will throw an ArrayIndexOutOfBoundsException) int numHeaders = getHeadersCount(); if (position < numHeaders) { return mHeaderViewInfos.get(position).view; } // Adapter final int adjPosition = position - numHeaders; int adapterCount = 0; if (mAdapter != null) { adapterCount = mAdapter.getCount(); if (adjPosition < adapterCount) { return mAdapter.getView(adjPosition, convertView, parent); } } } // Footer (off-limits positions will throw an ArrayIndexOutOfBoundsException) return mFooterViewInfos.get(adjPosition - adapterCount).view; HeaderViewListAdapter Sunday, November 10, 13
  • 25. - View Animation - Drawable Animation - Property Animation Sunday, November 10, 13
  • 27. lv_list.setRecyclerListener(new AbsListView.RecyclerListener() { @Override public void onMovedToScrapHeap(View view) { } }); /** * Sets the recycler listener to be notified whenever a View is set aside in * the recycler for later reuse. This listener can be used to free resources * associated to the View. * * @param listener The recycler listener to be notified of views set aside * in the recycler. * * @see android.widget.AbsListView.RecycleBin * @see android.widget.AbsListView.RecyclerListener */ public void setRecyclerListener(RecyclerListener listener) { mRecycler.mRecyclerListener = listener; } AbsListView Sunday, November 10, 13
  • 28. /** * Set whether this view is currently tracking transient state that the * framework should attempt to preserve when possible. This flag is reference counted, * so every call to setHasTransientState(true) should be paired with a later call * to setHasTransientState(false). * * <p>A view with transient state cannot be trivially rebound from an external * data source, such as an adapter binding item views in a list. This may be * because the view is performing an animation, tracking user selection * of content, or similar.</p> * * @param hasTransientState true if this view has transient state */ public void setHasTransientState(boolean hasTransientState) { mTransientStateCount = hasTransientState ? mTransientStateCount + 1 : mTransientStateCount - 1; if (mTransientStateCount < 0) { mTransientStateCount = 0; Log.e(VIEW_LOG_TAG, "hasTransientState decremented below 0: " + "unmatched pair of setHasTransientState calls"); } if ((hasTransientState && mTransientStateCount == 1) || (!hasTransientState && mTransientStateCount == 0)) { // update flag if we've just incremented up from 0 or decremented down to 0 mPrivateFlags2 = (mPrivateFlags2 & ~PFLAG2_HAS_TRANSIENT_STATE) | (hasTransientState ? PFLAG2_HAS_TRANSIENT_STATE : 0); if (mParent != null) { try { mParent.childHasTransientStateChanged(this, hasTransientState); } catch (AbstractMethodError e) { Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() + " does not fully implement ViewParent", e); } } } } View Sunday, November 10, 13
  • 29. /** * Starts the underlying Animator for a set of properties. We use a single animator that * simply runs from 0 to 1, and then use that fractional value to set each property * value accordingly. */ private void startAnimation() { mView.setHasTransientState(true); ValueAnimator animator = ValueAnimator.ofFloat(1.0f); ArrayList<NameValuesHolder> nameValueList = (ArrayList<NameValuesHolder>) mPendingAnimations.clone(); mPendingAnimations.clear(); int propertyMask = 0; int propertyCount = nameValueList.size(); for (int i = 0; i < propertyCount; ++i) { NameValuesHolder nameValuesHolder = nameValueList.get(i); propertyMask |= nameValuesHolder.mNameConstant; } mAnimatorMap.put(animator, new PropertyBundle(propertyMask, nameValueList)); if (mPendingSetupAction != null) { mAnimatorSetupMap.put(animator, mPendingSetupAction); mPendingSetupAction = null; } if (mPendingCleanupAction != null) { ... } ViewPropertyAnimator Sunday, November 10, 13
  • 33. 7 Sunday, November 10, 13 DIFF IS FUN http://www.flickr.com/photos/josephwuorigami/
  • 34. Did someone notice it? Sunday, November 10, 13
  • 36. Test Coverage ^_^ Sunday, November 10, 13
  • 37. They are also human! Sunday, November 10, 13