Search This Blog

Friday, December 12, 2014

HOWTO: Create a material design style alert box

In 2014 Google introduced us with a new interface language as they see it.
It's called "Material Design" and it's pretty great!

But what about all the other apps that uses older versions of the android SDK and that their clients may not all use "Lollipop" android version?
Well.. Google found a solution for that also, in a form of "Support Libraries".
Unfortunately, they did not cover the alert box part, and any of us who uses "Toast" until now would not have the beautiful alert boxes of Material Design.



So in this tutorial i'm going to show you how to create you own , Activity Based alert box.

Links:
This is a tutorial base on a SO answer I found and  tweeked:
http://stackoverflow.com/questions/21018283/implement-gmail-like-no-connection-alert-at-the-bottom-of-screen

All the files are in the GitHub repo:
https://github.com/DanielRasta/Material-Design-Alert-Box-

First of all, we would like to create an activity called "alert_box",
and draw inside of it only one thing: the TextView.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" 
android:background="#8A8A8A"
>
<TextView
        android:id="@+id/tvDetailsText"
        android:layout_width="fill_parent"
        android:paddingTop="10dp"
        android:layout_height="wrap_content"
        android:text="Custom Alert"
        android:textColor="#ffffff"
        android:background="#8A8A8A"
        android:textSize="20sp"
        android:typeface="sans" 
        android:gravity="center"
        android:textAlignment="center"/>
</LinearLayout>
Let's take a look at these attributes:
The LinearLayout is filling the parent and it is in a greyish kind of color.
The TextView has a text with a "Custom Alert" in a white color and the same garyish background color. Also, it's exactly in the size of it's centered text.

Next we would like to create the the code behind this activity:

public class AlertBoxView extends Activity {
static final int EXIT_DELAY= 3500;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.alert_box);
    TextView details = (TextView) findViewById(R.id.tvDetailsText);
    this.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
    String strNotificationToShow = "Oops.. Something went wrong.";
    int myParentWidth = getWindow().getAttributes().width;
    try {
        Bundle extras = getIntent().getExtras();
    if (extras != null) {
    strNotificationToShow = extras.get("AlertBoxText").toString();
    myParentWidth = extras.getInt("ParentWidth");
    }
    else
    {
    strNotificationToShow = "Oops.. Something went wrong.";
    myParentWidth = getWindow().getAttributes().width;
    }
        } catch (Exception e) {
            e.printStackTrace();
            strNotificationToShow = "Oops.. Something went wrong.";
            myParentWidth = getWindow().getAttributes().width;
        }
        finally
        {
        details.setText(strNotificationToShow);
        }
    WindowManager.LayoutParams params = getWindow().getAttributes();  
    params.width = myParentWidth;
    params.gravity = Gravity.BOTTOM;
    this.getWindow().setAttributes(params);
    Window window = this.getWindow();
    window.setAttributes((android.view.WindowManager.LayoutParams) params);
    window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
    window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
    new Handler().postDelayed(Exit(), EXIT_DELAY);
}
private Runnable Exit(){
    return new  Runnable(){     
        @Override
        public void run() {
            finish();
       }
    };
}
}
Again, lets go over the important staff.
We want to create the activity for a 3500 ms which is 3.5 seconds.
We want it the look like: no borders, filling the parent activity (passed by Extra), show the alert we wish (also by Extra) and always stay at the bottom section of the parent activity.

To call this activity from another activity, we'll need to make sure that the "Extra" parameters are passed correctly:
Intent i = new Intent("android.intent.action.ALERT");
i.putExtra("AlertBoxText","YOUR ALERT GOES HERE!");
i.putExtra("ParentWidth",this.getWindow().getAttributes().width);
startActivity(i); 

Now for the last thing, we need to declare this activity as a dialog in our manifest:
 <activity
            android:name="com.example.shakecardbeta1.AlertBoxView"
            android:label="@string/app_name" android:screenOrientation="portrait"
            android:theme="@android:style/Theme.Dialog">
            <intent-filter>
                <action android:name="android.intent.action.ALERT" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>