If you haven’t heard of the Android Support Annotations library yet, you’re missing out on a neat new package that will help you catch bugs in your apps. Included in the library is a number of Java annotations, that will help Android Studio check your code for possible errors and report them to you. There are quite a few of them, so I only plan to go over a few of them here, but you should definitely check out the docs for more info about the rest.
@NonNull / @Nullable
@NonNull and @Nullable are probably the most basic of the support annotations, but also some of the most helpful! Annotate a parameter or method with either of these to denote if the parameter or method’s return value can be null or not, and voila, now Android Studio can give us a nice warning that we’re doing something unsafe.
So recently I was trying to add a ripple to a view that had rounded corners. Simple enough right? Let’s just say I have a FrameLayout with the background similar to this one:
It’s not quite as simple as setting the foreground to ?attr/selectableItemBackground, or else you’ll see the ripple surpasses the corners (which doesn’t look so bad when your border radius is small, but this would look terrible with a circlular view):
The solution for this lies in the special mask layer of the RippleDrawable. You specify the mask layer via the android:id value set to @android:id/mask. For the example above, you can set the mask to the same size/shape as the view you’re masking, and then the ripple will only show for that area. For something like our example above, you’d use something like this:
One of these apps was Etsy, which had a very cool fading blur background effect, which you can see here:
As a learning experiment, I set off to replicate this behavior. I had seen a library by Manuel Peinado called GlassActionBar which demonstrated a similar glass-like blur effect on the ActionBar, so I decided to use that code for blurring my background.
The code itself is pretty interesting, specifically the bit for versions on Jelly Bean or higher. If you’re using API version 16 and up, you can use Renderscript Intrinsics, which are a set of built-in functions that require very little code to use, but are optimized for high-performance.
In my sample tests, using Renderscript to blur the image took on average about ~175ms, vs ~2 seconds doing the blur using Java code. (The required code is also only a tiny fraction of the length of the Renderscript one).
Renderscript is extremely easy to add to your project, just throw
in your build.gradle and you should be ready to roll.
Once you have the blurring, the rest of the process is fairly straight forward. When you plan to leave an activity, create a bitmap of the current view and write it to disk. When you start your new activity (which should have a transparent background), you override the transition (otherwise you’ll get the default zoom), and set the background to the blurred image you saved earlier. Add a fade in for the alpha and you get a nice little effect!
If you’d like to see how this looks in a sample project, you can find it on Github here.
Recently I’ve been watching a bunch of streams on Twitch, and was investigating the best options to stream from OS X. Sadly most of the ones I found were very expensive, until I saw that Open Broadcaster Software, which was previously only for Windows, was being rewritten to work with OS X and Linux. However, it’s still highly beta/under development and as a result, there’s not a lot of documentation on how to build it.
Here’s how I did it:
1234567
brew install ffmpeg glew cmake qt5
git clone https://github.com/jp9000/obs-studio.git
cd obs-studio
mkdir cmbuild && cd cmbuild
export CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.2.1/lib/cmake
cmake .. && make
cpack
This will leave you with a disk image named obs-studio-x64-<sha1-hash>.dmg, which you can mount and install, just like any other OS X application.
A few months back I wrote a blog post about my 2013 in Review. One thing I wanted to add to the post was a link to the #AutoAwesomed video, which was generated from photos and videos I took during the year, which were backed up to Google+.
Fortunately for me, Google allows you to embed posts into your pages using a technique which is documented here. The problem with this method, for me at least, is that my blog is created using Octopress, and posts are written in Markdown and then rendered to HTML. Octopress does, however, allow you to write plugins which can help us with this issue.
I haven’t updated my blog in a while, but this is a tip/trick that’s so good that I had to share. It’s not a very widely known feature, but once you try it, you’ll wonder how you lived with out it: using ADB over WiFi! That’s right, no more plugging in all your devices to your computer to debug/etc. Best of all, no root required.
It’s also ingeniusly simple. First, connect the device you want to use via a USB cable.
123
adb tcpip 5555
(Feel free to unplug it now)
adb connect <IP address of your device>
Today is December 31st, and I decided to write up a blog post, reflecting on the year that I’ve had. I’ve learned a lot over the last twelve months, and done a lot of interesting things (okay, at least interesting to me). Here’s a brief overview of what happened:
Last week I open sourced an Android library called ColorArt, which is a port of the popular OS X library written by the guys over at Panic. It allows you to use a source image to create a themed image/text display, very similar to the effect which is done in iTunes 11.
This morning Google launched a new product called Helpouts, a tool which will connect people with experts for help via a video conference. I was accepted as a Helpout provider a few weeks back, and have been using the product for a little while during the internal beta. I decided to do an Helpout to teach people to write code, which I cleverly named “Coding 101: learn the basics of writing code and building apps”.
For a new app that I’m working on, I wanted to use a ViewPager inside a ScrollView in order to make a simple image carousel. The only problem is, ScrollViews don’t seem to play nicely with horizontally swiping Views. As soon as the user moves their finger even slightly up or down, the ViewPager page change is cancelled, and the page snaps back to the current item. This can lead to an extremely frustrating user experience, because it is difficult for the user to understand why the views won’t swipe.