Showing posts with label Android. Show all posts
Showing posts with label Android. Show all posts

Sunday, June 9, 2013

Overflowing ListView





What this project is : 
  • Overflowing list lays out items across a view when list is scrolled to bottom
  • Allows interaction on list items as well as view covered
  • A behaviour like clippingChildren to false with some initial top padding
What this project is NOT: 

  • Best way to do this, its a hacky solution, an ideal solution would be overriding AdapterView or a ViewGroup
Why did I implement this: 

  • Imitating an implementation from an iOS app.
Source: 

Thursday, September 6, 2012

Google Now Cards Layout

If you are a fan of Google's android applications, you must haven't missed cards animation that Google Now brings in on Android 4.1, Jelly Bean.

Google Now Cards Layout on Jellybean

Lets see how to create these smooth animations.

You can browse the source here : https://github.com/shardul/Android/tree/master/NowLayout

Step 1 : Animations and Styles

There are two animations of similar sliding transition, differing slightly for alternating cards (technically Views). One rotating in from left and other for right. 

slide_up_left.xml


<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator" >

    <translate
        android:duration="@integer/config_slide_time"
        android:fromYDelta="100%p"
        android:toYDelta="0" />

    <alpha
        android:duration="@integer/config_slide_time"
        android:fromAlpha="0.0"
        android:toAlpha="1.0" />

    <rotate
        android:duration="@integer/config_slide_time"
        android:fromDegrees="25"
        android:pivotX="0"
        android:pivotY="0"
        android:toDegrees="0" />

</set>

slide_up_right.xml


<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator" >

    <translate
        android:duration="@integer/config_slide_time"
        android:fromYDelta="100%p"
        android:toYDelta="0" />

    <alpha
        android:duration="@integer/config_slide_time"
        android:fromAlpha="0.0"
        android:toAlpha="1.0" />

    <rotate
        android:duration="@integer/config_slide_time"
        android:fromDegrees="-25"
        android:pivotX="100%"
        android:pivotY="0"
        android:toDegrees="0" />

</set>

These animations will create alternate card animations.

NowLayout.java


package com.shardul.nowlayout;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.AnimationUtils;
import android.widget.LinearLayout;

public class NowLayout extends LinearLayout implements OnGlobalLayoutListener {

 public NowLayout(Context context, AttributeSet attrs) {
  super(context, attrs);
  initLayoutObserver();

 }

 public NowLayout(Context context) {
  super(context);
  initLayoutObserver();
 }

 private void initLayoutObserver() {
        // force vertical orientation and add observer
                setOrientation(LinearLayout.VERTICAL);
  getViewTreeObserver().addOnGlobalLayoutListener(this);
 }

 @Override
 public void onGlobalLayout() {
  getViewTreeObserver().removeGlobalOnLayoutListener(this);

  final int heightPx =getContext().getResources().
                getDisplayMetrics().heightPixels;

  boolean inversed = false;
  final int childCount = getChildCount();

 for (int i = 0; i < childCount; i++) {
  View child = getChildAt(i);

  int[] location = new int[2];

  child.getLocationOnScreen(location);

  if (location[1] > heightPx) {
   break;
  }

  if (!inversed) {
   child.startAnimation(
                        AnimationUtils.loadAnimation(getContext(),
      R.anim.slide_up_left));
   } else {
   child.startAnimation(
                        AnimationUtils.loadAnimation(getContext(),
      R.anim.slide_up_right));
   }

   inversed = !inversed;
  }

 }

}


This is where all the magic will happen. To create alternating animations we can definitely grab each child and start respective animation in activity but a better approach would be to create custom layout and handle animation there which is a better approach to take.

Integrating 


Now we have to make use of NowLayout in our activity.

main.xml


<ScrollView 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:fillViewport="true" >

    <com.shardul.nowlayout.NowLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#e3e3e3"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/txtView"
            style="@style/nowCardStyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/hello_world"
            tools:context=".MainActivity" />

        <TextView
            android:id="@+id/txtView"
            style="@style/nowCardStyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/hello_world"
            tools:context=".MainActivity" />

        <TextView
            android:id="@+id/txtView"
            style="@style/nowCardStyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/hello_world"
            tools:context=".MainActivity" />

        <TextView
            android:id="@+id/txtView"
            style="@style/nowCardStyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/hello_world"
            tools:context=".MainActivity" />

        <TextView
            android:id="@+id/txtView"
            style="@style/nowCardStyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/hello_world"
            tools:context=".MainActivity" />
    </com.shardul.nowlayout.NowLayout>

</ScrollView>

MainActivity.java


package com.shardul.nowlayout;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
 }

}

And there you have it. Run the app and see sliding cards similar to Google Now app.

Make sure you share with your friends if you like what you created.

You can also learn about Creating Chrome Style Help Popups on Android.

Wednesday, September 5, 2012

SOAP Calls With SOAPIntentService

WikiSOAP, originally defined as Simple Object Access Protocol, is a protocol specification for exchanging structured information in the implementation of Web Services in computer networks. It relies on Extensible Markup Language (XML) for its message format, and usually relies on otherApplication Layer protocols, most notably Hypertext Transfer Protocol (HTTP) and Simple Mail Transfer Protocol (SMTP), for message negotiation and transmission.

Being a developer, various server interaction methodologies come across you. SOAP being one of them when high security and reliability of transmission is concerned during server communication. Though it adds overhead (large payloads) it largely being used for enterprise level apps.

By default, SOAP isn't bundled with Android (unlike JSON). We have external libraries available which can be used to achieve this task.

One of these is kSoap2, official project http://code.google.com/p/ksoap2-android/

Lets talk about SOAPIntentService


Android Docs : IntentService is a base class for Services that handle asynchronous requests (expressed as Intents) on demand. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.

This "work queue processor" pattern is commonly used to offload tasks from an application's main thread. The IntentService class exists to simplify this pattern and take care of the mechanics. To use it, extend IntentService and implement onHandleIntent(Intent). IntentService will receive the Intents, launch a worker thread, and stop the service as appropriate.

All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application's main loop), but only one request will be processed at a time.

SOAPIntentService working

SOAP Intent Service, accepts a call and executes it on another thread, and responds back to caller via 
Broadcast Receiver

It's also designed to cache on failure when POST is set as request type.

You can acquire source from here : https://github.com/shardul/Android/tree/master/SoapIntentService

Usage


// initialise request helper with appropriate parameters from wsdl definition
SOAPRequestHelper soapRequestHelper = new SOAPRequestHelper(namespace,
    action, methodName, url);

// set properties for request using SOAPNameValuePair instances
SOAPNameValuePair[] props = new SOAPNameValuePair[2];
props[0]=new SOAPNameValuePair("param1","value1");
props[1]=new SOAPNameValuePair("param2","value2");

soapRequestHelper.setProperties(props);


// optionally set headers for request using SOAPNameValuePair instances

SOAPNameValuePair[] headers = new SOAPNameValuePair[2];
headers[0]=new SOAPNameValuePair("header1","headervalue1");
headers[1]=new SOAPNameValuePair("header2","headervalue2");

soapRequestHelper.setHeaders(headers);


//perform a call to SOAPIntentService using

soapRequestHelper.performSOAPRequest(this, responseReceiver);


responseReceiver defined above is a BroadcastReceiver and is an optional parameter. It should only be used when caller do bothers about the response. responseReceiver will be internally registered thus it should accompany a context.unregisterReceiver(responseReceiver) when service call is dealt with.

Heres how responseReceiver code definition should look like


private class ResponseReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
       // initialise response received
 SOAPResponseHelper soapResponseHelper = new SOAPResponseHelper(
    intent);

        //check if theres an exception
 if (!soapResponseHelper.isException()) {
  responseMap = soapResponseHelper.getResponseMap();
  showDialog(DIALOG_RESPONSE);
 } else {
 Toast.makeText(SoapIntentActivityActivity.this,
 soapResponseHelper.getException().toString(),Toast.LENGTH_LONG).show();
 }
 }

}

Additionally caching can be enabled on the call by setting requestType as post of SOAPRequetHelper class


soapRequestHelper.setRequestType(SOAPRequestHelper.REQUEST_TYPE_POST)

And don't forget to include internet permission in your AndroidManifest.xml


<uses-permission android:name="android.permission.INTERNET" />


For further implementation details, you can browse sample code here.

https://github.com/shardul/Android/blob/master/SoapIntentService/src/com/shardul/android/soapservice/activities/SoapIntentActivityActivity.java

Feel free to email me or post comments regarding implementation and enhancements.

Wednesday, August 29, 2012

Chrome Style Help Popups

If you love browsing on your phone with Google Chrome browser, you must have seen these quick help popups that appear when you first start Chrome.

Chrome Style Help Popups Demo

Those "floating" popups will surely come handy when you want to show some quick info about your in-app widgets or to be more technical Views in your application. 

You can pull / download entire Eclipse project source from my Github repo :


Or stick through to see how to create one of these.

Step 1 : Creating Resources Required

First lets create some resources that will create look and feel of those popups. Create a new Android project and add following resources to the project directory

Background: 


<shape android:shape="rectangle" 
  xmlns:android="http://schemas.android.com/apk/res/android">

    <corners android:radius="4dp">

    <solid android:color="#3a68a9">

    <stroke android:color="#32588c" android:width="1dp">

</stroke></solid></corners></shape>


This will define a new shape drawable, save this in res/drawable/blue_bg.xml


Floating Animation

Create new animation which will be used to create a floating fill to our popups, in this case defined animation is much faster as that in default Chrome application but you can play with it according to your needs. Following snippet creates an animation which will repeat it self for infinite times.


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

    <translate
        android:interpolator="@android:anim/bounce_interpolator"
        android:duration="1000"
        android:fillAfter="true"
        android:fromYDelta="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="infinite"
        android:repeatMode="reverse"
        android:toYDelta="5%" />

</set>

Save it as res/anim/float_anim.xml.

Step 2 : Popup definition files

Now lets start with popup declarations. To match look and feel, lets define a layout, composing an up arrow (ImageView) , text (TextView) and down arrow (ImageView). 

Popup layout


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/arrow_up"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/down_arrow" />

    <TextView
        android:id="@+id/text"
        style="@style/ChromeStylePopup"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/blue_bg"
        android:scrollbars="vertical" />

    <ImageView
        android:id="@+id/arrow_down"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="-1dip"
        android:src="@drawable/up_arrow" />

</LinearLayout>

Save this layout as res/layout/popup.xml

You will have to import 2 arrow images one pointing up and other pointing down to compile this.

This layout is also referring to an external style definition, which we will create next


<resources>

    <style name="ChromeStylePopup" parent="android:Widget.TextView">
        <item name="android:gravity">center</item>
        <item name="android:minHeight">50dp</item>
        <item name="android:minWidth">75dp</item>
        <item name="android:maxWidth">150dp</item>
        <item name="android:padding">6dp</item>
        <item name="android:textColor">@android:color/white</item>
        <item name="android:textStyle">bold</item>
        <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
    </style>

</resources>

This wil go into res/values/styles.xml.

Step 3 : ChromeHelpPopup.java


package com.example.chromestylehelppopups;

import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.method.ScrollingMovementMethod;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.TextView;

public class ChromeHelpPopup {

 protected WindowManager mWindowManager;

 protected Context mContext;
 protected PopupWindow mWindow;

 private TextView mHelpTextView;
 private ImageView mUpImageView;
 private ImageView mDownImageView;
 protected View mView;

 protected Drawable mBackgroundDrawable = null;
 protected ShowListener showListener;

 public ChromeHelpPopup(Context context, String text, int viewResource) {
  mContext = context;
  mWindow = new PopupWindow(context);

  mWindowManager = (WindowManager) context
    .getSystemService(Context.WINDOW_SERVICE);


  LayoutInflater layoutInflater = (LayoutInflater) context
    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

  setContentView(layoutInflater.inflate(viewResource, null));

  mHelpTextView = (TextView) mView.findViewById(R.id.text);
  mUpImageView = (ImageView) mView.findViewById(R.id.arrow_up);
  mDownImageView = (ImageView) mView.findViewById(R.id.arrow_down);

  mHelpTextView.setMovementMethod(ScrollingMovementMethod.getInstance());
  mHelpTextView.setSelected(true);
 }

 public ChromeHelpPopup(Context context) {
  this(context, "", R.layout.popup);

 }

 public ChromeHelpPopup(Context context, String text) {
  this(context);

  setText(text);
 }

 public void show(View anchor) {
  preShow();

  int[] location = new int[2];

  anchor.getLocationOnScreen(location);

  Rect anchorRect = new Rect(location[0], location[1], location[0]
    + anchor.getWidth(), location[1] + anchor.getHeight());

  mView.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

  int rootHeight = mView.getMeasuredHeight();
  int rootWidth = mView.getMeasuredWidth();

  final int screenWidth = mWindowManager.getDefaultDisplay().getWidth();
  final int screenHeight = mWindowManager.getDefaultDisplay().getHeight();

  int yPos = anchorRect.top - rootHeight;

  boolean onTop = true;

  if (anchorRect.top < screenHeight / 2) {
   yPos = anchorRect.bottom;
   onTop = false;
  }

  int whichArrow, requestedX;

  whichArrow = ((onTop) ? R.id.arrow_down : R.id.arrow_up);
  requestedX = anchorRect.centerX();

  View arrow = whichArrow == R.id.arrow_up ? mUpImageView
    : mDownImageView;
  View hideArrow = whichArrow == R.id.arrow_up ? mDownImageView
    : mUpImageView;

  final int arrowWidth = arrow.getMeasuredWidth();

  arrow.setVisibility(View.VISIBLE);

  ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams) arrow
    .getLayoutParams();

  hideArrow.setVisibility(View.INVISIBLE);

  int xPos = 0;

  // ETXTREME RIGHT CLIKED
  if (anchorRect.left + rootWidth > screenWidth) {
   xPos = (screenWidth - rootWidth);
  }
  // ETXTREME LEFT CLIKED
  else if (anchorRect.left - (rootWidth / 2) < 0) {
   xPos = anchorRect.left;
  }
  // INBETWEEN
  else {
   xPos = (anchorRect.centerX() - (rootWidth / 2));
  }

  param.leftMargin = (requestedX - xPos) - (arrowWidth / 2);

  if (onTop) {
   mHelpTextView.setMaxHeight(anchorRect.top - anchorRect.height());

  } else {
   mHelpTextView.setMaxHeight(screenHeight - yPos);
  }

  mWindow.showAtLocation(anchor, Gravity.NO_GRAVITY, xPos, yPos);

  mView.setAnimation(AnimationUtils.loadAnimation(mContext,
    R.anim.float_anim));

 }

 protected void preShow() {
  if (mView == null)
   throw new IllegalStateException("view undefined");

  
  
  if (showListener != null) {
   showListener.onPreShow();
   showListener.onShow();
  }

  if (mBackgroundDrawable == null)
   mWindow.setBackgroundDrawable(new BitmapDrawable());
  else
   mWindow.setBackgroundDrawable(mBackgroundDrawable);

  mWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
  mWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
  mWindow.setTouchable(true);
  mWindow.setFocusable(true);
  mWindow.setOutsideTouchable(true);

  mWindow.setContentView(mView);
 }

 public void setBackgroundDrawable(Drawable background) {
  mBackgroundDrawable = background;
 }

 public void setContentView(View root) {
  mView = root;

  mWindow.setContentView(root);
 }

 public void setContentView(int layoutResID) {
  LayoutInflater inflator = (LayoutInflater) mContext
    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

  setContentView(inflator.inflate(layoutResID, null));
 }

 public void setOnDismissListener(PopupWindow.OnDismissListener listener) {
  mWindow.setOnDismissListener(listener);
 }

 public void dismiss() {
  mWindow.dismiss();
  if (showListener != null) {
   showListener.onDismiss();
  }
 }

 public void setText(String text) {
  mHelpTextView.setText(text);
 }

 public static interface ShowListener {
  void onPreShow();
  void onDismiss();
  void onShow();
 }

 public void setShowListener(ShowListener showListener) {
  this.showListener = showListener;
 }
}


Above is the magic code that will glue everything up and will create floating chrome style popups for you. There are few I would like you to focus on :

  1. Constructors are used to initialise view of the popup, along with additional secondary constructors initializing texts.
  2. This also defines a static interface ShowListener which can be used to give callbacks.
  3. To invoke popups show() should be called with an "Anchor" view.
  4. show() is the magic method where all calculations of screen alignment is done.
You have everything you need!

Step 4 : Lets do some popups!

Lets stress test this popup we created, create a new layout xml file and save it in res/layout/main.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:weightSum="5" >

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />
    </LinearLayout>
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:weightSum="5" >

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />
    </LinearLayout>
    
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:weightSum="5" >

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />
    </LinearLayout>
    
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:weightSum="5" >

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />
    </LinearLayout>
    
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:weightSum="5" >

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />
    </LinearLayout>
    
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:weightSum="5" >

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />
    </LinearLayout>
    
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:weightSum="5" >

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />
    </LinearLayout>
    
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:weightSum="5" >

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_weight="1"
            android:onClick="clicked"
            android:text="Popup"
            tools:context=".MainActivity" />
    </LinearLayout>
    

</LinearLayout>

This will create rows of buttons saying "Popup" and will call clicked method of referring activity when clicked. Considering MainActivity.java is your launcher activity lets update its source to

MainActivity.java


package com.example.chromestylehelppopups;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends Activity {

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
 }

 @Override
 protected void onResume() {
  super.onResume();
 }

 public void clicked(View view) {
  ChromeHelpPopup chromeHelpPopup = new ChromeHelpPopup(MainActivity.this,"Hello!");
  chromeHelpPopup.show(view);
 }

}

And you are done! Wasn't that easy ? After you run this application, you should see something like this.

Creating Chrome Style Help Popups final output

Don't forget to add comments :)

You can also visit another post which describes Creating Google Now Cards on Android.