Android Material Design and Standards.

Android 5.0 and Material Design

Screenshot
We have updated the I/O app with material design and the Android 5.0 SDK! For a quick preview of the new tactile surfaces, animated touch feedback, bold use of color, and refreshed iconography, check out this teaser video.

Source

The source code in this repository reflects the app as of I/O 2014.
All Material UI
Download Zip File
 www.icons4android.com
https://github.com/snowdream/awesome-android

Features

With the app, you can:
  • View the conference agenda and edit your personal schedule
  • Sync your schedule between all of your devices and the I/O website
  • View detailed session, code lab, office hours, and speaker information, including speaker bios, photos, and Google+ profiles
  • +1 sessions right from the app
  • Participate in public #io14 conversations on Google+
  • Guide yourself using the vector-based conference map
  • Get a reminder a few minutes before sessions in your schedule are due to start
  • View information about companies in the Developer Sandbox
  • Play "I/O Live" session video streams
  • Beam session details from your NFC-enabled device to another using Android Beam
  • Scan attendee badges on your NFC-enabled device
  • See a list of people whose badges you have scanned, and take notes about your meeting with them
  • Send feedback on sessions, from your phone/tablet, or from your Android Wear device

How to Work with the Source

We hope the source code for this app is useful for you as a reference or starting point for creating your own apps. Here is some additional reading to help you better understand and reuse this code.

The Google I/O 2014 Android App
https://play.google.com/store/apps/details?id=com.google.samples.apps.iosched

Material Design UI Android Template App 


Download demo app!
We made this beautiful Android UI template with idea to provide developers easy and practical way to make their apps also beautiful. With our Android UI template you don’t need to loose your precious time to set up pre-designed graphic – we did it for you!
All elements are inspired with Android Lollipop Material Design and created by their instructions.
Also all elements are available to be used in older versions of Android so you don’t need to have expensive smartphone to have awesome Material design. You can easily implement components from Android UI template just by following our huge and well organized documentation.
Your’s is just to code, we do the design.
Easy as cake. Happy coding! :)
Download demo app!













Full feature list



To be able to have all of these beautiful elements available, we had to use some open source projects to achieve this. We have described in documentation and shown in our demo app how to use these projects. This is the list of projects we used to bring beautiful design in life:
  • Universal Image Loader – link – Used for effective image loading. Take a look at library for more details.
  • Ken Burns View – link – Extended ImageView that is capable of showing Ken Burns Effect.
  • Progress Wheel – link – Progress bar.
  • Circular Progress Button – link – Yet another example of a progress bar.
  • Float Labeled Text Field – link – This project allows us to show hint text above edit text when we start typing. This might be useful when you have prepopulated Edit Text fields, or when you have a large number of them to show user what is purpose of every Edit Text field.
  • Material Ripple Layout – link – We use this project to bring Material design ripple effect to api levels lower then Lollipop API level (pre-21). If you want to get ripple effect, add MaterialRippleLayout to your xml layout, then nest you own views into it.
  • Pull Zoom View – link – This project allows us to show parallax effect with image that is attached on top of ListView or ScrollView. You can see an example by clicking the link of project.
  • Not Boring ActionBar – link – Take a look at this link for more details.
  • Shape Image View – link – This project allows us to create different shapes around images using ImageViews. Visit link for more information.
  • List View Animations – link – For the most beautiful animations you want with your ListView items, use this project. To use this project with Sticky List Headers, use project below (Sticky List Headers).
  • Sticky List Headers – link – Sticky list headers project allows you to have headers drown above ListView (like the ones you have in Instagram application). For more information, take a look at a the link.
  • Animated Expandable List View – link – This project is used to animate expanded list items in ExpandableListView.     


How To Make Material Design Sliding Tabs  

In this tutorial we are going to implement sliding tabs in material design style by using the SlidingTabLayout from Google iosched app, The SlidingTabLayout is also provided on the Google developer page as well but it isn't updated with some methods such as setDistributeEvenly() and this method is actually needed to make fixed tabs, the Google ioshed version is more updated and so we are going to use that. Along with the SlidingTabLayout.java we would be needing the SlidingTabStrip.java, Okay so let's start making the Sliding Tabs.

 Requirements


1. Android Studio 1.0.1 (latest)

2. SlidingTabLayout.java & SlidingTabStrip.java from IOsched Google App and copy past both the files in your project


Understanding Sliding Tab Layout Implementation




As you can see we have we have made the Linear Layout as the root element for our activity and made the orientation of the LinearLayout as vertical so the elements would be placed one after another, First I have added the toolbar on which I have already made a separate tutorial on how to make a material design toolbar, Next element that I have added is the SlidingTabLayout which acts like a Tab Strip, you can place this strip anywhere in your layout but I want it to be above the pages that are being swiped so I am placing it just below the Toolbar, Next you add the View Pager which is required for swiping the pages. In the code you define every view and then set the SlidingTabs.SetViewPager method to the ViewPager in your activity which is where you tell the app that on page swipe of your View Pager you want the tabs to swipe and change as well.




Steps To Implement Sliding Tab Layout


1. First let's decide the color scheme for our app I want the color scheme to be red so lets do that by making a new color.xml file in your values folder and add the following code to it. You may notice a item in the color.xml with name ScrollColor that is the color which I am going to set to the scroll bar of the Tab Strip.


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="ColorPrimary">#e62117</color>
    <color name="ColorPrimaryDark">#c31c13</color>
    <color name="tabsScrollColor">#8a140e</color>

</resources>


2. Next we need to make a layout file for toolbar and add that layout file to our apps activity_main.xml. So create a new layout file and name it tool_bar.xml and add the following code to it.


<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:background="@color/ColorPrimary"
    android:elevation="2dp"
    android:theme="@style/Base.ThemeOverlay.AppCompat.Dark"
    xmlns:android="http://schemas.android.com/apk/res/android" />

3. Now its time to add Toolbar and the SlidingTabLayout to our main_activity.xml, To add SlidingTablayout in your app you must make sure you have already added the SlidingTabLayout.java and SlidingTabStrip.java in your app as explained in the requirements section at the top. If you have added both the files in your project, open your main_activity.xml and add the following code to it. I have given the SlidigTabLayout an id ="Tabs" and added a elevation of 2dp for the shadow effect.


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <include
        androidd.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <include
        android:id="@+id/tool_bar"
        layout="@layout/tool_bar"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        />

    <com.android4devs.slidingtab.SlidingTabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:elevation="2dp"
        android:background="@color/ColorPrimary"/>

</LinearLayout>  

4. Now we just have to add the ViewPager view to your layout, make sure to give it an Id, I have given my ViewPager an Id called pager. Finally your main_activiy.xml looks something like this.


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <include
        android:id="@+id/tool_bar"
        layout="@layout/tool_bar"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        />

    <com.android4devs.slidingtab.SlidingTabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:elevation="2dp"
        android:background="@color/ColorPrimary"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"

        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:layout_weight="1"
        ></android.support.v4.view.ViewPager>



</LinearLayout>

5. Now I have decided to make 2 tabs for this project, so I have to make the layout for this tabs, so I have created two new layouts tab_1.xml and tab_2.xml and added the medium text view inside both the layout as shown below.

tab_1.xml


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="You Are In Tab 1"
        android:id="@+id/textView"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />

</RelativeLayout>

tab_2.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="You Are In Tab 2"
        android:id="@+id/textView"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />

</RelativeLayout>

Now I am done with my layout section and its time to work things out in the code.

6. Now let's first make the 2 fragments for Tab1 and Tab2, So go ahead and create two new java files, name it Tab1 and Tab2 and add the following code to it.

Tab1


package com.android4devs.slidingtab;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * Created by hp1 on 21-01-2015.
 */
public class Tab1 extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v =inflater.inflate(R.layout.tab_1,container,false);
        return v;
    }
}


Tab2


package com.android4devs.slidingtab;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * Created by hp1 on 21-01-2015.
 */
public class Tab2 extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.tab_2,container,false);
        return v;
    }
}


7. Now before we start working with MainActiviy we need a ViewPager adapter to provide the views for every page i.e every Tab. So go ahead and make a new java file, name it ViewPagerAdapter and add the following code to it. I have added the comments to help you understand the working.


package com.android4devs.slidingtab;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;

/**
 * Created by hp1 on 21-01-2015.
 */
public class ViewPagerAdapter extends FragmentStatePagerAdapter {

    CharSequence Titles[]; // This will Store the Titles of the Tabs which are Going to be passed when ViewPagerAdapter is created
    int NumbOfTabs; // Store the number of tabs, this will also be passed when the ViewPagerAdapter is created


    // Build a Constructor and assign the passed Values to appropriate values in the class
    public ViewPagerAdapter(FragmentManager fm,CharSequence mTitles[], int mNumbOfTabsumb) {
        super(fm);

        this.Titles = mTitles;
        this.NumbOfTabs = mNumbOfTabsumb;

    }

    //This method return the fragment for the every position in the View Pager
    @Override
    public Fragment getItem(int position) {

        if(position == 0) // if the position is 0 we are returning the First tab
        {
            Tab1 tab1 = new Tab1();
            return tab1;
        }
        else             // As we are having 2 tabs if the position is now 0 it must be 1 so we are returning second tab
        {
            Tab2 tab2 = new Tab2();
            return tab2;
        }


    }

    // This method return the titles for the Tabs in the Tab Strip

    @Override
    public CharSequence getPageTitle(int position) {
        return Titles[position];
    }

    // This method return the Number of tabs for the tabs Strip

    @Override
    public int getCount() {
        return NumbOfTabs;
    }
}


8. Now we have everything ready to start work with the MainActivity.java, So go ahead and add the following code to your MainActivity.java. check out the comments in the code to understand the working.


package com.android4devs.slidingtab;

import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;


public class MainActivity extends ActionBarActivity {

    // Declaring Your View and Variables

    Toolbar toolbar;
    ViewPager pager;
    ViewPagerAdapter adapter;
    SlidingTabLayout tabs;
    CharSequence Titles[]={"Home","Events"};
    int Numboftabs =2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        // Creating The Toolbar and setting it as the Toolbar for the activity

        toolbar = (Toolbar) findViewById(R.id.tool_bar);
        setSupportActionBar(toolbar);


        // Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
        adapter =  new ViewPagerAdapter(getSupportFragmentManager(),Titles,Numboftabs);

        // Assigning ViewPager View and setting the adapter
        pager = (ViewPager) findViewById(R.id.pager);
        pager.setAdapter(adapter);

        // Assiging the Sliding Tab Layout View
        tabs = (SlidingTabLayout) findViewById(R.id.tabs);
        tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width

        // Setting Custom Color for the Scroll bar indicator of the Tab View
        tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
            @Override
            public int getIndicatorColor(int position) {
                return getResources().getColor(R.color.tabsScrollColor);
            }
        });

        // Setting the ViewPager For the SlidingTabsLayout
        tabs.setViewPager(pager);



    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}


Now everything is set, Lets just run our app and check out how it looks




Its Looks perfect. Tabs are working nicely. But what if you want to customize the text color of your Tabs Title for a specific event i.e on Page selected etc and you surely would like to tell the user about the active tab he is on. For this you have to make a selector.xml in  your res/color/ folder and add the following code to your selector.xml, of course change the colors as your requirements


<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:color="@android:color/white" />
    <item android:state_focused="true" android:color="@android:color/white" />
    <item android:state_pressed="true" android:color="@android:color/white" />
    <item android:color="#8a140e" />
</selector> 

After making the selector you have to add it in your SlidingTabLayout.java, Look for a method called  private void populateTabStrip() and add the following line of code at the end of it.


tabTitleView.setTextColor(getResources().getColorStateList(R.color.selector));
tabTitleView.setTextSize(14);


Look at the SlidingTabLayout code below, I have just copy pasted populateTabStrip() method in which you are suppose to do the changes


private void populateTabStrip() {
        final PagerAdapter adapter = mViewPager.getAdapter();
        final View.OnClickListener tabClickListener = new TabClickListener();

        for (int i = 0; i < adapter.getCount(); i++) {
            View tabView = null;
            TextView tabTitleView = null;

            if (mTabViewLayoutId != 0) {
                // If there is a custom tab view layout id set, try and inflate it
                tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
                        false);
                tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
            }

            if (tabView == null) {
                tabView = createDefaultTabView(getContext());
            }

            if (tabTitleView == null && TextView.class.isInstance(tabView)) {
                tabTitleView = (TextView) tabView;
            }

            if (mDistributeEvenly) {
                LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) tabView.getLayoutParams();
                lp.width = 0;
                lp.weight = 1;
            }

            tabTitleView.setText(adapter.getPageTitle(i));
            tabView.setOnClickListener(tabClickListener);
            String desc = mContentDescriptions.get(i, null);
            if (desc != null) {
                tabView.setContentDescription(desc);
            }

            mTabStrip.addView(tabView);
            if (i == mViewPager.getCurrentItem()) {
                tabView.setSelected(true);
            }
            tabTitleView.setTextColor(getResources().getColorStateList(R.color.selector));
            tabTitleView.setTextSize(14);
        }
    }


Finally, Everything is set and we are done. Let's just run the app and check out how things work.




Well that's just looks amazing, So with this you have learned how to make Sliding Tabs in Material Design style, If you like this tutorial please subscribe to the blog for coming updates.
















Material design Introduction
















Introduction


























We challenged ourselves to create a visual language for our users that synthesizes the classic principles of good design with the innovation and possibility of technology and science. This is material design. This spec is a living document that will be updated as we continue to develop the tenets and specifics of material design.














Goals














Create a visual language that synthesizes classic principles of good design with the innovation and possibility of technology and science.



























Develop a single underlying system that allows for a unified experience across platforms and device sizes. Mobile precepts are fundamental, but touch, voice, mouse, and keyboard are all first-class input methods.














Principles




























Material is the metaphor

A material metaphor is the unifying theory of a rationalized space and a system of motion. The material is grounded in tactile reality, inspired by the study of paper and ink, yet technologically advanced and open to imagination and magic.
Surfaces and edges of the material provide visual cues that are grounded in reality. The use of familiar tactile attributes helps users quickly understand affordances. Yet the flexibility of the material creates new affordances that supercede those in the physical world, without breaking the rules of physics.
The fundamentals of light, surface, and movement are key to conveying how objects move, interact, and exist in space and in relation to each other. Realistic lighting shows seams, divides space, and indicates moving parts.


Add Floating Button With list view

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#f0f0f0f0" >
        
        <ListView
            android:id="@+id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:headerDividersEnabled="true"
    android:footerDividersEnabled="true"
            android:listSelector="@android:color/transparent"
    android:cacheColorHint="@android:color/transparent"
    android:divider="@null"
            android:dividerHeight="10dp" >
        </ListView>
        
    </FrameLayout>

    <ImageView
        android:id="@+id/createactivity"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:src="@drawable/roundedfloatbuttonimage"
        android:layout_gravity="bottom|right"
        android:layout_margin="20dp" />

</FrameLayout>















Bold, graphic, intentional

The foundational elements of print-based design—typography, grids, space, scale, color, and use of imagery—guide visual treatments. These elements do far more than please the eye. They create hierarchy, meaning, and focus. Deliberate color choices, edge-to-edge imagery, large-scale typography, and intentional white space create a bold and graphic interface that immerse the user in the experience.
An emphasis on user actions makes core functionality immediately apparent and provides waypoints for the user.















Motion provides meaning

Motion respects and reinforces the user as the prime mover. Primary user actions are inflection points that initiate motion, transforming the whole design.
All action takes place in a single environment. Objects are presented to the user without breaking the continuity of experience even as they transform and reorganize.
Motion is meaningful and appropriate, serving to focus attention and maintain continuity. Feedback is subtle yet clear. Transitions are efficient yet coherent.


What is material? Environment

Environment

















3D world

The material environment is a 3D space, which means all objects have x, y, and z dimensions. The z-axis is perpendicularly aligned to the plane of the display, with the positive z-axis extending towards the viewer. Every sheet of material occupies a single position along the z-axis and has a standard 1dp thickness.


















Light and shadow









Within the material environment, virtual lights illuminate the scene and allow objects to cast shadows. A key light creates directional shadows, while an ambient light creates consistent, soft shadows from all angles.
All shadows in the material environment are cast by these two light sources. Shadows are the absence of light resulting from the occlusion of these light sources by sheets of material at various positions along the z-axis.



























Shadow cast by key light















Shadow cast by ambient light















Combined shadow from key and ambient lights



Promoted Actions

Floating Action Button (FAB)

Custom component

Material design

Recently new design pattern were introduced in Android. One of the most known pattern is the Promoted Actions. They are actions that  are directly visible in the UI instead of using action bar button; for this reason these actions are called promoted, they can be easily accessed and define the main action in the current UI. For example, if we are using an email app and we are listing the inbox folder, one promoted action can be a new mail. The visual pattern is called Float Action Button (or FAB) because the promoted action can be represented using a floating circular button on the UI.
This type of design patterns are available in Android L but we can create a floating button also in previous Android version. Let us suppose we have a list of elements in our UI, the promoted action can be ‘Add new item’, so we can have something like the pic shown below:

android_floating_action_button_1

There are several way we can use to crate a floating action button.

Floating action button using ImageButton

The first way to create a FAB is using the ImageButton, we simply add the ImageButton to our UI layout and exploit some new features provided by Android L.
<ImageButton
android:layout_width="56dp"
android:layout_height="56dp"
android:src="@drawable/plus"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginRight="16dp"
android:layout_marginBottom="16dp"
android:tint="@android:color/white"
android:id="@+id/fab"
android:elevation="1dp"
android:background="@drawable/ripple"
android:stateListAnimator="@anim/fab_anim"
/>

If we look above, we can notice it is a normal ImageButton that we place usually at lower right corner. There are some aspects we should consider:
  • Background
  • Shadow
  • Animation



To make our button more “attractive”, we can implement some effect as background. If we notice we use a ripple drawable defined in this way:
<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="?android:colorControlHighlight">
    <item>
        <shape android:shape="oval">
            <solid android:color="?android:colorAccent" />
        </shape>
    </item>
</ripple>

We said it is a floating button, so it means it should float above the UI data as if it was in another plane level. This effect can be obtained using the elevation attribute that “moves”  our UI component on Z-axis. The last thing is the animation effect as we press the button. We want to give to the user the feeling the button is sinking as we press it, so we have to enlarge the shadow around it:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_enabled="true"
        android:state_pressed="true">
        <objectAnimator
            android:duration="@android:integer/config_shortAnimTime"
            android:propertyName="translationZ"
            android:valueFrom="@dimen/start_z"
            android:valueTo="@dimen/end_z"
            android:valueType="floatType" />
    </item>
    <item>
        <objectAnimator
            android:duration="@android:integer/config_shortAnimTime"
            android:propertyName="translationZ"
            android:valueFrom="@dimen/end_z"
            android:valueTo="@dimen/start_z"
            android:valueType="floatType" />
    </item>
</selector>


Floating Action Button using a Custom Component 

https://github.com/survivingwithandroid/Surviving-with-android

Another way to create our Floating Button is using a custom component. In this case we don’t use the Android L feature but we code it manually.

As first thing, we create our class that represents the custom component:
public class CustomFAB extends ImageButton {
...
}

The next step is reading some custom attributes that affect the UI behavior, we can do it in the method called init:
private void init(AttributeSet attrSet) {
    Resources.Theme theme = ctx.getTheme();
    TypedArray arr = theme.obtainStyledAttributes(attrSet, R.styleable.FAB, 0, 0);
    try {
        setBgColor(arr.getColor(R.styleable.FAB_bg_color, Color.BLUE));
        setBgColorPressed(arr.getColor(R.styleable.FAB_bg_color_pressed, Color.GRAY));
        StateListDrawable sld = new StateListDrawable();

        sld.addState(new int[] {android.R.attr.state_pressed}, createButton(bgColorPressed));
        sld.addState(new int[] {}, createButton(bgColor));
        setBackground(sld);
    }

    catch(Throwable t) {}
    finally {
         arr.recycle();
    }

}

At the same time we define these attributes in a XML file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="FAB">
        <!-- Background color -->
        <attr name="bg_color" format="color|reference"/>
        <attr name="bg_color_pressed" format="color|reference"/>
    </declare-styleable>
</resources>

If you notice we have some attribute that control the background color. At line 8 we define several button states using StateListDrawable and for each state we create our button:
private Drawable createButton(int color) {
    OvalShape oShape = new OvalShape();
    ShapeDrawable sd = new ShapeDrawable(oShape);
    setWillNotDraw(false);
    sd.getPaint().setColor(color);

    OvalShape oShape1 = new OvalShape();
    ShapeDrawable sd1 = new ShapeDrawable(oShape);

    sd1.setShaderFactory(new ShapeDrawable.ShaderFactory() {
        @Override
        public Shader resize(int width, int height) {
            LinearGradient lg = new LinearGradient(0,0,0, height,
                    new int[] {
                            Color.WHITE,
                            Color.GRAY,
                            Color.DKGRAY,
                            Color.BLACK
                    }, null, Shader.TileMode.REPEAT);

            return lg;
        }
    });

    LayerDrawable ld = new LayerDrawable(new Drawable[] { sd1, sd });
    ld.setLayerInset(0, 5, 5, 0, 0);
    ld.setLayerInset(1, 0, 0, 5, 5);

    return ld;
}

Finally we can add this component to our Layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:custom="http://schemas.android.com/apk/res/com.survivingwithandroid.fab"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MyActivity">
...

    <com.survivingwithandroid.fab.CustomFAB
        android:layout_width="56dp"
        android:layout_height="56dp"
        android:src="@android:drawable/ic_input_add"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_marginRight="16dp"
        android:layout_marginBottom="16dp"
        custom:bg_color="@color/light_blue"
        android:tint="@android:color/white"
     />
     
</RelativeLayout>

source code available @ github

https://github.com/survivingwithandroid/Surviving-with-android


Android Google Map: Add weather data

Android Google map: Add weather data

This post describes how to add weather layer to google map. We want to add weather information to a map so that we can have a look about clouds, temperature, pressure and so on.
In the previous post we talked about how to get weather information and how to parse the data to create a UI, now we want to add other weather tile to a map. To do it, we start creating a sample project that contains a map activity.
If we use Android Studio (as i suggest) it is very simple and fast.

Create Android Map Project In Android Studio

The first step is creating a google map project in Android. As always, we select File->New project and after inserting some project information we land to this page:


Now we select Google Map Activity. Android Studio will create all the things to handle google map in our project. The last thing to do is to add the key to use the map. If you look in the files inside the project you will find the way to create your debug key. Once you have the key, you are ready to use the map.

Add Weather Tile To Google Map

The next step is adding weather tile to google map. To this purpose, we will use Open Weather Map as weather provider, but you could use other weather providers. We modify the setUpMap inside our MapsActivity (or the name of the class you used when you created the project) and add a new TileProvider. A Tile provider is essential an interface that we have to implement in our provider so that we fetch the image that covers the map. A tile is an image that is represented over the map. In the case of OWM, the URL we have to use to retrieve the image is:

http://tile.openweathermap.org/map/%s/%d/%d/%d.png

where %s represents the type of the tile we want to use like clouds, temperature and so on while the other three integers (%d) represent the zoom and x, y coords. 
In our case, we use a UrlTileProvider that can be used to retrieve tiles from an HTTP connection. Our implementation is very simple:

    private TileProvider createTilePovider() {
        TileProvider tileProvider = new UrlTileProvider(256, 256) {
            @Override
            public URL getTileUrl(int x, int y, int zoom) {
                String fUrl = String.format(OWM_TILE_URL, tileType == null ? "clouds" : tileType, zoom, x, y);
                URL url = null;
                try {
                    url = new URL(fUrl);
                }
                catch(MalformedURLException mfe) {
                    mfe.printStackTrace();
                }

                return url;
            }
        } ;

Finally in our setUpMap() method we add our tile provider to the map: 

tileOver = mMap.addTileOverlay(new TileOverlayOptions().
                tileProvider(createTransparentTileProvider()));

where tileOver is an instance of TileOverlay. Running the example we get:

Add Weather Data Tiles

Now we want to add a Spinner over our map so that we can select the type of information we want to add on top of the map like temperature, wind, pressure and so on.
This is very simple because we can modify the activity_maps.xml and add our spinner:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <fragment  android:id="@+id/map"
      android:name="com.google.android.gms.maps.SupportMapFragment"
      android:layout_width="match_parent" 
      android:layout_height="match_parent"
      tools:context=".MapsActivity" />

  <Spinner
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true"
      android:layout_alignParentRight="true"
      android:layout_marginBottom="10dp"
      android:layout_marginRight="10dp"
      android:id="@+id/tileType"/>

</RelativeLayout>

Finally in the onCreate() we add the code to handle the spinner:

        spinner = (Spinner) findViewById(R.id.tileType);

        String[] tileName = new String[]{"Clouds", "Temperature", "Precipitations", "Snow", "Rain", "Wind", "Sea level press."};

        ArrayAdapter adpt = new ArrayAdapter(this, android.R.layout.simple_spinner_item, tileName);

        spinner.setAdapter(adpt);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

            @Override
            public void onNothingSelected(AdapterView parent) {

            }

            @Override
            public void onItemSelected(AdapterView parent, View view, int position, long id) {
                 // Check click
                switch (position) {
                    case 0:
                        tileType = "clouds";
                        break;
                    case 1:
                        tileType = "temp";
                        break;
                    case 2:
                        tileType = "precipitation";
                        break;
                    case 3:
                        tileType = "snow";
                        break;
                    case 4:
                        tileType = "rain";
                        break;
                    case 5:
                        tileType = "wind";
                        break;
                    case 6:
                        tileType = "pressure";
                        break;

                }

                if (mMap != null) {
                    tileOver.remove();
                    setUpMap();
                }


            }
        });

We simply list all the tile types and when the user selects one of them we show the relative images on top of the map. If we select for example the temperature map we have:


If you look the image you can notice that the tile has covered almost the map behind. This happens because we don't have an easy way to modify the transparency of the map. 

Add Transparent Tile To Google Map

The last step, if we want that the weather data doesn't cover the map that stands behind, is modifying our provider. This code shown below is derived from this post. We create, in other words, a custom provider so that we can change the opacity of the images we add over the map:
public class TransparentTileOWM implements TileProvider {
    //private String url;
    private Paint opacityPaint = new Paint();
    private String tileType;

    private static final String OWM_TILE_URL = "http://tile.openweathermap.org/map/%s/%d/%d/%d.png";

    /**
     * This constructor assumes the url parameter contains three placeholders for the x- and y-positions of
     * the tile as well as the zoom level of the tile. The placeholders are assumed to be {x},
     * {y}, and {zoom}. An example
     * for an OpenWeatherMap URL would be: http://tile.openweathermap.org/map/precipitation/{zoom}/{x}/{y}.png
     *
     */
    public TransparentTileOWM(String tileType)
    {
        this.tileType = tileType;
        setOpacity(50);
    }

    /**
     * Sets the desired opacity of map {@link Tile}s, as a percentage where 0% is invisible and 100% is completely opaque.
     * @param opacity The desired opacity of map {@link Tile}s (as a percentage between 0 and 100, inclusive)
     */
    public void setOpacity(int opacity)
    {
        int alpha = (int)Math.round(opacity * 2.55);    // 2.55 = 255 * 0.01
        opacityPaint.setAlpha(alpha);
    }

    @Override
    public Tile getTile(int x, int y, int zoom)
    {
        URL tileUrl = getTileUrl(x, y, zoom);

        Tile tile = null;
        ByteArrayOutputStream stream = null;

        try
        {
            Bitmap image = BitmapFactory.decodeStream(tileUrl.openConnection().getInputStream());
            image = adjustOpacity(image);

            stream = new ByteArrayOutputStream();
            image.compress(Bitmap.CompressFormat.PNG, 100, stream);

            byte[] byteArray = stream.toByteArray();

            tile = new Tile(256, 256, byteArray);
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
        finally
        {
            if(stream != null)
            {
                try
                {
                    stream.close();
                }
                catch(IOException e) {}
            }
        }

        return tile;
    }

    /**
     * Helper method that returns the {@link URL} of the tile image for the given x/y/zoom location.
     *
     * This method assumes the URL string provided in the constructor contains three placeholders for the x-
     * and y-positions as well as the zoom level of the desired tile; {x}, {y}, and
     * {zoom}. An example for an OpenWeatherMap URL would be:
     * http://tile.openweathermap.org/map/precipitation/{zoom}/{x}/{y}.png


     *
     * @param x The x-position of the tile
     * @param y The y-position of the tile
     * @param zoom The zoom level of the tile
     *
     * @return The {@link URL} of the desired tile image
     */
    private URL getTileUrl(int x, int y, int zoom)
    {
        String tileUrl = String.format(OWM_TILE_URL, tileType, zoom, x, y);
        try
        {
            return new URL(tileUrl);
        }
        catch(MalformedURLException e)
        {
            throw new AssertionError(e);
        }
    }

    /**
     * Helper method that adjusts the given {@link Bitmap}'s opacity to the opacity previously set via
     * {@link #setOpacity(int)}. Stolen from Elysium's comment at StackOverflow.
     *
     * @param bitmap The {@link Bitmap} whose opacity to adjust
     * @return A new {@link Bitmap} with an adjusted opacity
     *
     * @see htp://stackoverflow.com/questions/14322236/making-tileoverlays-transparent#comment19934097_14329560
     */
    private Bitmap adjustOpacity(Bitmap bitmap)
    {
        Bitmap adjustedBitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(adjustedBitmap);
        canvas.drawBitmap(bitmap, 0, 0, opacityPaint);

        return adjustedBitmap;
    }

}

Now running the code and using this new provider we have: 



NFC Android:

In this post we want to describe how to read NFC tag. Android SDK provides a set of API that can be used to read the NFC payload, anyway if we look at the NFC spec we can notice there are several type of payload depending on the type of the tag. Android SDK doesn't provide any support to parse the payload and extract information, so in this post we will describe how we can read the NFC tag content. As we said in the previous post, explaining how to use NFC in Android, there are several type of NFC (NDEF) tag:
  • NFC Forum well-known type [NFC RTD] 
  • Media-type as defined in RFC 2046 
  • Absolute URI as defined in RFC 3986 
  • NFC Forum external type [NFC RTD]
We can know the NFC type using the last three bytes in the NFC header or simpler using:
?
1
short tnf = record.getTnf();

Comparing the tnf (Type Name Format) with all possible combination we can know the record type. In the code above record is an instance of NdefRecord.

NDEF Record Structure

Before analysing how to read NDEF content, it is important to know the NDEF record structure. The picture below shows the structure:


The most important byte (7th) is the Message Begin byte, this byte is 1 if the it is the starting message otherwise is zero. The 6th byte is the Message End, this byte is 1 if the this record is the end record otherwise is 0. SR is the Short Record and it is 1 if it is a short record. This information are important if we want to handle the NDEF tag data correctly.
We know that Android SDK provides the method getPayload() that returns an array of bytes that represent the tag content. We have to read and parse this array to extract information.
Let's start from the simplest record structure: text record.

Well Known Type: Text Record

This is the simplest record type and we will start from here. We know from the specification how to read the payload. The first thing we have to read is the header (payload[0]) and parse it. The most significative byte (the 7th) represent the text encoding:

?
1
2
3
4
5
6
7
byte status = payload[0];
int enc = status & 0x80; // Bit mask 7th bit 1
String encString = null;
if (enc == 0)
  encString = "UTF-8";
else
  encString = "UTF-16";

The bit from 5th to 0 represents the language length: 

?
1
int ianaLength = status & 0x3F; // Bit mask bit 5..0

Now we are ready to read the "real" content: 

?
1
2
3
4
5
6
7
try {
  String content = new String(payload, ianaLength + 1, payload.length - 1 - ianaLength, encString);
  record.payload = content;
}
catch(Throwable t) {
    t.printStackTrace();
}

Let us suppose we create  simple text/plain content with Surviving with Android. Now if we read the content we have:

02 65 6e 53 75 72 76 69 76 69 6e 67 20 77 69 74 68 20 61 6e 64 72 6f 69 64

This is the payload, and if we parse it we get:

NFC Forum External Type

This is another simple NDEF content. This type of content is built for organization that want to create a custom name space. This type of content can be useful when we want to create a special name space to run an app for example. Reading it is very simple: 

?
1
2
3
4
StringBuffer pCont = new StringBuffer();
for (int rn=0; rn < payload.length;rn++) {
   pCont.append(( char) payload[rn]);
}

All the payload is the content. 

NDEF Smart Poster

This is the most complex NDEF tag, because it can be made by several inner contents made by several types. In this case is very important to read the message header to know if the record is a Message Begin or Message end or if the record is a Short Record.
The first thing we have to do is read the header:

?
1
2
3
4
int[] result = getHeader(payload); // 0 = MB, 1 = ME, 2 = SR
int numLenByte = 1;
if (result[2] == 0)
   numLenByte = 4; // This is not a Short Record. Length = 4 byte

Now we know how many bytes is the payload length and then we have to get the length:

?
1
2
3
String byteLen = "";
for (int p = 2; p <= 2 + numLenByte - 1; p++)
   byteLen = byteLen + payload[p]; // We simply append the bytes

Then we read the record type to know how to handle it: 

?
1
2
int pos = 2 + numLenByte;
int type = payload[pos];

We can parse the payload according to the record type: 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
if (type == 'U') {
  RDTUrl url = new RDTUrl();
  result = getHeader(payload);
  url.MB = result[0];
  url.ME = result[1];
  url.SR = result[2];
  url.prefix = payload[pos];
  Log.d("NFC", "Action:" + "0x" + Integer.toHexString(url.prefix));
  url.url = new String(payload, pos + 1, Integer.parseInt(byteLen) - 1);
  Log.d("NFC", "Content:" + url.url);
  record.records.add(url);
}
else if (type == 'T') {
   RDTTextRecord text = new RDTTextRecord();
   result = getHeader(payload);
   text.MB = result[0];
   text.ME = result[1];
   text.SR = result[2];
   int len = payload[pos];
   Log.d("Nfc", "Lan len ["+len+"]");
   text.language = "";
   for (int i = pos + 1; i <= pos + len; i++)
     text.language = text.language + (char) payload[i];
     Log.d("Nfc", "Lang ["+text.language+"]");
     text.payload = new String(payload, pos + len + 1, Integer.parseInt(byteLen) - len - 1);
     Log.d("NFC", "Content:" + text.payload);
     record.records.add(text);
   }
}

And finally we move to the next message part: 

?
1
payload = Arrays.copyOfRange(payload, pos + Integer.parseInt(byteLen), payload.length);

...and of course we repeat all these things until the payload length is greater than 0. That's all.
Let us suppose we a NDEF Tag that has a link that points to this website and a text part like surviving.
The payload is:

ffffff91 1 19 55 1 73 75 72 76 69 76 69 6e 67 77 69 74 68 61 6e 64 72 6f 69 64 2e 63 6f 6d 51 1 c 54 2 65 6e 73 75 72 76 69 76 69 6e 67

Now, if we run our app we get:


We can suppose now we have a tag containing a telephone number with a label:


Source code available @github

https://github.com/survivingwithandroid/Surviving-with-android

A Guide to Android RecyclerView and CardView

The new support library in Android L introduced two new UI widgets: RecyclerView and CardView. The RecyclerView is a more advanced and more flexible version of the ListView. This new component is a big step because the ListView is one of the most used UI widgets. The CardView widget, on the other hand, is a new component that does not "upgrade" an existing component. In this tutorial, I'll explain how to use these two widgets and show how we can mix them. Let's start by diving into the RecyclerView.

RecyclerView: Introduction

As I mentioned, RecyclerView is more flexible that ListView even if it introduces some complexities. We all know how to use ListView in our app and we know if we want to increase the ListView performances we can use a pattern called ViewHolder. This pattern consists of a simple class that holds the references to the UI components for each row in the ListView. This pattern avoids looking up the UI components all the time the system shows a row in the list. Even if this pattern introduces some benefits, we can implement the ListView without using it at all. RecyclerView forces us to use the ViewHolder pattern. To show how we can use the RecyclerView, we can suppose we want to create a simple app that shows a list of contact cards. The first thing we should do is create the main layout. RecyclerView is very similar to the ListView and we can use them in the same way:
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2.       xmlns:tools="http://schemas.android.com/tools"
  3.       android:layout_width="match_parent"
  4.       android:layout_height="match_parent"
  5.       android:paddingLeft="@dimen/activity_horizontal_margin"
  6.       android:paddingRight="@dimen/activity_horizontal_margin"
  7.       android:paddingTop="@dimen/activity_vertical_margin"
  8.       android:paddingBottom="@dimen/activity_vertical_margin"
  9.       tools:context=".MyActivity">
  10.       <android.support.v7.widget.RecyclerView
  11.              android:id="@+id/cardList"
  12.              android:layout_width="match_parent"
  13.              android:layout_height="match_parent"
  14.        />    
  15. </RelativeLayout>
As you'll notice from the layout shown above, the RecyclerView is available in the Android support library, so we have to modify build.gradle to include this dependency:
  1. dependencies {
  2.        ...    
  3.        compile 'com.android.support:recyclerview-v7:21.0.0-rc1'
  4.  }
Now, in the onCreate method we can get the reference to our RecyclerView and configure it:
  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3.       super.onCreate(savedInstanceState);
  4.       setContentView(R.layout.activity_my);
  5.       RecyclerView recList = (RecyclerView) findViewById(R.id.cardList);
  6.       recList.setHasFixedSize(true);
  7.       LinearLayoutManager llm = new LinearLayoutManager(this);
  8.       llm.setOrientation(LinearLayoutManager.VERTICAL);
  9.       recList.setLayoutManager(llm);
  10. }
If you look at the code above, you'll notice some differences between the RecyclerView and ListView. RecyclerView requires a layout manager. This component positions item views inside the row and determines when it is time to recycle the views. The library provides a default layout manager calledLinearLayoutManager.

CardView

The CardView UI component shows information inside cards. We can customise its corners, the elevation and so on. We want to use this component to show contact information. These cards will be the rows of RecyclerView and we will see later how to integrate these two components. By now, we can define our card layout:
  1. <android.support.v7.widget.CardView
  2.       xmlns:card_view="http://schemas.android.com/apk/res-auto"
  3.       xmlns:android="http://schemas.android.com/apk/res/android"
  4.       android:id="@+id/card_view"
  5.       android:layout_width="match_parent"
  6.       android:layout_height="match_parent"
  7.       card_view:cardCornerRadius="4dp"
  8.       android:layout_margin="5dp">
  9.   <RelativeLayout
  10.       android:layout_width="match_parent"
  11.       android:layout_height="match_parent">
  12.      <TextView
  13.          android:id="@+id/title"
  14.          android:layout_width="match_parent"
  15.          android:layout_height="20dp"
  16.          android:background="@color/bkg_card"
  17.          android:text="contact det"
  18.          android:gravity="center_vertical"
  19.          android:textColor="@android:color/white"
  20.          android:textSize="14dp"/>
  21.     <TextView
  22.         android:id="@+id/txtName"
  23.         android:layout_width="wrap_content"
  24.         android:layout_height="wrap_content"
  25.         android:text="Name"
  26.         android:gravity="center_vertical"
  27.         android:textSize="10dp"
  28.         android:layout_below="@id/title"
  29.         android:layout_marginTop="10dp"
  30.         android:layout_marginLeft="5dp"/>
  31.     <TextView
  32.         android:id="@+id/txtSurname"
  33.         android:layout_width="wrap_content"
  34.         android:layout_height="wrap_content"
  35.         android:text="Surname"
  36.         android:gravity="center_vertical"
  37.         android:textSize="10dp"
  38.         android:layout_below="@id/txtName"
  39.         android:layout_marginTop="10dp"
  40.         android:layout_marginLeft="5dp"/>
  41.     <TextView
  42.         android:id="@+id/txtEmail"
  43.         android:layout_width="wrap_content"
  44.         android:layout_height="wrap_content"
  45.         android:text="Email"
  46.         android:textSize="10dp"
  47.         android:layout_marginTop="10dp"
  48.         android:layout_alignParentRight="true"
  49.         android:layout_marginRight="150dp"
  50.         android:layout_alignBaseline="@id/txtName"/>
  51. </RelativeLayout>
As you can see, the CardView is very simple to use. This component is available in another android support library so we have to add this dependency too:
  1. dependencies {
  2.         compile 'com.android.support:cardview-v7:21.0.0-rc1'
  3.         compile 'com.android.support:recyclerview-v7:21.0.0-rc1'
  4.  }

RecyclerView: Adapter

The adapter is a component that stands between the data model we want to show in our app UI and the UI component that renders this information. In other words, an adapter guides the way the information are shown in the UI. So if we want to display our contacts, we need an adapter for the RecyclerView. This adapter must extend a class called RecyclerView.Adapter passing our class that implements the ViewHolder pattern:
public class MyAdapter extends RecyclerView.Adapter<MyHolder> { ..... }
We now have to override two methods so that we can implement our logic: onCreateViewHolderis called whenever a new instance of our ViewHolder class is created, and onBindViewHolder is called when the SO binds the view with the data -- or, in other words, the data is shown in the UI.
In this case, the adapter helps us combine the RecyclerView and CardView. The layout we defined before for the cards will be the row layout of our contact list in the RecyclerView. Before doing it, we have to define our data model that stands at the base of our UI (i.e. what information we want to show). For this purpose, we can define a simple class:
  1. public class ContactInfo {
  2.       protected String name;
  3.       protected String surname;
  4.       protected String email;
  5.       protected static final String NAME_PREFIX = "Name_";
  6.       protected static final String SURNAME_PREFIX = "Surname_";
  7.       protected static final String EMAIL_PREFIX = "email_";
  8. }
And finally, we are ready to create our adapter. If you remember what we said before about Viewholder pattern, we have to code our class that implements it:
  1. public static class ContactViewHolder extends RecyclerView.ViewHolder {
  2.      protected TextView vName;
  3.      protected TextView vSurname;
  4.      protected TextView vEmail;
  5.      protected TextView vTitle;
  6.      public ContactViewHolder(View v) {
  7.           super(v);
  8.           vName =  (TextView) v.findViewById(R.id.txtName);
  9.           vSurname = (TextView)  v.findViewById(R.id.txtSurname);
  10.           vEmail = (TextView)  v.findViewById(R.id.txtEmail);
  11.           vTitle = (TextView) v.findViewById(R.id.title);
  12.       }
  13.  }
Look at the code, in the class constructor we get the reference to the views we defined in our card layout. Now it is time to code our adapter:
  1. public class ContactAdapter extends RecyclerView.Adapter<ContactAdapter.ContactViewHolder> {
  2.     private List<ContactInfo> contactList;
  3.     public ContactAdapter(List<ContactInfo> contactList) {
  4.             this.contactList = contactList;
  5.     }
  6.     @Override
  7.     public int getItemCount() {
  8.           return contactList.size();
  9.     }
  10.     @Override
  11.     public void onBindViewHolder(ContactViewHolder contactViewHolder, int i) {
  12.         ContactInfo ci = contactList.get(i);
  13.         contactViewHolder.vName.setText(ci.name);
  14.         contactViewHolder.vSurname.setText(ci.surname);
  15.         contactViewHolder.vEmail.setText(ci.email);
  16.         contactViewHolder.vTitle.setText(ci.name + " " + ci.surname);
  17.    }
  18.    @Override
  19.    public ContactViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
  20.         View itemView = LayoutInflater.
  21.                     from(viewGroup.getContext()).
  22.                     inflate(R.layout.card_layout, viewGroup, false);
  23.         return new ContactViewHolder(itemView);
  24.    }
  25.   public static class ContactViewHolder extends RecyclerView.ViewHolder {
  26.       ...
  27.   }
  28. }
In our implementation, we override onBindViewHolder where we bind the data (our contact info) to the Views. Notice that we don't look up UI components but simply use the references stored in our ContactViewHolder. In onCreateViewHolder we return our ContactViewHolder inflating the row layout (the CardView in our case).
Run the app and you'll get the results shown below:
Android RecyclerView with Cardview
The source code is available @github

Android chart Tutorial

In this post, I will describe how to use AchartEngine. This is a great library for Android that help you to create charts. It supports several chart types, just to name a few:
  • line chart
  • area chart
  • bar chart
  • pie chart
  • combined chart
and so on.
This library helps you in every aspects when you create a charts so you don’t need anything else to create interesting charts.

Getting Started

If you use Android Studio you can download directly the jar containing all the classes and add it to your project. When the download is completed, you should add the library under libs folder so that I can be included automatically into your project. Now you are ready to use the lib!
When you create a charts you need usually a set of data that has to be drawn in the chart, in this case to have real values and to not re-invent the wheel we can suppose we get these values using WeatherLib so that we will plot the atmospheric parameters (like temperature, and pressure..).
There some basic concepts that stand behind this library and they are important so that you can use it:
  • Dataset (The set of data you have to draw in your chart)
  • The view (or the type of chart you want)
  • Renderer (It controls how the view is drawn, settings some parameters you can change the way the charts looks like. There are two types of renderer: one that controls the rendering of the dataset and another one that controls how the main chart aspects look like (i.e. axis, labels and so on)
  • Chart factory (combines the dataset and the renderers to create the charts. The chart can be created inside an Activity or the factory can return a View.)

Line Chart

As first example, we want to create a Line chart. In this chart we will draw the temperature that is our Dataset. Considering that a line chart is an XY chart we create as first step the right series that holds the data:
?
1
XYSeries series = new XYSeries("London Temperature hourly");

next we have to populate the series using the data retrieved from WeatherLib (hourly weather forecast):
?
1
2
3
4
int hour = 0;
for (HourForecast hf : nextHourForecast) {
    series.add(hour++, hf.weather.temperature.getTemp());
}

almost done, the series contains the data. If you look carefully we represented on X-axis the hours and on Y-axis the temperature.

Remembering the basic concepts described above, we have to create a series renderer:
?
1
2
3
4
5
6
7
8
9
// Now we create the renderer
XYSeriesRenderer renderer = new XYSeriesRenderer();
renderer.setLineWidth(2);
renderer.setColor(Color.RED);
// Include low and max value
renderer.setDisplayBoundingPoints(true);
// we add point markers
renderer.setPointStyle(PointStyle.CIRCLE);
renderer.setPointStrokeWidth(3);

At line 3, we set the line width. One aspect you should consider when using achartengine is that the dimensions are expressed in pixel not in dp!. At line 4, we set the color and then at line 8 we set the Point Style, meaning the point contained in our series.

The last step is creating the renderer that controls the full charts and add the single renderer for each series:
?
1
2
XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();
mRenderer.addSeriesRenderer(renderer);

and then
?
1
2
3
4
5
6
7
// We want to avoid black border
mRenderer.setMarginsColor(Color.argb(0x00, 0xff, 0x00, 0x00)); // transparent margins
// Disable Pan on two axis
mRenderer.setPanEnabled(false, false);
mRenderer.setYAxisMax(35);
mRenderer.setYAxisMin(0);
mRenderer.setShowGrid(true); // we show the grid

A small tip: if you create a chart, you will notice that around the chart there are black borders, if you want to remove them you have to set this margin transparent (line 2). At line 5,6 we set the Y value range.

The last step is creating the View:
?
1
GraphicalView chartView = ChartFactory.getLineChartView(getActivity(), dataset, mRenderer);

Now we have the view the last step is adding it to our layout. Let us suppose we have a linear layout:
?
1
2
3
4
5
<LinearLayout
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:id="@+id/chart"
       android:orientation="vertical"/>

We add the view to it:
?
1
chartLyt.addView(chartView,0);

Running the example we have at the end:

android_temperature

 


Bar Chart


Bar chart are another type of charts that can be built using AchartEngine. In this case, we can suppose we want to plot the pressure values retrieved from WeatherLib. As we did before we have to create a data series:
?
1
2
3
4
5
6
for (HourForecast hf : nextHourForecast) {
    series.add(hour++, hf.weather.currentCondition.getPressure());
    if (hour > 24)
        break;
}

Some steps are very similar to what explained before so we can safely jump them and create the chart:
?
1
GraphicalView chartView = ChartFactory.getBarChartView(getActivity(), dataset, mRenderer, BarChart.Type.DEFAULT);

As result we get:

android_pressure

Range Bar


Range bar is special type of bar chart and it is interesting because it uses a different type of data series. A Range bar is a bar that has a lower and upper limit. We can use this type of chart if we want to plot the max and min temperature.
?
1
RangeCategorySeries series = new RangeCategorySeries("London next days temperature");

now we add the values:
?
1
2
3
4
for (DayForecast df : dayForecast) {
    series.add(df.forecastTemp.min, df.forecastTemp.max);
    mRenderer.addXTextLabel(hour++, sdf.format(df.timestamp));
}

At line 2 we set the min and max temperature adding them to the data series. At line 3 we add a label to the X-axis values. In this case we use the day number and the month:
?
1
SimpleDateFormat sdf = new SimpleDateFormat("dd,MMM");

now we add the series:
?
1
2
XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
dataset.addSeries(series.toXYSeries());

and create the series renderer:
?
1
2
3
4
5
6
7
8
XYSeriesRenderer renderer = new XYSeriesRenderer();
renderer.setDisplayChartValues(true);
mRenderer.addSeriesRenderer(renderer);
mRenderer.setYAxisMax(30.0);
mRenderer.setYAxisMin(0.0);
renderer.setChartValuesTextSize(12);
renderer.setChartValuesFormat(new DecimalFormat("#.##"));
renderer.setColor(Color.GREEN);

Some aspects to notice: at line 2, we tell to the renderer we want that the values appears on the chart, while at line 6, we set the text size. Another important aspect: the value format: at line 7, we specify that we want two digits after the decimal point. Finally, we can create the graph:
?
1
GraphicalView chartView = ChartFactory.getRangeBarChartView(getActivity(), dataset, mRenderer, BarChart.Type.DEFAULT);

Running the example we have:

android_maxmin_temp



Source code available @ github.
http://www.survivingwithandroid.com/



Game AI – An Introduction to Behaviour Trees


Game AI is a very broad subject and while there is a lot of material out there, I didn’t find something that introduces the concepts gently and at a slower, more understandable pace. This article will try to explain how to design a very simple but extendable AI system loosely based on the concept of Behaviour Trees.

What is AI?


Artificial Intelligence is the human-like behaviour exhibited by the entities participating in the game. It’s more the illusion of intelligence and thoughtful action performed by the entities than an actual intelligent reasoning driven behaviour. The goal is to try to fool the player into thinking that the other “intelligent” entities are controlled by humans and not by a machine. It’s easier said than done, but we can use a lot of tricks to achieve some really good, seemingly random and “intelligent” behaviours.
http://obviam.net/


The Essential Android Game Development Tutorials 


Games are among the most popular and profitable types of mobile applications. New games are developed and released every day on Google Play and other app marketplaces and once in a while we also come across a Flappy Bird like wonder story. This is a roundup of some of the best tutorials available online on Andorid game development that can be useful to developers in learning how to develop games for Android. Note that this list doesn’t cover any specific game engine or game creation tool, (which will be covered in later posts) but concentrates mainly on game development with Canvas/Open GL.

This set of tutorials is perhaps one of the most popular sources for learning Android game development. The comprehensive series of tutorials is also nicely organized into different units and sections. If you are a complete beginner to Java and Android you can start following the series right from Unit 1, titled “Beginning Java” and which essentially deals with various Java concepts from basics to advanced. Unit 2 & 3 covers various aspects of creating a game and lays down the foundation of gaming concepts (you can skip this too if you have created a game in Java before and are familiar with game development concepts). Unit 4 exclusively deals with Android game development and covers a wide range of topics right from setting up a development environment to creating your Android game.
A tutorial in five parts. First part discusses how to create a drawing surface and a framework for the game, second part covers the basics of how to load and display sprites when developing an Android game, the third installment of the tutorial deals with sprite animations, the fourth part walks you through the concept of collision detection while the final installment of the tutorial shows how to derive input from a user and how to use the input to influence the on-screen action (user input). The tutorial linked here is the final installment of the tutorials as it contains the links to all the previous parts. You can also download the project covered in the tutorial and import it into Eclipse.
OpenGL ES (OpenGL for Embedded Systems)  is an implementation of OpenGL for embedded devices. Android features good support for OpenGL ES and it is also widely used in developing Android games. This tutorial shows how to get started with OpenGL ES 2.0 for Android.
These series of tutorials walks you through the process of creating a simple 2-dimensional game engine for Android from scratch. During the course of development you will learn about design decisions and understand how each component works in a game engine. The series starts with a detailed introduction to OpenGL ES and then progresses to other topics such as setting up your development environment, concepts related to game engine, stage, scenes, sprites, primitive drawing, textures etc.
You can draw 2D objects in Android either on a View or with a Canvas. If you are drawing objects that need to be be redrawn regularly (which is the case in games) Canvas is the better solution. This tutorials walks you through the process of drawing a 2D object with a Canvas and also shows how to use a secondary thread to perform the drawing for better performance.
Another multi-part tutorial on Android game development. This series walks you through the process of developing a hangman game for Android and discusses the core game development concepts right from basics such as setting up your project to developing the user interface and user interaction. The tutorial also deals with topics such as adapters, XML resources, action bar etc. You can also download the source code of the project developed in the course of the tutorial.
A lengthy series of Android game development tutorials that is somewhat outdated but useful nonetheless. The series guides you through the process of developing an Android game right from the conception of the game idea to its execution. You will learn important game development concepts such as a basic game architecture, game loop, sprite animation, particle explosion, bitmap fonts, moving images on screen, MVC pattern, OpenGL ES, OpenGL texture mapping, collision detection etc. The tutorials are also accompanied with relevant illustrations and source code. You can also download the source code and the eclipse project.
This section of the Android documentation is a must read for developers getting started with OpenGL ES in Android. It walks you through the basics of developing applications using OpenGL  and covers topics such as setup, drawing objects, moving drawn elements and responding to touch input. The example code uses the  OpenGL ES 2.0 APIs. It is divided into several sections, each one of which discusses a different aspect of working with OpenGL. Building an OpenGL ES Environment, which starts the series shows you how to create a view container for  OpenGL ES while the next couple of sections guide you through the basics of how to define and draw OpenGL shapes in your application. The rest of the documentation covers various other important topics such as  how to use projection and camera views to get a new perspective on your drawn objects, how to do basic movement and animation of drawn objects, basic interaction with OpenGL graphics etc.
A series of tutorials on OpenGL ES 2.0 that specifically focuses on the 2D aspects of OpenGL ES 2.0 for Android. The tutorials are descriptive and include example source code, which are also available for download. The tutorials cover topics starting from how to render a triangle (first part) to rendering an image, handling input, transforming images, the OpenGL texture system, screens and dimensions etc.
Google Play game services lets you create great game experiences by helping you implement achievement, leaderboards, and real-time multiplaying capability to your game. These elements greatly enhance the game experience for the user/player. A leaderboard allows the players to compare their scores with other players or friends, rewards and achievements encourage better user engagement and multiplayer capability provides a competitive and cooperative experience often using social platforms. In short, you can add a lot to your game experience by utilizing the Google Play Game Services. This official documentation guides you through the basics of how to get started with Google Play Game Services.