Getting Started Guide - Informatica · Getting Started Guide - Informatica ... - Profiling
Getting Started With Material Design
-
Upload
yasin-yildirim -
Category
Technology
-
view
1.754 -
download
2
Transcript of Getting Started With Material Design
Getting Started withMaterial Design
David Montiel Yasin Yıldırım
eBay Kleinanzeigen
Who Are We?
David Montiel
● 3+ Years on Android Development
● >1 Year @eBay Kleinanzeigen
● Before worked at Google, LinkedIn, Xing.
● Enjoy staying up to date with current Android design patterns.
Who Are We?
Yasin Yıldırım
● 4+ years on Android Development
● 1,5 Year @eBay Kleinanzeigen
● Before worked at couple of software agencies in Turkey
● Passionate about Android
Android App
● German Classifieds platform● >6 Mio downloads● 4,4 / 5 stars rating (68K ratings)● Got featured on Play Store
This presentation is a very general overview
In-App Navigation● Inside the app, Up button usually means back. (But not always!)
Where Up doesn’t mean Back?
Navigation Drawer● The common pattern for navigating between main parts of your app
Swipe Between Views● Provide easiest possible navigation between Views for the user
Pure Android
● Do not mimic UI elements from other platforms
● Do not carry over platform specific icons
Pure Android
● No bottom tabs ● No labels on back buttons
● No right-pointing carets on line items
Some Material Taste?
● You will be spending much more time programming animations…
● Most of the “new” animations are provided by android, but many others continue depending on AnimationUtils, TranslateAnimation, etc..
First thing to assume...
Material design focuses on...
● Animations
● Layers
● Minimalism
Basic Items: List and Cards
● Android provides new widgets for displaying cards and lists with material design styles and animations.
Basic Items: Animations!● There are a lot of new recommended animations
Floating Elements: The Z axis● Some items in material design elevate in a Z axis, occupying a
space “closer” to the user. Use the shadow!
Floating Button: The basic example
Let’s get technical!
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:+'
compile 'com.android.support:cardview-v7:+'
compile 'com.android.support:recyclerview-v7:+'
compile 'com.android.support:palette-v7:+'
}
Add support libraries for backwards compatibility
● AppCompat: Backport for ActionBar & Material Design UI implementations
● RecyclerView: Includes RecyclerView, RecyclerView.Adapter & LayoutManagers
● CardView: Contains CardView widget to have cards layout easily
● Palette: Extracts prominent colors from an image
values/styles.xml
<!-- Base application theme. -->
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. →
<!-- your app branding color for the app bar -->
<item name="colorPrimary">@color/primary</item>
<!-- darker variant for the status bar and contextual app bars -->
<item name="colorPrimaryDark">@color/primary_dark</item>
<!-- theme UI controls like checkboxes and text fields -->
<item name="colorAccent">@color/accent</item>
</style>
Style your app
Cool new DrawerToggle
import android.support.v4.app.ActionBarDrawerToggle
import android.support.v7.app.ActionBarDrawerToggle
ActionBarDrawerToggle drawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
drawerLayout, /* DrawerLayout object */
R.string.drawer_open, /* "open drawer" description */
R.string.drawer_close /* "close drawer" description */
)
Update your imports to get the latest version
Cool new DrawerToggle - Getting the animation
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Synchronize the indicator with the state of the linked DrawerLayout
drawerToggle.syncState();
}
drawerToggle = new ActionBarDrawerToggle (this, drawerLayout, R.string.drawer_open, R.string.drawer_close) {
@Override
public void onDrawerOpened (View drawerView) {
super .onDrawerOpened(drawerView);
getSupportActionBar() .setTitle(getString( R.string.app_name));
}
@Override
public void onDrawerClosed (View drawerView) {
super .onDrawerClosed(drawerView);
getSupportActionBar() .setTitle(getString( R.string.activity_title));
}
};
Cool new DrawerToggle - Style the hamburger<!-- Base application theme. -->
<style name= "AppTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar" >
<item name= "colorPrimary" >@color/primary</item>
<item name= "colorPrimaryDark" >@color/primary_dark</item>
<item name= "colorAccent" >@color/accent</item>
<item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
</style>
<style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
<!--The size of the bars when they are parallel to each other-->
<item name="barSize">20dp</item>
<!--The max gap between the bars when they are parallel to each other-->
<item name="gapBetweenBars">4dp</item>
<!--The size of the middle bar when top and bottom bars merge into middle bar to form an arrow-->
<item name="middleBarArrowSize">20dp</item>
<!--The size of the top and bottom bars when they merge to the middle bar to form an arrow-->
<item name="topBottomBarArrowSize">15dp</item>
<!--The thickness (stroke size) for the bar paint-->
<item name="thickness">2dp</item>
<!--Whether bars should rotate or not during transition-->
<item name="spinBars">true</item>
<!--The drawing color for the bars-->
<item name="color">@android:color/white</item>
</style>
Cool new SwipeRefreshLayout
swipeRefreshLayout.setProgressBackgroundColor(R.color.accent_light);
swipeRefreshLayout.setSize(SwipeRefreshLayout.DEFAULT);
OR
swipeRefreshLayout.setSize(SwipeRefreshLayout.LARGE);
swipeRefreshLayout.setColorSchemeResources(R.color.red,R.color.blue,R.color.yellow,R.color.green);
OR
swipeRefreshLayout.setColorSchemeResources(R.color.red,R.color.yellow);
OR
swipeRefreshLayout.setColorSchemeResources(R.color.red);
● Looks better● Doesn’t move the content down & up again● More options to customize● Single or multiple colors for progress
RecyclerView
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
● Advanced & more flexible version of ListView● Recycling is more efficient● Layout managers for positioning items● Item animators for adding / removing items
RecyclerView.Adapter<VH extends RecyclerView.ViewHolder>
private static class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
// set the view's size, margins, paddings and layout parameters
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.textView.setText(dataset.get(position));
}
}
● Using a ViewHolder is mandatory
RecyclerView.ViewHolder
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public final CardView wholeListItem;
public final TextView textView;
public ViewHolder (CardView v) {
super(v);
wholeListItem = (CardView) v.findViewById( R.id.card_view);
textView = (TextView) v.findViewById( R.id.text_view);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.card_view) {
// Clicked on list item at getPosition()
} else if (v.getId() == R.id.text_view) {
// Clicked on textView at getPosition()
}
}
}
}
● There’s no OnItemClickListener for RecyclerView, ViewHolder takes care of all clicks
CardView
<android.support.v7.widget.CardView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="100dp"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="2dip"
app:cardElevation="1sp"
app:cardUseCompatPadding="true"
app:cardBackgroundColor="#fcfcfc">
</android.support.v7.widget.CardView>
Shared Elements & Activity Transitions
values-v21/styles.xml:
<style name= "AppTheme" parent="AppTheme.Base" >
<item name="android:windowContentTransitions">true</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>
● Only works with Lollipop (API Level 21)
● Activity starting is made with ActivityCompat
Shared Elements & Activity Transitions
Second Activity:
@Override
protected void onCreate( Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView( R.layout.activity_planet_detail);
image = (ImageView) findViewById( R.id.planet_image);
// Animate the shared element
ViewCompat .setTransitionName(image, "SHARED_IMAGE" );
}
First Activity:
// Define transition options
ActivityOptionsCompat options = ActivityOptionsCompat .makeSceneTransitionAnimation(this,
new Pair<View, String> (view.findViewById( R.id.grid_item_planet_image), "SHARED_IMAGE" ));
// Create intent
Intent intent = new Intent(this, PlanetDetailActivity .class);
// Start activity with defined options
ActivityCompat .startActivity(this, intent, options .toBundle());
ToolBar as ActionBar
In the activity.xml: <android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:background="@android:color/transparent"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
In the activity use a theme with no action bar: <!-- Base application theme with no actionbar. -->
<style name="AppTheme.Base.NoActionBar" parent="
AppTheme.Base">
<item name="android:windowNoTitle">true</item>
<item name="windowActionBar">false</item>
</style>
private void setupToolBar() {
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
Tangible Surfaces
public void onScrollChanged(int deltaX, int deltaY) {
int scrollY = scrollView.getScrollY();
// Move background photo (with parallax effect)
imageContainer.setTranslationY(scrollY * 0.5f);
float newTop = Math.max(imageHeightPixels, scrollY);
if (imageHeightPixels - scrollY <= toolBarHeightPixels) { // We reached the ToolBar
newTop = scrollY + toolBarHeightPixels;
}
// Reposition the name bar -- it's normally anchored to the top of the detail part,
// but locks to the bottom of the ToolBar on scroll
nameContainer.setTranslationY(newTop);
float gapFillProgress = 1;
if (imageHeightPixels != 0) {
gapFillProgress = Math.min(Math.max(getProgress(scrollY, 0, imageHeightPixels), 0), 1);
}
ViewCompat.setElevation(nameContainer, gapFillProgress * mMaxHeaderElevation);
toolbar.getBackground().setAlpha((int) (gapFillProgress * 255));
}
Color Palette
// Get palette from an image
Palette.generateAsync(bitmap, new PaletteListener());
private class PaletteListener implements Palette.PaletteAsyncListener {
@Override
public void onGenerated(Palette palette) {
lightVibrantColorFromImage =
palette.getLightVibrantColor(R.color.light_blue);
textViewPlanetName.setBackgroundColor(lightVibrantColorFromImage);
}
}
Overlapping Motion
private void expandAnimation(int position, View convertView)
{
final View finalConvertView = convertView;
convertView.postDelayed(new Runnable() {
@Override
public void run() {
Animation a = AnimationUtils.loadAnimation
(context, R.anim.scale_up_from_center);
finalConvertView.setAnimation(a);
finalConvertView.setVisibility(View.VISIBLE);
}
}, position * 30);
}
<scale android:interpolator="@android:
anim/accelerate_decelerate_interpolator"
android:duration="150"
android:fillAfter="true"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:toXScale="1.0"
android:toYScale="1.0"
android:pivotX="50%"
android:pivotY="50%" />
view.animate().translationZ(20f).setDuration(500).setListener(new Animator.AnimatorListener() {
// ..... other overriden methods
@Override
public void onAnimationEnd(Animator animation) {
view.animate().translationZ(1f).setDuration(500).start();
}
}).start();
translationZ Animation
<ImageButton android:layout_width ="@dimen/floating_button_height"
android:layout_height ="@dimen/floating_button_height"
android:layout_gravity ="bottom|end"
android:elevation="5sp"
android:layout_margin ="25dip"
android:background ="@drawable/floating_button_bg"
android:src="@drawable/ic_plus"
android:stateListAnimator ="@anim/floating_button_state_list_anim"
android:contentDescription ="@string/floating_button" />
State List Animatorfloating_button_state_list_anim:
<selector xmlns :android="http://schemas.android.com/apk/res/android" >
<item
android :state_enabled ="true"
android :state_pressed ="true">
<set>
<objectAnimator
android :duration="@android:integer/config_shortAnimTime"
android :propertyName ="translationZ"
android :valueTo="15dp"
android :valueType="floatType" />
</set>
</item>
<item>
<set>
<objectAnimator
android :duration="@android:integer/config_shortAnimTime"
android :propertyName ="translationZ"
android :valueTo="0dp"
android :valueType="floatType" />
</set>
</item>
</selector>
Last thought..Developers can make it happen but… we still need a designer...
Code & Slides
https://github.com/vudin/MaterialDesignDemo
http://goo.gl/xKJRdu
Questions?
@davidmonti @vudin
+DavidMontiel +YasinYildirimm