SlideShare a Scribd company logo
1 of 87
#AnimateMe
by(Mathias Seguy== Android2EE){
French AndroidTrainer}
If you don't do it for me,
do it for chet !
Demonstration !
Animation is life
Animationis comprehension
Animation is engagements
Animationis delightedyour UX
Animationis necessary
Animation is simple
Make Animations simple
Because we wantyou to animate your
application !
Alpha
Rotate
Translate
Scale
And the plan transformations are yours
V1
<set
android:interpolator="@[package:]anim/interpolator_resource">
<alpha
android:duration="float"
android:fromAlpha="float" android:toAlpha="float" />
<scale
android:duration="float"
android:fromXScale="float" android:toXScale="float"
android:fromYScale="float" android:toYScale="float"
android:pivotX="float" android:pivotY="float" />
<translate
android:duration="float"
android:fromXDelta="float" android:toXDelta="float"
android:fromYDelta="float" android:toYDelta="float" />
<rotate
android:duration="float"
android:fromDegrees="float" android:toDegrees="float"
android:pivotX="float" android:pivotY="float" />
<set>
...
</set>
</set>
Animation animIn= AnimationUtils.loadAnimation(ctx, R.anim.generic_anim);
edtMessage.startAnimation(animIn);
animation/generic_anim.xml
Onlychange pixelsnotthe state of the view
Makes animations generic
V11
/** * The in Animation for after HC */
AnimatorSet animInHC;
animInHC = (AnimatorSet) AnimatorInflater.loadAnimator(ctx, R.animator.generic_anim);
animInHC.setTarget(edtMessage);
animInHC.setTarget(btnAdd);
animInHC.start();
<set >
<objectAnimator
android:duration="1000"
android:propertyName="translationX"
android:valueFrom="-250"
android:valueTo="0"
android:valueType="floatType" />
<objectAnimator
android:duration="1000"
android:propertyName="scaleX"
android:valueFrom="0.0"
android:valueTo="1.0"
android:valueType="floatType" />
</set>
animator-v11/generic_anim.xml
Changes the state of the object
Uses Handler and Runnable
Simplebut dangerous(memory leak, runs inUI thread, can generates frames drops)
Not optimized
Animationis changingthe view/objectstate by droppingchanges inthe UI thread
Handler clipDrawableHandler=new Handler();
Runnable clipDrawableRunnable=new Runnable() {
@Override
public void run() {
myView.changeSomething(level);
clipDrawableHandler.postDelayed(clipDrawableRunnable,32);
}
};
V1
Uses Handler and Runnable
Simplebut dangerous(memory leak, runs inUI thread, can generates frames drops)
Not optimized
V11
Animationis changingthe view/objectstate by droppingchanges inthe UI thread
Handler clipDrawableHandler=new Handler();
Runnable clipDrawableRunnable=new Runnable() {
@Override
public void run() {
myView.changeSomething(level);
clipDrawableHandler.postDelayed(clipDrawableRunnable,32);
}
};
Don't be scared, it's simple.
How do yougofrom the pointfromto the pointto?
V1
t1t0
v0
v1
from
to
?
i(t)=v,
where i(t0)=v0
and i(t1)=v1
float
time
It can be straight
V1
t1t0
v0
v1
from
to
linear
t1t0
v0
v1
Youcan use the system's ones
V1
t1t0
v0
v1
from
to
deceleration acceleration
to
from
t1t0
v0
v1
to
bouncing
from
<set android:interpolator=
"@android:anim/accelerate_interpolator">
<set android:interpolator=
"@android:anim/decelerate_interpolator">
<set android:interpolator=
"@android:anim/bounce_interpolator"
>
Or buildyour own.
V1
t1t0
v0
v1
from
to
alcoholic
public class MyInterpolator implements Interpolator {
float v;
@Override
public float getInterpolation(float input) {
//v=i(input)
return v;
}...}
myDrawable= (ImageView)findViewById(R.id.imvToto).getDrawable();
<ImageView
android:id="@+id/imvToto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/my_drawable"/>
V1
ClipDrawable
RotateDrawable
ScaleDrawable
AnimationDrawable
TransitionDrawable
StateListDrawable
AnimatedStateListDrawable
AnimatedVectorDrawable
Handler clipDrawableHandler=new Handler();
Runnable clipDrawableRunnable=new Runnable() {
@Override
public void run() {level++;
clipDrawableHorizontal.setLevel(level);
clipDrawableHandler.postDelayed(clipDrawableRunnable,32);
}
};
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_android2ee"
android:clipOrientation="horizontal"
android:gravity="left" />
V1
RotateDrawable rotateDrawableWheel;
Handler rotateDrawableHandler=new Handler();
Runnable rotateDrawableRunnable=new Runnable() {
public void run() {level++;
rotateDrawableWheel.setLevel(level);
rotateDrawableHandler.postDelayed(rotateDrawableRunnable,32);
}
};
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_android2ee"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" />
V1
ClipDrawable
RotateDrawable
ScaleDrawable
AnimationDrawable
TransitionDrawable
StateListDrawable
AnimatedStateListDrawable
AnimatedVectorDrawable
ScaleDrawable scaleDrawable;
Handler scaleDrawableHandler=new Handler();
Runnable scaleDrawableRunnable=new Runnable() {
public void run() {level++;
scaleDrawable.setLevel(level);
scaleDrawableHandler.postDelayed(scaleeDrawableRunnable,32);
}
};
<?xml version="1.0" encoding="utf-8"?>
<scale
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@mipmap/ic_edit"
android:scaleGravity="center"
android:scaleHeight="100%"
android:scaleWidth="100%" />
V1
ClipDrawable
RotateDrawable
ScaleDrawable
AnimationDrawable
TransitionDrawable
StateListDrawable
AnimatedStateListDrawable
AnimatedVectorDrawable
animationDrawable.start();
<animation-list
android:id="@+id/selected" android:oneshot="false">
<item android:drawable="@drawable/attack_magic1" android:duration="100" />
<item android:drawable="@drawable/attack_magic2" android:duration="100" />
<item android:drawable="@drawable/attack_magic3" android:duration="100" />
<item android:drawable="@drawable/attack_magic4" android:duration="100" />
</animation-list>
ClipDrawable
RotateDrawable
ScaleDrawable
AnimationDrawable
TransitionDrawable
StateListDrawable
AnimatedStateListDrawable
AnimatedVectorDrawable
V1
transitionDrawable.startTransition(3000);
transitionDrawable.reverseTransition(3000);
<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/ic_ok" />
<item android:drawable="@mipmap/ic_nok" />
</transition>
ClipDrawable
RotateDrawable
ScaleDrawable
AnimationDrawable
TransitionDrawable
StateListDrawable
AnimatedStateListDrawable
AnimatedVectorDrawable
V1
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:enterFadeDuration="300"
android:exitFadeDuration="300">
<!--Sorry below v21 there is no animated selector
you can just fade in and fade out-->
<item android:id="@+id/item_pressed"
android:state_pressed="true">
<bitmap android:src="@drawable/ic_android2ee"/></item>
<item android:id="@+id/item_normal">
<bitmap android:src="@drawable/ic_nut"/> </item>
</selector>
fade fade
Norma
l
Press
ed
Norma
l
View
state
Displ
ay
V
1
ClipDrawable
RotateDrawable
ScaleDrawable
AnimationDrawable
TransitionDrawable
StateListDrawable
AnimatedStateListDraw
able
AnimatedVectorDrawabl
e
<?xml version="1.0" encoding="utf-8"?>
<animated-selector >
<item android:id="@+id/item_pressed"
android:state_pressed="true">
<bitmap android:src="@drawable/ic_android2ee"/></item>
<item android:id="@+id/item_normal">
<bitmap android:src="@drawable/ic_nut"/> </item>
<transition android:fromId="@+id/item_pressed"
android:toId="@+id/item_normal">
<animation-list android:id="@+id/selected"
android:oneshot="true">
<item android:drawable="@drawable/attack_magic1"
android:duration="100" />
<item android:drawable="@drawable/attack_magic2"
android:duration="100" />
</animation-list></transition></animated-selector>
V21
Normal Pressed NormalView state
Display
ClipDrawable
RotateDrawable
ScaleDrawable
AnimationDrawable
TransitionDrawable
StateListDrawable
AnimatedStateListDrawable
AnimatedVectorDrawable
<?xml version="1.0" encoding="utf-8"?>
<vector
android:viewportWidth="500"
android:viewportHeight="500"
android:width="500px"
android:height="500px">
<!--Make group to animate them separately using
ObjectAnimator-->
<!--Define the pivot in the group they will be used by
ObjectAnimator-->
<group android:name="tete"
android:pivotX="250.0"
android:pivotY="100.0">
<path
android:name="head"
android:fillColor="#9FBF3B"
android:pathData="..." />
</group>...</vector>
<?xml version="1.0" encoding="utf-8"?>
<animated-vector
android:drawable="@drawable/my_svg" >
<target
android:name="tete"
android:animation="@anim/anim_svg"
/>
</animated-vector>
<?xml version="1.0" encoding="utf-8"?>
<set
xmlns:android="http://schemas.android.com/apk/res/a
ndroid">
<!-- res/anim/rotation.xml -->
<objectAnimator
android:duration="6000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360" />
</set>
drawable/my_svg drawable/my_svg_animated anim/anim_svg
use
us
e
layout/my_view
use
<ImageView
android:id="@+id/imvAnimatedVector"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/my_svg_animated"/>
animatedVectorDrawable.start();
V21
TransitionDrawable
StateListDrawable
AnimatedStateListDrawable
AnimatedVectorDrawable
<?xml version="1.0" encoding="utf-8"?>
<vector
android:viewportWidth="500"
android:viewportHeight="500"
android:width="500px"
android:height="500px">
<!--Make group to animate them separately using
ObjectAnimator-->
<!--Define the pivot in the group they will be used by
ObjectAnimator-->
<group android:name="tete"
android:pivotX="250.0"
android:pivotY="100.0">
<path
android:name="head"
android:fillColor="#9FBF3B"
android:pathData="..." />
</group>...</vector>
<?xml version="1.0" encoding="utf-8"?>
<animated-vector
android:drawable="@drawable/my_svg" >
<target
android:name="tete"
android:animation="@anim/animpath_svg"
/>
</animated-vector>
<?xml version="1.0" encoding="utf-8"?>
<set >
<!-- res/anim/rotation.xml -->
<objectAnimator
android:duration="6000"
android:propertyName="pathData"
android:valueFrom="M300,70 l 0,-70 70,70 0,0 -
70,70z"
android:valueTo="M300,70 l 0,-70 70,0 0,140 -
70,0 z"
android:valueType="pathType"/>
</set>
drawable/my_svg drawable/my_svg_animated anim/animpath_svg
use
us
e
layout/my_view
use
<ImageView
android:id="@+id/imvAnimatedVector2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/my_svg_animated"/>
animatedVectorDrawable.start();
V21
TransitionDrawable
StateListDrawable
AnimatedStateListDrawable
AnimatedVectorDrawable
The constraints that killfor path transformation:
"Note that the paths must be compatible for morphing.In more details, the paths shouldhave
exact same lengthof commands , and exact same lengthof parameters for each commands."
It means: youwon't use it expect for so simpletrick (arrow to hamburger).
=>Waiting for tools !
V21
And here it is !!!
https://github.com/bonnyfone/vectalign
V21
To create Svg and/orsimplify them
https://inkscape.org/
To convertSvg intoVectorDrawable
http://inloop.github.io/svg2android/
A goodpractice :
Define your path in aString file
(resvaluesmy_path_string.xml)
V21
But even with that it's the hell on earth
=>working ona Github project
Make it simple and magic:
Youcan animate any view
translationX ,translationY, rotationX, rotationY, rotation, scaleX, scaleY, pivotX,pivotY,
x,y,alphaand more
with onelineof code!
myView.animate().setDuration(300).x(20).rotationY(60).start();
V13
myView.animate().rotation(360);
is equivalent to
ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f).start();
V13
Makes animations simple,magic and generic
V13
First extends what youwant
(Objector View or what ever)
public class BlueDot extends View {
V13
Define the propertyto animate
using set/*MyProperty*/
public class BlueDot extends View {
/** * The property to animate *
* @param parameter value of the state to calculate the animation of the object */
private void setToto(int parameter) {
/*Do your stuff,
(call invalidate to redraw view)*/
V13
Then animate
public class BlueDot extends View {
/** * The property to animate *
@param parameter value of the state to calculate the animation of the object */
private void setToto(int parameter) {/*Do your stuff,(call invalidate to redraw view)*/
ObjectAnimator.ofInt(blueDot, "toto", 0, 110)
.start();
V13
ClipDrawable
Handler clipDrawableHandler=new Handler();
Runnable clipDrawableRunnable=new Runnable() {
@Override
public void run() {level++;
clipDrawableHorizontal.setLevel(level);
clipDrawableHandler.postDelayed(clipDrawableRunnable,32);
}
};
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_android2ee"
android:clipOrientation="horizontal"
android:gravity="left" />
It was before
Works with every think !
V13
Works with every think !
public class MyActivity extends Activity{
private void setMoveDrawable(int level){
clipDrawableHorizontal.setLevel(level); }
private void animateDrawable() {
ObjectAnimator.ofInt(this, "MoveDrawable", 0, 10000).start();
}
No more Handler neither Runnable!!!
yes thanks Chet !
V13
Demonstration !
v16
One xmllineto add
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/llSceneRoot"
android:animateLayoutChanges="true"
>
v16
One xmllineto add
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/llSceneRoot"
android:animateLayoutChanges="true"
>
One lineof code to add
if(postICS){
LayoutTransition transition = ((ViewGroup)findViewById(R.id.llSceneRoot)).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.(==size)
transition.enableTransitionType(LayoutTransition.CHANGING);
}
v16
v16v8
Youhave the choicebetween
Custom animation
Intent slidingActivity = new Intent(this, SlidingActivity.class);
ActivityCompat.startActivity(this, slidingActivity, translationBundle);}
v16v8
Bundle translationBundle = ActivityOptionsCompat.makeCustomAnimation(this,
R.anim.anim_push_left_in_a2ee,R.anim.anim_push_left_out_a2ee).toBundle();
Youhave the choicebetween
Custom animation
Scaling Component
Intent slidingActivity = new Intent(this, SlidingActivity.class);
ActivityCompat.startActivity(this, slidingActivity, translationBundle);}
v16v8
Bundle translationBundle = ActivityOptionsCompat.makeCustomAnimation(this,
R.anim.anim_push_left_in_a2ee,R.anim.anim_push_left_out_a2ee).toBundle();
Bundle translationBundle =
ActivityOptionsCompat.makeScaleUpAnimation(btnScaling,0,0,btnScaling.getWidth(),
btnScaling.getHeight() ).toBundle();
Youhave the choicebetween:
Custom animation
Scaling Component
Scaling bitmap
Intent slidingActivity = new Intent(this, SlidingActivity.class);
ActivityCompat.startActivity(this, slidingActivity, translationBundle);}
Bundle translationBundle = ActivityOptionsCompat.makeCustomAnimation(this,
R.anim.anim_push_left_in_a2ee,R.anim.anim_push_left_out_a2ee).toBundle();
Bundle translationBundle =
ActivityOptionsCompat.makeScaleUpAnimation(btnScaling,0,0,btnScaling.getWidth(),
btnScaling.getHeight() ).toBundle();
Bundle translationBundle =
ActivityOptionsCompat.makeThumbnailScaleUpAnimation(imvSmiley,bitmap,0,0)
.toBundle();
v16v8
Youhave the choicebetween:
Custom animation
Scaling Component
Scaling bitmap
You needto reverse :
public class otherActivity extends Activity {
public void finish() {
super.finish();
//this work for all version superior to level 5
overridePendingTransition(R.anim.anim_push_right_in_a2ee,
R.anim.anim_push_right_out_a2ee);
}}
v16v8
Awesome
First manage your theme
<resources>
<!-- Thanks to :-->
<!-- http://code.tutsplus.com/tutorials/introduction-to-the-new-lollipop-activity-transitions&#45;&#45;cms-23711-->
<!-- Base application theme. -->
<style name="AppTheme" parent="BaseTheme">
<!-- Set the transition between activities effective -->
<item name="android:windowContentTransitions">true</item>
<item name="android:windowEnterTransition">@android:transition/slide_bottom</item>
<item name="android:windowExitTransition">@android:transition/slide_bottom</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
<item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
<item name="android:windowSharedElementExitTransition">@android:transition/move</item>
</style>
</resources>
v21
Set the android:transitionName to your components
<ImageButton
android:id="@+id/ibtnSprite"
android:transitionName="@string/imvSprite_transition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_gravity="center"
android:src="@drawable/attack_magic_animation"
/>
<ImageView
android:id="@+id/imvSprite"
android:transitionName="@string/imvSprite_transition"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/attack_magic_animation"
/>
layout/main_activity layout/other_activity
v21
Make yourpairs and launchthe new Activity
if (isPostLollipop) {
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
this,
new Pair<View, String>(imvSprites, getString(R.string.imvSprite_transition)),
);
}
ActivityCompat.startActivity(MainActivity.this, intent, options.toBundle());
}
v21
53
54
dependencies {
...
compile 'com.android.support:recyclerview-v7:23.0.1'
55
RecyclerView
Adapter
ViewHolder
LayoutManager
ItemAnimator ItemDecorator
ItemView management
(ClickListener,Animation...)
dataSet
56
Its the natural evolution of the ListView, the ViewHolder is the one responsible of the view management
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View myView=inflater.inflate(R.layout.recyclerview,container,false);
recyclerView= (RecyclerView) myView.findViewById(R.id.my_recycler_view);
// use a layout manager
recyclerViewLayoutManager = getLayoutManager();
recyclerView.setLayoutManager(recyclerViewLayoutManager);
// specify an adapter (see also next example)
recyclerViewAdapter = new RecyclerViewAdapter(humans,getActivity());
recyclerView.setAdapter(recyclerViewAdapter);
return myView ;
}
find the View
set the LayoutManager
set the Adapter
57
This is the same code as for the ListView (ViewHolder next slide)
public class RecyclerViewAdapter extends
RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{
/****Attributes (t for temp)**/
private ArrayList<Human> humans;
private LayoutInflater inflater;
private View tNewView;
private ViewHolder tViewHolder;
private Human tHuman;
/****** Constructor**/
public RecyclerViewAdapter(ArrayList<Human>
dataSet,Context ctx){
humans=dataSet;
inflater=LayoutInflater.from(ctx);
}
@Override
public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
tNewView=inflater.inflate(R.layout.simple_item,parent,false);
tViewHolder=new ViewHolder(tNewView);
return tViewHolder;
}
@Override
public void onBindViewHolder(RecyclerViewAdapter.ViewHolder holder, int position) {
tHuman=humans.get(position);
holder.getTxvName().setText(tHuman.getName());
holder.getTxvFirstName().setText(tHuman.getFirstName());
holder.getTxvMessage().setText(tHuman.getMessage());
}
@Override
public int getItemCount() {
return humans.size();
}
58
This is the same code as for the ListView (ViewHolder next slide)
public class RecyclerViewAdapter extends
RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{
/****Attributes (t for temp)**/
private ArrayList<Human> humans;
private LayoutInflater inflater;
private View tNewView;
private ViewHolder tViewHolder;
private Human tHuman;
/****** Constructor**/
public RecyclerViewAdapter(ArrayList<Human>
dataSet,Context ctx){
humans=dataSet;
inflater=LayoutInflater.from(ctx);
}
@Override
public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
tNewView=inflater.inflate(R.layout.simple_item,parent,false);
tViewHolder=new ViewHolder(tNewView);
return tViewHolder;
}
@Override
public void onBindViewHolder(RecyclerViewAdapter.ViewHolder holder, int position) {
tHuman=humans.get(position);
holder.getTxvName().setText(tHuman.getName());
holder.getTxvFirstName().setText(tHuman.getFirstName());
holder.getTxvMessage().setText(tHuman.getMessage());
}
@Override
public int getItemCount() {
return humans.size();
}
Inflate the view and its viewHolder
Return the ViewHolder
Update the View using the ViewHolder
Set your DataSet and your LayoutInflater
59
Le ViewHolder gère la vue qu'il encapsule
public class ViewHolder extends RecyclerView.ViewHolder{
TextView txvName=null;
TextView txvFirstName=null;
TextView txvMessage=null;
View.OnClickListener clickListener;
int position;
public ViewHolder(View itemView) {
super(itemView);
txvName= (TextView) itemView.findViewById(R.id.txvName);
txvFirstName= (TextView) itemView.findViewById(R.id.txvFirstName);
txvMessage= (TextView) itemView.findViewById(R.id.txvMessage);
clickListener=new View.OnClickListener() {
public void onClick(View v) {changeTxvMessageVisibilityState(); }
};
itemView.setOnClickListener(clickListener);
}
public TextView getTxvFirstName() {return txvFirstName;}
public TextView getTxvMessage() {return txvMessage;}
public TextView getTxvName() {return txvName;}
public void changeTxvMessageVisibilityState(){
//Do the stuff }
}
60
Le LinearLayoutManager
public RecyclerView.LayoutManager getLayoutManager() {
return new LinearLayoutManager(getContext());
}
61
Le StaggeredLayoutManager
public RecyclerView.LayoutManager getLayoutManager() {
StaggeredGridLayoutManager stagLayoutManager=new StaggeredGridLayoutManager(2,GridLayoutManager.VERTICAL);
stagLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);
return stagLayoutManager;
}
62
Le GridLayoutManager
public RecyclerView.LayoutManager getLayoutManager() {
GridLayoutManager gridLayoutManager=new GridLayoutManager(getContext(),2,GridLayoutManager.VERTICAL,false);
//define specific span of specific cells according to a rule
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int arg0) {
return (arg0 % 3) == 0 ? 2 : 1;
}
});
return gridLayoutManager;
}
63
64
dependencies {
...
compile 'com.android.support:design:23.0.1'
65
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CoordinatorLayout">
The parent Layout of all yours Layouts: The CoordinatorLayout
66
<android.support.design.widget.CoordinatorLayout >
<android.support.design.widget.AppBarLayout
...
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
...
app:layout_scrollFlags="scroll|enterAlways"/>
<android.support.design.widget.TabLayout
...
android:fillViewport="true"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager //Your content
...
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout >
67
<android.support.design.widget.AppBarLayout
... >
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp">
<ImageView
...
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
...
app:layout_scrollFlags="scroll|enterAlways"/>
<android.support.design.widget.TabLayout
...
android:fillViewport="true"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
68
<android.support.design.widget.AppBarLayout...>
<android.support.design.widget.CollapsingToolbarLayout...>
<ImageView.../>
<android.support.design.widget.TabLayout .../>
<android.support.v7.widget.Toolbar.../>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
Set the title of the ActionBar on
the CollapsingToolbarLayout not
on the ToolBar!
69
<android.support.design.widget.AppBarLayout...>
<android.support.design.widget.CollapsingToolbarLayout...>
<ImageView.../>
<android.support.v7.widget.Toolbar.../>
<android.support.design.widget.TabLayout .../>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
s
w
it
c
h
71
<android.support.design.widget.AppBarLayout ... >
<android.support.design.widget.CollapsingToolbarLayout ... >
<ImageView ... />
<android.support.v7.widget.Toolbar ... />
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.design.widget.TabLayout />
</android.support.design.widget.AppBarLayout>
collapsingToolbar.setContentScrimResource(R.drawable.cardview_background_toolbar);
73
V13
Demonstration !
V13
75
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/viewpager"
android:background="#FF00F0F0">
</android.support.v4.view.ViewPager>
public class MainActivity extends ActionBarActivity {
private MyPagerAdapter pagerAdapter;
private ViewPager viewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
//instanciate the PageAdapter
pagerAdapter=new MyPagerAdapter(this);
//Find the viewPager
viewPager = (ViewPager) super.findViewById(R.id.viewpager);
// Affectation de l'adapter au ViewPager
viewPager.setAdapter(pagerAdapter);
}
V13
76
public class MyPagerAdapter extends FragmentPagerAdapter {
private final ArrayList<Fragment> fragments;
public MyPagerAdapter(ActionBarActivity ctx) {
super(ctx.getSupportFragmentManager());
fragments = new ArrayList<Fragment>();
//A stuff I never did before, instanciate my fragment
Fragment frag =new MyFragment1();
fragments.add(frag);...
}
public Fragment getItem(int position) { return fragments.get(position); }
public int getCount() {return fragments.size(); }
V13
77
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
...
//instanciate the PageAdapter
pagerAdapter=new MyPagerAdapter(this);
//Find the viewPager
viewPager = (ViewPager) super.findViewById(R.id.viewpager);
// Affectation de l'adapter au ViewPager
viewPager.setAdapter(pagerAdapter);
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB){
viewPager.setPageTransformer(true, new PageTransformer(this));
}
V13
78
public class MyPageTransformer implements ViewPager.PageTransformer{
RecyclerView myRecyclerView;
public void transformPage(View view, float position) {
//Only the main layout is passed here/
myRecyclerView= (RecyclerView) view.findViewById(R.id.my_recycler_view);
if (position < -1) { // [-Infinity,-1)This page is way off-screen to the left.
view.setAlpha(0); }
else if (position < 1) { //in the visible range [-1,1]
myRecyclerView.setAlpha(1-Math.abs(position));
view.setAlpha(1);
if (position < 0) {//coming from left
myRecyclerView.setRotationX((position * 360));
} else {//coming from right
myRecyclerView.setRotationX(-1*position *360);
}
}
else { // (1,+Infinity] // This page is way off-screen to the right.
view.setAlpha(0); }
}}
V13
How to get the screen size ?
@SuppressLint("NewApi")
private void getViewSize() {
//this is an usual trick when we want to know the dimension of our view
//initialize dimensions of the view
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
if (postICS) {
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
} else {
width = display.getWidth(); // deprecated
height = display.getHeight(); // deprecated
}
}
V1
Whencustomizing youview, youhave to overwrite the followingmethod:
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.w = w;
this.h = h;
centerX = w / 2;
centerY = h / 2;
//...}
V1
Use the ViewTreeObserver
private void getEditButtonWidth() {
//this is an usual trick when we want to know the dimension of the elements of our view
//find the dimension of the EditButton
ViewTreeObserver vto = btnEdit.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
btnEdit.getViewTreeObserver().removeGlobalOnLayoutListener(this);
btnEditWidth = btnEdit.getMeasuredWidth();
}
});
}
V1
Use the LayoutParameter of the ViewGroup
private void changeImvSprite1Size(){
//Change the LayoutParameter to change the size of view
if(isImvSprite1Expended){
imvSprite1.setLayoutParams(imvSpritesLayoutParamNormal);
}else{
imvSprite1.setLayoutParams(imvSpritesLayoutParamExpanded);
}
isImvSprite1Expended=!isImvSprite1Expended;
}
private void initializeImvSpriteSize() {
//get the real size of the components
imvSprite1Height = imvSprite1.getMeasuredHeight();
//initialize the layout parameter for the normal size
imvSpritesLayoutParamNormal = new LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, imvSprite1Height);
//initialize the layout parameter for the expanded size
imvSpritesLayoutParamExpanded= new LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, 2*imvSprite1Height);}
private LinearLayout.LayoutParams imvSpritesLayoutParamNormal, imvSpritesLayoutParamExpanded ;
V1
Invalidate and dirtyArea
or layoutRequest
V1
Make yourownpaint :
Paint dotPaint= new Paint();
//initialize the shader (stuff that make the color of the paint depending on
// the location in the screen and a set of colors)
//@chiuki at droidcon london
int[] rainbow = getRainbowColors();
Shader shader = new LinearGradient(0, 0, 0, w, rainbow,
null, Shader.TileMode.MIRROR);
Matrix matrix = new Matrix();
matrix.setRotate(90);
shader.setLocalMatrix(matrix);
dotPaint.setShader(shader);
private int[] getRainbowColors() {
return new int[]{
getResources().getColor(R.color.rainbow_red),
getResources().getColor(R.color.rainbow_yellow),
getResources().getColor(R.color.rainbow_green),
getResources().getColor(R.color.rainbow_turquoise),
getResources().getColor(R.color.rainbow_blue),
getResources().getColor(R.color.rainbow_purple)
};}
V1
First: Simplifyyour layout!!!
if not enoughyoucan also:
User LayerType Hardware accelerated
btnDoNotPress.setLayerType(View.LAYER_TYPE_HARDWARE,null);
new Animator.AnimatorListener() {
public void onAnimationEnd(Animator animation) {
btnDoNotPress.setLayerType(View.LAYER_TYPE_NONE, null);
}
V1
#android2ee
mathias.seguy@android2ee.com
www.android2ee.com
Code:
https://github.com/MathiasSeguy-Android2EE
Android2EE
@android2ee
Thank you!
MathiasSeguy
Slides:
http://fr.slideshare.net/Android2EE

More Related Content

Similar to Animate Me! if you don't do it for me, do it for Chet - DroidconLondon2015

Constraint-ly motion - making your app dance - John Hoford, Google
Constraint-ly motion - making your app dance - John Hoford, GoogleConstraint-ly motion - making your app dance - John Hoford, Google
Constraint-ly motion - making your app dance - John Hoford, GoogleDroidConTLV
 
Beauty Treatment for your Android Application
Beauty Treatment for your Android ApplicationBeauty Treatment for your Android Application
Beauty Treatment for your Android ApplicationCodemotion
 
Tips & Tricks to spice up your Android app
Tips & Tricks to spice up your Android appTips & Tricks to spice up your Android app
Tips & Tricks to spice up your Android appJérémie Laval
 
Android 2D Drawing and Animation Framework
Android 2D Drawing and Animation FrameworkAndroid 2D Drawing and Animation Framework
Android 2D Drawing and Animation FrameworkJussi Pohjolainen
 
Enhancing UI/UX using Java animations
Enhancing UI/UX using Java animationsEnhancing UI/UX using Java animations
Enhancing UI/UX using Java animationsNaman Dwivedi
 
Seven Peaks Speaks - Android Jetpack Compose Animation
Seven Peaks Speaks - Android Jetpack Compose AnimationSeven Peaks Speaks - Android Jetpack Compose Animation
Seven Peaks Speaks - Android Jetpack Compose AnimationSeven Peaks Speaks
 
Android design and Custom views
Android design and Custom views Android design and Custom views
Android design and Custom views Lars Vogel
 
Basic Android Animation
Basic Android Animation Basic Android Animation
Basic Android Animation Shilu Shrestha
 
Getting Started With Material Design
Getting Started With Material DesignGetting Started With Material Design
Getting Started With Material DesignYasin Yildirim
 
ProTips DroidCon Paris 2013
ProTips DroidCon Paris 2013ProTips DroidCon Paris 2013
ProTips DroidCon Paris 2013Mathias Seguy
 
Project Prague & RealSense: il potere nelle mani!!
Project Prague & RealSense: il potere nelle mani!!Project Prague & RealSense: il potere nelle mani!!
Project Prague & RealSense: il potere nelle mani!!Massimo Bonanni
 
Mobile HTML, CSS, and JavaScript
Mobile HTML, CSS, and JavaScriptMobile HTML, CSS, and JavaScript
Mobile HTML, CSS, and JavaScriptfranksvalli
 
Android JetPack: easy navigation with the new Navigation Controller
Android JetPack: easy navigation with the new Navigation ControllerAndroid JetPack: easy navigation with the new Navigation Controller
Android JetPack: easy navigation with the new Navigation ControllerLeonardo Pirro
 
Intro to computer vision in .net
Intro to computer vision in .netIntro to computer vision in .net
Intro to computer vision in .netStephen Lorello
 
Motion Layout - Easy animations for everyone
Motion Layout - Easy animations for everyoneMotion Layout - Easy animations for everyone
Motion Layout - Easy animations for everyoneBoris D'Amato
 
Project Gesture & RealSense: gestures in a simple way!!
Project Gesture & RealSense: gestures in a simple way!!Project Gesture & RealSense: gestures in a simple way!!
Project Gesture & RealSense: gestures in a simple way!!Massimo Bonanni
 

Similar to Animate Me! if you don't do it for me, do it for Chet - DroidconLondon2015 (20)

Constraint-ly motion - making your app dance - John Hoford, Google
Constraint-ly motion - making your app dance - John Hoford, GoogleConstraint-ly motion - making your app dance - John Hoford, Google
Constraint-ly motion - making your app dance - John Hoford, Google
 
Beauty Treatment for your Android Application
Beauty Treatment for your Android ApplicationBeauty Treatment for your Android Application
Beauty Treatment for your Android Application
 
Tips & Tricks to spice up your Android app
Tips & Tricks to spice up your Android appTips & Tricks to spice up your Android app
Tips & Tricks to spice up your Android app
 
Getting the Magic on Android Tablets
Getting the Magic on Android TabletsGetting the Magic on Android Tablets
Getting the Magic on Android Tablets
 
Android 2D Drawing and Animation Framework
Android 2D Drawing and Animation FrameworkAndroid 2D Drawing and Animation Framework
Android 2D Drawing and Animation Framework
 
Enhancing UI/UX using Java animations
Enhancing UI/UX using Java animationsEnhancing UI/UX using Java animations
Enhancing UI/UX using Java animations
 
Seven Peaks Speaks - Android Jetpack Compose Animation
Seven Peaks Speaks - Android Jetpack Compose AnimationSeven Peaks Speaks - Android Jetpack Compose Animation
Seven Peaks Speaks - Android Jetpack Compose Animation
 
Android view animation in android-chapter18
Android view animation in android-chapter18Android view animation in android-chapter18
Android view animation in android-chapter18
 
Android design and Custom views
Android design and Custom views Android design and Custom views
Android design and Custom views
 
Basic Android Animation
Basic Android Animation Basic Android Animation
Basic Android Animation
 
Getting Started With Material Design
Getting Started With Material DesignGetting Started With Material Design
Getting Started With Material Design
 
ProTips DroidCon Paris 2013
ProTips DroidCon Paris 2013ProTips DroidCon Paris 2013
ProTips DroidCon Paris 2013
 
Project Prague & RealSense: il potere nelle mani!!
Project Prague & RealSense: il potere nelle mani!!Project Prague & RealSense: il potere nelle mani!!
Project Prague & RealSense: il potere nelle mani!!
 
Mobile HTML, CSS, and JavaScript
Mobile HTML, CSS, and JavaScriptMobile HTML, CSS, and JavaScript
Mobile HTML, CSS, and JavaScript
 
The world of Android Animations
The world of Android AnimationsThe world of Android Animations
The world of Android Animations
 
Android JetPack: easy navigation with the new Navigation Controller
Android JetPack: easy navigation with the new Navigation ControllerAndroid JetPack: easy navigation with the new Navigation Controller
Android JetPack: easy navigation with the new Navigation Controller
 
Intro to computer vision in .net
Intro to computer vision in .netIntro to computer vision in .net
Intro to computer vision in .net
 
Motion Layout - Easy animations for everyone
Motion Layout - Easy animations for everyoneMotion Layout - Easy animations for everyone
Motion Layout - Easy animations for everyone
 
Project Gesture & RealSense: gestures in a simple way!!
Project Gesture & RealSense: gestures in a simple way!!Project Gesture & RealSense: gestures in a simple way!!
Project Gesture & RealSense: gestures in a simple way!!
 
Angular animate
Angular animateAngular animate
Angular animate
 

More from Mathias Seguy

Treatment, Architecture and Threads
Treatment, Architecture and ThreadsTreatment, Architecture and Threads
Treatment, Architecture and ThreadsMathias Seguy
 
Architecture et Bonnes pratiques Android #DevoxxFr2016 Part2
Architecture et Bonnes pratiques Android #DevoxxFr2016 Part2Architecture et Bonnes pratiques Android #DevoxxFr2016 Part2
Architecture et Bonnes pratiques Android #DevoxxFr2016 Part2Mathias Seguy
 
Architecture et Bonnes pratiques Android #DevoxxFr2016 Part1
Architecture et Bonnes pratiques Android #DevoxxFr2016 Part1Architecture et Bonnes pratiques Android #DevoxxFr2016 Part1
Architecture et Bonnes pratiques Android #DevoxxFr2016 Part1Mathias Seguy
 
Conférence "Architecture Android" du 19 Mars 2013 par Mathias Seguy fondateur...
Conférence "Architecture Android" du 19 Mars 2013 par Mathias Seguy fondateur...Conférence "Architecture Android" du 19 Mars 2013 par Mathias Seguy fondateur...
Conférence "Architecture Android" du 19 Mars 2013 par Mathias Seguy fondateur...Mathias Seguy
 
Android un nouveau futur s'ouvre à nous
Android un nouveau futur s'ouvre à nousAndroid un nouveau futur s'ouvre à nous
Android un nouveau futur s'ouvre à nousMathias Seguy
 
CocoaHeads An Android Overview (fr)
CocoaHeads An Android Overview (fr)CocoaHeads An Android Overview (fr)
CocoaHeads An Android Overview (fr)Mathias Seguy
 

More from Mathias Seguy (6)

Treatment, Architecture and Threads
Treatment, Architecture and ThreadsTreatment, Architecture and Threads
Treatment, Architecture and Threads
 
Architecture et Bonnes pratiques Android #DevoxxFr2016 Part2
Architecture et Bonnes pratiques Android #DevoxxFr2016 Part2Architecture et Bonnes pratiques Android #DevoxxFr2016 Part2
Architecture et Bonnes pratiques Android #DevoxxFr2016 Part2
 
Architecture et Bonnes pratiques Android #DevoxxFr2016 Part1
Architecture et Bonnes pratiques Android #DevoxxFr2016 Part1Architecture et Bonnes pratiques Android #DevoxxFr2016 Part1
Architecture et Bonnes pratiques Android #DevoxxFr2016 Part1
 
Conférence "Architecture Android" du 19 Mars 2013 par Mathias Seguy fondateur...
Conférence "Architecture Android" du 19 Mars 2013 par Mathias Seguy fondateur...Conférence "Architecture Android" du 19 Mars 2013 par Mathias Seguy fondateur...
Conférence "Architecture Android" du 19 Mars 2013 par Mathias Seguy fondateur...
 
Android un nouveau futur s'ouvre à nous
Android un nouveau futur s'ouvre à nousAndroid un nouveau futur s'ouvre à nous
Android un nouveau futur s'ouvre à nous
 
CocoaHeads An Android Overview (fr)
CocoaHeads An Android Overview (fr)CocoaHeads An Android Overview (fr)
CocoaHeads An Android Overview (fr)
 

Recently uploaded

My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 

Recently uploaded (20)

My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 

Animate Me! if you don't do it for me, do it for Chet - DroidconLondon2015

  • 2. If you don't do it for me, do it for chet !
  • 4. Animation is life Animationis comprehension Animation is engagements Animationis delightedyour UX Animationis necessary Animation is simple
  • 6. Because we wantyou to animate your application !
  • 7.
  • 8. Alpha Rotate Translate Scale And the plan transformations are yours V1 <set android:interpolator="@[package:]anim/interpolator_resource"> <alpha android:duration="float" android:fromAlpha="float" android:toAlpha="float" /> <scale android:duration="float" android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" /> <translate android:duration="float" android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" /> <rotate android:duration="float" android:fromDegrees="float" android:toDegrees="float" android:pivotX="float" android:pivotY="float" /> <set> ... </set> </set> Animation animIn= AnimationUtils.loadAnimation(ctx, R.anim.generic_anim); edtMessage.startAnimation(animIn); animation/generic_anim.xml Onlychange pixelsnotthe state of the view
  • 9. Makes animations generic V11 /** * The in Animation for after HC */ AnimatorSet animInHC; animInHC = (AnimatorSet) AnimatorInflater.loadAnimator(ctx, R.animator.generic_anim); animInHC.setTarget(edtMessage); animInHC.setTarget(btnAdd); animInHC.start(); <set > <objectAnimator android:duration="1000" android:propertyName="translationX" android:valueFrom="-250" android:valueTo="0" android:valueType="floatType" /> <objectAnimator android:duration="1000" android:propertyName="scaleX" android:valueFrom="0.0" android:valueTo="1.0" android:valueType="floatType" /> </set> animator-v11/generic_anim.xml Changes the state of the object
  • 10. Uses Handler and Runnable Simplebut dangerous(memory leak, runs inUI thread, can generates frames drops) Not optimized Animationis changingthe view/objectstate by droppingchanges inthe UI thread Handler clipDrawableHandler=new Handler(); Runnable clipDrawableRunnable=new Runnable() { @Override public void run() { myView.changeSomething(level); clipDrawableHandler.postDelayed(clipDrawableRunnable,32); } }; V1
  • 11. Uses Handler and Runnable Simplebut dangerous(memory leak, runs inUI thread, can generates frames drops) Not optimized V11 Animationis changingthe view/objectstate by droppingchanges inthe UI thread Handler clipDrawableHandler=new Handler(); Runnable clipDrawableRunnable=new Runnable() { @Override public void run() { myView.changeSomething(level); clipDrawableHandler.postDelayed(clipDrawableRunnable,32); } };
  • 12.
  • 13. Don't be scared, it's simple. How do yougofrom the pointfromto the pointto? V1 t1t0 v0 v1 from to ? i(t)=v, where i(t0)=v0 and i(t1)=v1 float time
  • 14. It can be straight V1 t1t0 v0 v1 from to linear
  • 15. t1t0 v0 v1 Youcan use the system's ones V1 t1t0 v0 v1 from to deceleration acceleration to from t1t0 v0 v1 to bouncing from <set android:interpolator= "@android:anim/accelerate_interpolator"> <set android:interpolator= "@android:anim/decelerate_interpolator"> <set android:interpolator= "@android:anim/bounce_interpolator" >
  • 16. Or buildyour own. V1 t1t0 v0 v1 from to alcoholic public class MyInterpolator implements Interpolator { float v; @Override public float getInterpolation(float input) { //v=i(input) return v; }...}
  • 17.
  • 19. ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable TransitionDrawable StateListDrawable AnimatedStateListDrawable AnimatedVectorDrawable Handler clipDrawableHandler=new Handler(); Runnable clipDrawableRunnable=new Runnable() { @Override public void run() {level++; clipDrawableHorizontal.setLevel(level); clipDrawableHandler.postDelayed(clipDrawableRunnable,32); } }; <?xml version="1.0" encoding="utf-8"?> <clip xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_android2ee" android:clipOrientation="horizontal" android:gravity="left" /> V1
  • 20. RotateDrawable rotateDrawableWheel; Handler rotateDrawableHandler=new Handler(); Runnable rotateDrawableRunnable=new Runnable() { public void run() {level++; rotateDrawableWheel.setLevel(level); rotateDrawableHandler.postDelayed(rotateDrawableRunnable,32); } }; <?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_android2ee" android:fromDegrees="0" android:pivotX="50%" android:pivotY="50%" android:toDegrees="360" /> V1 ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable TransitionDrawable StateListDrawable AnimatedStateListDrawable AnimatedVectorDrawable
  • 21. ScaleDrawable scaleDrawable; Handler scaleDrawableHandler=new Handler(); Runnable scaleDrawableRunnable=new Runnable() { public void run() {level++; scaleDrawable.setLevel(level); scaleDrawableHandler.postDelayed(scaleeDrawableRunnable,32); } }; <?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@mipmap/ic_edit" android:scaleGravity="center" android:scaleHeight="100%" android:scaleWidth="100%" /> V1 ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable TransitionDrawable StateListDrawable AnimatedStateListDrawable AnimatedVectorDrawable
  • 22. animationDrawable.start(); <animation-list android:id="@+id/selected" android:oneshot="false"> <item android:drawable="@drawable/attack_magic1" android:duration="100" /> <item android:drawable="@drawable/attack_magic2" android:duration="100" /> <item android:drawable="@drawable/attack_magic3" android:duration="100" /> <item android:drawable="@drawable/attack_magic4" android:duration="100" /> </animation-list> ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable TransitionDrawable StateListDrawable AnimatedStateListDrawable AnimatedVectorDrawable V1
  • 23. transitionDrawable.startTransition(3000); transitionDrawable.reverseTransition(3000); <?xml version="1.0" encoding="utf-8"?> <transition xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@mipmap/ic_ok" /> <item android:drawable="@mipmap/ic_nok" /> </transition> ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable TransitionDrawable StateListDrawable AnimatedStateListDrawable AnimatedVectorDrawable V1
  • 24. <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" android:enterFadeDuration="300" android:exitFadeDuration="300"> <!--Sorry below v21 there is no animated selector you can just fade in and fade out--> <item android:id="@+id/item_pressed" android:state_pressed="true"> <bitmap android:src="@drawable/ic_android2ee"/></item> <item android:id="@+id/item_normal"> <bitmap android:src="@drawable/ic_nut"/> </item> </selector> fade fade Norma l Press ed Norma l View state Displ ay V 1 ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable TransitionDrawable StateListDrawable AnimatedStateListDraw able AnimatedVectorDrawabl e
  • 25. <?xml version="1.0" encoding="utf-8"?> <animated-selector > <item android:id="@+id/item_pressed" android:state_pressed="true"> <bitmap android:src="@drawable/ic_android2ee"/></item> <item android:id="@+id/item_normal"> <bitmap android:src="@drawable/ic_nut"/> </item> <transition android:fromId="@+id/item_pressed" android:toId="@+id/item_normal"> <animation-list android:id="@+id/selected" android:oneshot="true"> <item android:drawable="@drawable/attack_magic1" android:duration="100" /> <item android:drawable="@drawable/attack_magic2" android:duration="100" /> </animation-list></transition></animated-selector> V21 Normal Pressed NormalView state Display ClipDrawable RotateDrawable ScaleDrawable AnimationDrawable TransitionDrawable StateListDrawable AnimatedStateListDrawable AnimatedVectorDrawable
  • 26. <?xml version="1.0" encoding="utf-8"?> <vector android:viewportWidth="500" android:viewportHeight="500" android:width="500px" android:height="500px"> <!--Make group to animate them separately using ObjectAnimator--> <!--Define the pivot in the group they will be used by ObjectAnimator--> <group android:name="tete" android:pivotX="250.0" android:pivotY="100.0"> <path android:name="head" android:fillColor="#9FBF3B" android:pathData="..." /> </group>...</vector> <?xml version="1.0" encoding="utf-8"?> <animated-vector android:drawable="@drawable/my_svg" > <target android:name="tete" android:animation="@anim/anim_svg" /> </animated-vector> <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/a ndroid"> <!-- res/anim/rotation.xml --> <objectAnimator android:duration="6000" android:propertyName="rotation" android:valueFrom="0" android:valueTo="360" /> </set> drawable/my_svg drawable/my_svg_animated anim/anim_svg use us e layout/my_view use <ImageView android:id="@+id/imvAnimatedVector" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:src="@drawable/my_svg_animated"/> animatedVectorDrawable.start(); V21 TransitionDrawable StateListDrawable AnimatedStateListDrawable AnimatedVectorDrawable
  • 27. <?xml version="1.0" encoding="utf-8"?> <vector android:viewportWidth="500" android:viewportHeight="500" android:width="500px" android:height="500px"> <!--Make group to animate them separately using ObjectAnimator--> <!--Define the pivot in the group they will be used by ObjectAnimator--> <group android:name="tete" android:pivotX="250.0" android:pivotY="100.0"> <path android:name="head" android:fillColor="#9FBF3B" android:pathData="..." /> </group>...</vector> <?xml version="1.0" encoding="utf-8"?> <animated-vector android:drawable="@drawable/my_svg" > <target android:name="tete" android:animation="@anim/animpath_svg" /> </animated-vector> <?xml version="1.0" encoding="utf-8"?> <set > <!-- res/anim/rotation.xml --> <objectAnimator android:duration="6000" android:propertyName="pathData" android:valueFrom="M300,70 l 0,-70 70,70 0,0 - 70,70z" android:valueTo="M300,70 l 0,-70 70,0 0,140 - 70,0 z" android:valueType="pathType"/> </set> drawable/my_svg drawable/my_svg_animated anim/animpath_svg use us e layout/my_view use <ImageView android:id="@+id/imvAnimatedVector2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:src="@drawable/my_svg_animated"/> animatedVectorDrawable.start(); V21 TransitionDrawable StateListDrawable AnimatedStateListDrawable AnimatedVectorDrawable
  • 28. The constraints that killfor path transformation: "Note that the paths must be compatible for morphing.In more details, the paths shouldhave exact same lengthof commands , and exact same lengthof parameters for each commands." It means: youwon't use it expect for so simpletrick (arrow to hamburger). =>Waiting for tools ! V21
  • 29. And here it is !!! https://github.com/bonnyfone/vectalign V21
  • 30. To create Svg and/orsimplify them https://inkscape.org/ To convertSvg intoVectorDrawable http://inloop.github.io/svg2android/ A goodpractice : Define your path in aString file (resvaluesmy_path_string.xml) V21 But even with that it's the hell on earth =>working ona Github project
  • 31.
  • 32. Make it simple and magic: Youcan animate any view translationX ,translationY, rotationX, rotationY, rotation, scaleX, scaleY, pivotX,pivotY, x,y,alphaand more with onelineof code! myView.animate().setDuration(300).x(20).rotationY(60).start(); V13
  • 34. Makes animations simple,magic and generic V13
  • 35. First extends what youwant (Objector View or what ever) public class BlueDot extends View { V13
  • 36. Define the propertyto animate using set/*MyProperty*/ public class BlueDot extends View { /** * The property to animate * * @param parameter value of the state to calculate the animation of the object */ private void setToto(int parameter) { /*Do your stuff, (call invalidate to redraw view)*/ V13
  • 37. Then animate public class BlueDot extends View { /** * The property to animate * @param parameter value of the state to calculate the animation of the object */ private void setToto(int parameter) {/*Do your stuff,(call invalidate to redraw view)*/ ObjectAnimator.ofInt(blueDot, "toto", 0, 110) .start(); V13
  • 38. ClipDrawable Handler clipDrawableHandler=new Handler(); Runnable clipDrawableRunnable=new Runnable() { @Override public void run() {level++; clipDrawableHorizontal.setLevel(level); clipDrawableHandler.postDelayed(clipDrawableRunnable,32); } }; <?xml version="1.0" encoding="utf-8"?> <clip xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_android2ee" android:clipOrientation="horizontal" android:gravity="left" /> It was before Works with every think ! V13
  • 39. Works with every think ! public class MyActivity extends Activity{ private void setMoveDrawable(int level){ clipDrawableHorizontal.setLevel(level); } private void animateDrawable() { ObjectAnimator.ofInt(this, "MoveDrawable", 0, 10000).start(); } No more Handler neither Runnable!!! yes thanks Chet ! V13
  • 40.
  • 43. One xmllineto add <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/llSceneRoot" android:animateLayoutChanges="true" > One lineof code to add if(postICS){ LayoutTransition transition = ((ViewGroup)findViewById(R.id.llSceneRoot)).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.(==size) transition.enableTransitionType(LayoutTransition.CHANGING); } v16
  • 44. v16v8
  • 45. Youhave the choicebetween Custom animation Intent slidingActivity = new Intent(this, SlidingActivity.class); ActivityCompat.startActivity(this, slidingActivity, translationBundle);} v16v8 Bundle translationBundle = ActivityOptionsCompat.makeCustomAnimation(this, R.anim.anim_push_left_in_a2ee,R.anim.anim_push_left_out_a2ee).toBundle();
  • 46. Youhave the choicebetween Custom animation Scaling Component Intent slidingActivity = new Intent(this, SlidingActivity.class); ActivityCompat.startActivity(this, slidingActivity, translationBundle);} v16v8 Bundle translationBundle = ActivityOptionsCompat.makeCustomAnimation(this, R.anim.anim_push_left_in_a2ee,R.anim.anim_push_left_out_a2ee).toBundle(); Bundle translationBundle = ActivityOptionsCompat.makeScaleUpAnimation(btnScaling,0,0,btnScaling.getWidth(), btnScaling.getHeight() ).toBundle();
  • 47. Youhave the choicebetween: Custom animation Scaling Component Scaling bitmap Intent slidingActivity = new Intent(this, SlidingActivity.class); ActivityCompat.startActivity(this, slidingActivity, translationBundle);} Bundle translationBundle = ActivityOptionsCompat.makeCustomAnimation(this, R.anim.anim_push_left_in_a2ee,R.anim.anim_push_left_out_a2ee).toBundle(); Bundle translationBundle = ActivityOptionsCompat.makeScaleUpAnimation(btnScaling,0,0,btnScaling.getWidth(), btnScaling.getHeight() ).toBundle(); Bundle translationBundle = ActivityOptionsCompat.makeThumbnailScaleUpAnimation(imvSmiley,bitmap,0,0) .toBundle(); v16v8
  • 48. Youhave the choicebetween: Custom animation Scaling Component Scaling bitmap You needto reverse : public class otherActivity extends Activity { public void finish() { super.finish(); //this work for all version superior to level 5 overridePendingTransition(R.anim.anim_push_right_in_a2ee, R.anim.anim_push_right_out_a2ee); }} v16v8
  • 49. Awesome First manage your theme <resources> <!-- Thanks to :--> <!-- http://code.tutsplus.com/tutorials/introduction-to-the-new-lollipop-activity-transitions&#45;&#45;cms-23711--> <!-- Base application theme. --> <style name="AppTheme" parent="BaseTheme"> <!-- Set the transition between activities effective --> <item name="android:windowContentTransitions">true</item> <item name="android:windowEnterTransition">@android:transition/slide_bottom</item> <item name="android:windowExitTransition">@android:transition/slide_bottom</item> <item name="android:windowAllowEnterTransitionOverlap">true</item> <item name="android:windowAllowReturnTransitionOverlap">true</item> <item name="android:windowSharedElementEnterTransition">@android:transition/move</item> <item name="android:windowSharedElementExitTransition">@android:transition/move</item> </style> </resources> v21
  • 50. Set the android:transitionName to your components <ImageButton android:id="@+id/ibtnSprite" android:transitionName="@string/imvSprite_transition" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_gravity="center" android:src="@drawable/attack_magic_animation" /> <ImageView android:id="@+id/imvSprite" android:transitionName="@string/imvSprite_transition" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@drawable/attack_magic_animation" /> layout/main_activity layout/other_activity v21
  • 51. Make yourpairs and launchthe new Activity if (isPostLollipop) { ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation( this, new Pair<View, String>(imvSprites, getString(R.string.imvSprite_transition)), ); } ActivityCompat.startActivity(MainActivity.this, intent, options.toBundle()); } v21
  • 52.
  • 53. 53
  • 56. 56 Its the natural evolution of the ListView, the ViewHolder is the one responsible of the view management public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View myView=inflater.inflate(R.layout.recyclerview,container,false); recyclerView= (RecyclerView) myView.findViewById(R.id.my_recycler_view); // use a layout manager recyclerViewLayoutManager = getLayoutManager(); recyclerView.setLayoutManager(recyclerViewLayoutManager); // specify an adapter (see also next example) recyclerViewAdapter = new RecyclerViewAdapter(humans,getActivity()); recyclerView.setAdapter(recyclerViewAdapter); return myView ; } find the View set the LayoutManager set the Adapter
  • 57. 57 This is the same code as for the ListView (ViewHolder next slide) public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{ /****Attributes (t for temp)**/ private ArrayList<Human> humans; private LayoutInflater inflater; private View tNewView; private ViewHolder tViewHolder; private Human tHuman; /****** Constructor**/ public RecyclerViewAdapter(ArrayList<Human> dataSet,Context ctx){ humans=dataSet; inflater=LayoutInflater.from(ctx); } @Override public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { tNewView=inflater.inflate(R.layout.simple_item,parent,false); tViewHolder=new ViewHolder(tNewView); return tViewHolder; } @Override public void onBindViewHolder(RecyclerViewAdapter.ViewHolder holder, int position) { tHuman=humans.get(position); holder.getTxvName().setText(tHuman.getName()); holder.getTxvFirstName().setText(tHuman.getFirstName()); holder.getTxvMessage().setText(tHuman.getMessage()); } @Override public int getItemCount() { return humans.size(); }
  • 58. 58 This is the same code as for the ListView (ViewHolder next slide) public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{ /****Attributes (t for temp)**/ private ArrayList<Human> humans; private LayoutInflater inflater; private View tNewView; private ViewHolder tViewHolder; private Human tHuman; /****** Constructor**/ public RecyclerViewAdapter(ArrayList<Human> dataSet,Context ctx){ humans=dataSet; inflater=LayoutInflater.from(ctx); } @Override public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { tNewView=inflater.inflate(R.layout.simple_item,parent,false); tViewHolder=new ViewHolder(tNewView); return tViewHolder; } @Override public void onBindViewHolder(RecyclerViewAdapter.ViewHolder holder, int position) { tHuman=humans.get(position); holder.getTxvName().setText(tHuman.getName()); holder.getTxvFirstName().setText(tHuman.getFirstName()); holder.getTxvMessage().setText(tHuman.getMessage()); } @Override public int getItemCount() { return humans.size(); } Inflate the view and its viewHolder Return the ViewHolder Update the View using the ViewHolder Set your DataSet and your LayoutInflater
  • 59. 59 Le ViewHolder gère la vue qu'il encapsule public class ViewHolder extends RecyclerView.ViewHolder{ TextView txvName=null; TextView txvFirstName=null; TextView txvMessage=null; View.OnClickListener clickListener; int position; public ViewHolder(View itemView) { super(itemView); txvName= (TextView) itemView.findViewById(R.id.txvName); txvFirstName= (TextView) itemView.findViewById(R.id.txvFirstName); txvMessage= (TextView) itemView.findViewById(R.id.txvMessage); clickListener=new View.OnClickListener() { public void onClick(View v) {changeTxvMessageVisibilityState(); } }; itemView.setOnClickListener(clickListener); } public TextView getTxvFirstName() {return txvFirstName;} public TextView getTxvMessage() {return txvMessage;} public TextView getTxvName() {return txvName;} public void changeTxvMessageVisibilityState(){ //Do the stuff } }
  • 60. 60 Le LinearLayoutManager public RecyclerView.LayoutManager getLayoutManager() { return new LinearLayoutManager(getContext()); }
  • 61. 61 Le StaggeredLayoutManager public RecyclerView.LayoutManager getLayoutManager() { StaggeredGridLayoutManager stagLayoutManager=new StaggeredGridLayoutManager(2,GridLayoutManager.VERTICAL); stagLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS); return stagLayoutManager; }
  • 62. 62 Le GridLayoutManager public RecyclerView.LayoutManager getLayoutManager() { GridLayoutManager gridLayoutManager=new GridLayoutManager(getContext(),2,GridLayoutManager.VERTICAL,false); //define specific span of specific cells according to a rule gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int arg0) { return (arg0 % 3) == 0 ? 2 : 1; } }); return gridLayoutManager; }
  • 63. 63
  • 70. 71 <android.support.design.widget.AppBarLayout ... > <android.support.design.widget.CollapsingToolbarLayout ... > <ImageView ... /> <android.support.v7.widget.Toolbar ... /> </android.support.design.widget.CollapsingToolbarLayout> <android.support.design.widget.TabLayout /> </android.support.design.widget.AppBarLayout> collapsingToolbar.setContentScrimResource(R.drawable.cardview_background_toolbar);
  • 71.
  • 74. 75 activity_main.xml <?xml version="1.0" encoding="utf-8"?> <android.support.v4.view.ViewPager android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/viewpager" android:background="#FF00F0F0"> </android.support.v4.view.ViewPager> public class MainActivity extends ActionBarActivity { private MyPagerAdapter pagerAdapter; private ViewPager viewPager; @Override protected void onCreate(Bundle savedInstanceState) { ... //instanciate the PageAdapter pagerAdapter=new MyPagerAdapter(this); //Find the viewPager viewPager = (ViewPager) super.findViewById(R.id.viewpager); // Affectation de l'adapter au ViewPager viewPager.setAdapter(pagerAdapter); } V13
  • 75. 76 public class MyPagerAdapter extends FragmentPagerAdapter { private final ArrayList<Fragment> fragments; public MyPagerAdapter(ActionBarActivity ctx) { super(ctx.getSupportFragmentManager()); fragments = new ArrayList<Fragment>(); //A stuff I never did before, instanciate my fragment Fragment frag =new MyFragment1(); fragments.add(frag);... } public Fragment getItem(int position) { return fragments.get(position); } public int getCount() {return fragments.size(); } V13
  • 76. 77 public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { ... //instanciate the PageAdapter pagerAdapter=new MyPagerAdapter(this); //Find the viewPager viewPager = (ViewPager) super.findViewById(R.id.viewpager); // Affectation de l'adapter au ViewPager viewPager.setAdapter(pagerAdapter); if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB){ viewPager.setPageTransformer(true, new PageTransformer(this)); } V13
  • 77. 78 public class MyPageTransformer implements ViewPager.PageTransformer{ RecyclerView myRecyclerView; public void transformPage(View view, float position) { //Only the main layout is passed here/ myRecyclerView= (RecyclerView) view.findViewById(R.id.my_recycler_view); if (position < -1) { // [-Infinity,-1)This page is way off-screen to the left. view.setAlpha(0); } else if (position < 1) { //in the visible range [-1,1] myRecyclerView.setAlpha(1-Math.abs(position)); view.setAlpha(1); if (position < 0) {//coming from left myRecyclerView.setRotationX((position * 360)); } else {//coming from right myRecyclerView.setRotationX(-1*position *360); } } else { // (1,+Infinity] // This page is way off-screen to the right. view.setAlpha(0); } }} V13
  • 78.
  • 79. How to get the screen size ? @SuppressLint("NewApi") private void getViewSize() { //this is an usual trick when we want to know the dimension of our view //initialize dimensions of the view WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); Display display = wm.getDefaultDisplay(); if (postICS) { Point size = new Point(); display.getSize(size); width = size.x; height = size.y; } else { width = display.getWidth(); // deprecated height = display.getHeight(); // deprecated } } V1
  • 80. Whencustomizing youview, youhave to overwrite the followingmethod: protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); this.w = w; this.h = h; centerX = w / 2; centerY = h / 2; //...} V1
  • 81. Use the ViewTreeObserver private void getEditButtonWidth() { //this is an usual trick when we want to know the dimension of the elements of our view //find the dimension of the EditButton ViewTreeObserver vto = btnEdit.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { btnEdit.getViewTreeObserver().removeGlobalOnLayoutListener(this); btnEditWidth = btnEdit.getMeasuredWidth(); } }); } V1
  • 82. Use the LayoutParameter of the ViewGroup private void changeImvSprite1Size(){ //Change the LayoutParameter to change the size of view if(isImvSprite1Expended){ imvSprite1.setLayoutParams(imvSpritesLayoutParamNormal); }else{ imvSprite1.setLayoutParams(imvSpritesLayoutParamExpanded); } isImvSprite1Expended=!isImvSprite1Expended; } private void initializeImvSpriteSize() { //get the real size of the components imvSprite1Height = imvSprite1.getMeasuredHeight(); //initialize the layout parameter for the normal size imvSpritesLayoutParamNormal = new LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, imvSprite1Height); //initialize the layout parameter for the expanded size imvSpritesLayoutParamExpanded= new LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, 2*imvSprite1Height);} private LinearLayout.LayoutParams imvSpritesLayoutParamNormal, imvSpritesLayoutParamExpanded ; V1
  • 83. Invalidate and dirtyArea or layoutRequest V1
  • 84. Make yourownpaint : Paint dotPaint= new Paint(); //initialize the shader (stuff that make the color of the paint depending on // the location in the screen and a set of colors) //@chiuki at droidcon london int[] rainbow = getRainbowColors(); Shader shader = new LinearGradient(0, 0, 0, w, rainbow, null, Shader.TileMode.MIRROR); Matrix matrix = new Matrix(); matrix.setRotate(90); shader.setLocalMatrix(matrix); dotPaint.setShader(shader); private int[] getRainbowColors() { return new int[]{ getResources().getColor(R.color.rainbow_red), getResources().getColor(R.color.rainbow_yellow), getResources().getColor(R.color.rainbow_green), getResources().getColor(R.color.rainbow_turquoise), getResources().getColor(R.color.rainbow_blue), getResources().getColor(R.color.rainbow_purple) };} V1
  • 85. First: Simplifyyour layout!!! if not enoughyoucan also: User LayerType Hardware accelerated btnDoNotPress.setLayerType(View.LAYER_TYPE_HARDWARE,null); new Animator.AnimatorListener() { public void onAnimationEnd(Animator animation) { btnDoNotPress.setLayerType(View.LAYER_TYPE_NONE, null); } V1