Tuesday, January 22, 2013

Android Animated Notification Bar

I have been developing Android apps for some time now and was never happy with the in-built notifications.

Following are some notification mechanisms I have used in past:
  • Toast messages
  • A notification strip with distinct background color and some notification text on it
With apps adding more and more animation with every passing day, both these mechanisms lag behind terribly.

I wanted something which is dynamic, fun to look at, fun to use and something which enhances app's branding value.

In following details, you will see how I was able to achieve notification bar shown in picture below:


I started with a MapActivity and +Jake Wharton's SherlockActionBar for my app. Added a small rounded rectangle as described in following drawable code and added it to my main activity:

<item>
    <shape android:shape="rectangle">
        <corners android:bottomRightRadius="25dp" android:topRightRadius="25dp" />
        <solid android:color="#FFFFFF"/>
    </shape>
</item>

Here's the result:


To add branding to this notification bar, I added gradient to this notification bar with color same as my app's icon.

Code is changed to:

<item>
    <shape android:shape="rectangle">
        <corners android:bottomRightRadius="25dp" android:topRightRadius="25dp" />
        <gradient 
             android:startColor="@color/notificationStartColor" 
             android:endColor="@color/notificationEndColor"
             android:angle="270"
        />
    </shape>
</item>

This is how it looks by just adding colors to the gradient:




While this looks much better now, I was still not satisfied with how two dimensional it was looking. I wanted to make it look more three dimensional and then wanted to animate it to give the effect as if a notification board is displayed to the user.

To achieve this desired 3D effect, I added a layer below existing layer with some offset. This new layer was drawn with the universally accepted shadow color (#40000000). Resultant code is:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <shape android:shape="rectangle"> 
            <solid android:color="#40000000"/>
            <corners android:bottomRightRadius="25dp" android:topRightRadius="25dp" />
            <padding android:right="2dp" android:bottom="2dp"/>
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <corners android:bottomRightRadius="25dp" android:topRightRadius="25dp" />
                <gradient 
                     android:startColor="@color/notificationStartColor" 
                     android:endColor="@color/notificationEndColor"
                     android:angle="270"
                />
        </shape>
    </item>
</layer-list>

And resultant final image is:


To be able to add text to this notification bar dynamically, I used above layer-list as a background of a TextView and animated the TextView every time I showed it to the user.

You can see this notification bar in action in my two apps so far: Distance Calculator Free and it is coming up shortly in Distance Calculator as well.

Feedback on this blog is welcome and feel free to contact me through Google+ in case of any questions. Thanks for reading!


Tuesday, December 15, 2009

Little More Smartness

ICICI Direct and ICICI Bank are one of the best portals I have seen so far. They are fast, has almost every function you will ever need while trading or banking and has awesome customer care as well. Also, the site is seldom down.

May be that is the reason they do not have much experience when it comes to error messages. Have a look at this screenshot


Look at the timing in area which I have tried to highlight.

The problem here is, they had hard-coded the time when site was expected to be up and running and unfortunately they could bring it up. The time when site was expected to be up and running again had already past the current time.

While not being able to bring the site back up and running in expected time is not uncommon, hard-coding time in error message is!

May be it was important for ICICI Direct to mention the time to keep their clients informed. But still hard coding is not justified.
Worst case, if they HAD TO, they could have done something like this:

if($time < $currentTime) {
print "The site will be back soon";
} else {
print "The site will be back by " . $time;
}

So I strongly recommend to always ensure that if you had to hard-code anything in your view, it doesn't contradict with anything else. It really doesn't look good and user's trust is lost on robustness of your website. Specially when your website is a banking website or trading website. :)

Wednesday, July 29, 2009

Kaizen

Till date most of my blogs talked about corrective measures to be taken AFTER mistakes were committed. Now as I grew in my career, I have started (or made to) worrying about how to avoid mistakes.

While working in Amazon, I have learned a very good concept called KAIZEN. Kaizen is a Japanese concept which talks about continuous improvement. Do not worry a lot about major changes, rearchitecturing the whole system or reorganizing your team. Think about small improvements you can make in your day-to-day life. Can you be 0.001% more efficient by keeping your coffee mug on your right side than your left side? Can you be little faster by aligning your chair, keyboard and monitor correctly?

Kaizen is called "Kaizen" and not bug fix/project/enhancement if the change you have brought has following properties:
  1. is completed in not more than 5 working days
  2. has a direct dollar impact i.e. you can actually derive number of dollars your kaizen will have
  3. it is not a workaround but an actual root cause elimination (this applies only when you are solving any problem)
Kaizens are easy to identify. Anything you do to avoid MUDA (waste) can be called as Kaizen. In Amazon, we are always asked to identify and eliminate wastes. I have seen miraculous results coming out of various kaizens implemented in Amazon.

Following are few examples of kaizens which can be directly related to you:
  1. unnecessary compiling of unchanged classes
  2. long queues at coffee machine taking lot of your time
  3. network delays while working remotely
  4. number of times you type backspace.. instead try typing slow
  5. number of obvious bugs you fix.. can you write unit tests? if written, can you automatically run them at every check-in?
  6. amount of time you spend on documentation you are never going to see as soon as project is started.. work on only relevant documents
Try this and let me know whether or not you see any improvement in your efficiency. Let me know if there are more kaizens you can think of.

Saturday, April 21, 2007

Be prepared for Oracle-Prepared Statements

I am a starter with Oracle databases and hence this article might be very obvious to people who are working with databases since 4-6 months or more. When I faced this problem, I googled a lot but could not find much about it and hence decided to put this up in blog.

It all started when I had to delete few rows from my database table. Table had two columns:
name -> varchar(20);
id -> char(5);

I was testing my program of deleting rows and hence, before deleting rows, I was inserting few in table.
I inserted following three rows
a 1
b 2
c 3
and started deleting rows with following code:

DEL_SQL = "delete from table_name where id = ?"
PreparedStatement del = conn.prepareStatement(DEL_SQL);
for(int i=0; i<3;>
del.setString(1, Integer.toString(i));
int updated = del.executeQuery();
System.out.println("Number of rows affected: " + updated);
}

I ran this program and surprisingly, value of "updated" was always 0. Went everywhere to look for mistake I have made.. from Connection to PreparedStatement, from Integer to String.. but could not find any mistake there.
After I toiled for one day, next day I just thought of looking for the difference between varchar(n) and char(n) and came to know that "char(n) is a fixed length string of n characters. So if you put a string of length n-m, this string will be padded by m space/blank characters".

It means that when I inserted values "1", "2", and "3" in "id" column, it was padded by extra spaces. :(
i.e. value in database table of id was "1 ", "2 " and "3 " and hence when I was trying to delete such rows, result of equality I was looking for was false.

"trunc()" function, provided by Oracle came to my rescue and I modified by DEL_SQL to:
"delete from table_name where trunc(id) = ?"
and it started working fine.

Unfortunately, this problem doesn't occur when you use such queries from command line (SQLPlus).
My suggestion is to take special care while querying columns of fixed length datatype like "char(n)".

Please let me know if my conclusion is wrong or if there is some better way of handling this scenario.

Thanks for taking time to read this.

Wednesday, August 16, 2006

Resin AIX nightmare

Hi all,
After developing a medium sized web application, I wanted to enable https:// for my aplication.
How difficult that could be? I started with Windows and making few configuration changes in resin.conf (yes, I am using Resin for my application) things started working.

Happily, I used the same war file and deployed it on AIX with Resin 3.0.19 installed on it. Made similar changes that I made on Windows' resin.conf and restarted Resin.
(If you are using 3.0.19, you might want to know why we add <jsp jstl="false"> in resin.conf)
Things didn't work as smoothly as expected. :(
I got following error on console when I restarted Resin:
"[org.apache.commons.digester.Digester] - Begin event threw exception"
It was also making ActionServlet Unavailable by giving following message
SEVERE: Unable to initialize Struts ActionServlet due to an unexpected exception or error thrown, so marking the servlet as unavailable. Most likely, this is due to an incorrect or missing library dependency.

I was totally clueless about all this. I had no idea why this was happenening.
For some reason, Resin was not able to get depedent classes/jars for ActionServlet.
After wandering on net for few hours, I went to home at 7:00 in morning.
Collegue of mine worked on that and found that RESIN ON AIX CANN'T READ COMPRESSED JAR FILES. :O :O :O

This was like a shock to me. How this could be a possibility?
Who would guess this? I don't think it is documented at all.
We used uncompressed jar files for this and everything is working as expected.
We concluded that, this is the only reason why it was not working before.

If someone has some different experience or doesn't agree that this could be the reason for errors, please let us know.
Till then, others, please keep it in mind
RESIN ON AIX DOESN'T WORK WITH COMPRESSED JAR FILES.

Thanks.

Wednesday, July 19, 2006

Calendar bug in Java

Hi all,
While extending a FileAppender class in Log4j, for some reason, I just did not want to use timestamp [%d] given by Log4j while logging the messages.

In my appender, I declared one Calendar instance which was an instance variable for the appender class. I used "Calender.getTime()" method to get current time for the logging message.

Compiled code, put the war file in container, started the application.
Things went fine and log messages were getting written to the file properly. Only problem I faced was about "DATE" in my log messages.
All the messages were showing same timestamp as a log time. :O

Went to appender and saw my code where I was putting CurrentTimestamp in the message before writing it to the file.
Went to check the documentation for Calendar.getTime() and documentation says the right thing as well.
Gets this Calendar's current time.
I was lost.. what could be the problem??

Was looking for some help/hint/thread but nothing was found.
Finally, somebody told me about the bug with Id #4479408. Sun claims that they have fixed this bug, but it doesn't look like that.
You can have a look at it by accessing following link.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4479408

So, for now, I am making a new instance of Calendar everytime I want to have get a Current Timestamp.
I am not very sure about this approach, how efficient is that, but we all know: "Deadline is sole responsible for bad software quality" and hence I had to put it in my code.

I hope this time Sun not only claim that they have fixed this bug, but really look into the issue and test the fix. :)

Thanks.

Wednesday, June 21, 2006

Eclipse - new discovery

Hi,
After a long time I am updating my blog.
Something really new to me, encouraged me to do so.

ECLIPSE - we all use it for developing Java applications.
We all use Build, Build All, Clean while developing applications.

Well.. did you know that we can change the default behaviour of Build and Clean?
i.e. when I say clean, I can ask Eclipse to use my ANT target instead of its default behaviour? (deleting generated class files)
Same is the case with Build.

This is achieved by something called "Builder" in Eclipse.
I know it was always there infront of my eyes, but I never noticed it.
I never bothered to go into it to see what it is all about.

I hope that this blog help other ignorant users like me to explore more into Eclipse.. or atleast into Builders. :)
Have a look at it, its really amazing.

Thanks,
Viraj K. Turakhia