The ViewHolder Pattern

As you develop your Android application, performance becomes more and more important. If your application appears slow, the user will get frustrated and not want to use it. One example of where this could happen is in the scrolling of a ListView. ListViews are a popular way to display information and can be done very poorly.

Each ListView has an adapter that is responsible for displaying the information in the list, and many times we’ll want to write a custom adapter to do something special. Within that adapter, the getView() method is responsible for figuring out how to display each cell in the list.  There are two main ways you’ll see developers implement this method–the right way and the wrong way.

The wrong way:

public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater mInflater = mContext.getLayoutInflater();
    View convertView = mInflater.inflate(R.layout.buddy_list_item, null);
    Buddy buddy = getItem(position);

    ((TextView) convertView.findViewById(R.id.buddy_full_name)).setText(buddy.getFullName());
    ((TextView) convertView.findViewById(R.id.buddy_username)).setText(data.getUsername());
    return convertView;
}

In this example, each time a cell needs to be created, the ListView will need to find the View and its components (see where findViewById() is called?). This means the code will scan over all the layout resources and find this View and get its components to then populate in the cell. This is very expensive, and could lead to poor performance.

The correct way:

public static class ViewHolder {
    TextView fullName;
    TextView username;
}

Now, we use a ViewHolder which will represent a cell in our ListView. The ViewHolder will be attached to the tag field of our View. This will make it much easier for the ListView to recall the correct View and components, rather than calling findViewById() many times. Let’s see how it’s used in the getView() method.

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView==null) {
        holder = new ViewHolder();
        convertView = mInflater.inflate(R.layout.list_item_buddy, null);
        holder.fullName = (TextView)convertView.findViewById(R.id.buddy_full_name);
        holder.username = (TextView)convertView.findViewById(R.id.buddy_username);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    final Buddy buddy = buddies.get(position);
    holder.fullName.setText(buddy.getFullName());
    holder.username.setText(buddy.getUsername());
    return convertView;
}

Here, we only inflate a View from scratch if convertView is null. Otherwise we have a reference to the View through the convertView’s tag, and we don’t need to call findViewById at all! This leads to great performance and smoother scrolling in our list.

Hopefully it’s clear why the ViewHolder pattern is superior. There are some great Android docs that touch on this. If you need clarity or have questions or suggestions, be sure to comment below!

Happy coding!
Brandon from The Bunch

iOS vs. Android: The Case for iOS

iphones

Last week my co-founder Brandon laid out the case for Android. While I agree that Android has some benefits like customizability, there are a few key factors that put the iPhone ahead.

Reliability & Smoothness

The iPhone is a reliable machine that runs at about the same performance throughout its lifetime. There’s a reason iPhone users rarely turn off their phone, and that’s because it performs reliably even after heavy usage. With reliability comes a consistent user experience, providing a smooth user interface. With Android, I’ve seen many phones start out zippy but degrade over time or lag periodically.

Updates

Apple has done a great service to developers and users alike by essentially forcing you to update your phone. Updates are simple on the iPhone, and users are quick to update iOS for new features. For developers, this means they don’t have to support the older versions of iOS, which increases time spent on things that matter. Android phones usually are customized on a phone-by-phone basis, meaning the version of Android they run becomes outdated and doesn’t get updated as frequently, which is bad for developers and users alike and probably only good for new phone sales.

Simplicity

iOS is very consistent and simple across apps. Apple’s design standard has made apps converge on “best” practices (sometimes they might not be the best, but they’re common). An example of this is swiping on an item in a list. The home screen on iOS is quite simple, where each app gets its own space. The counter-point for Android is customizability, but that comes at the expense of simplicity. Personally, I like an environment to be plug and play, where I can start using something and be productive in a matter of minutes and continue to be productive over time. iOS does this well.

Other Benefits

  • Quality of apps (largely due to Apple screening every app in the App Store)
  • Integration with Mac. If you use a MacBook, you’ll agree that some of the desktop apps don’t feel complete unless they’re used with the phone (i.e. Messages, Notes, etc.).
  • The lure of Android is always there to explore something unfamiliar, but I’m a “no-nonsense” user, so you can leave me here…I’ll be ok.

What are you favorite or least-favorite parts about owning an iPhone or an Android? Let us know in the comments below!

Sincerely,
Matt from the Bunch

iOS vs. Android: The Case for Android

android

Which is better: the iPhone or Android? Well, if we say iPhone vs. Android it’s actually as if we’re comparing apples and oranges. iPhone is the name of the device made by Apple. Android is an operating system (OS) made by Google. For the purposes of this blog post, let’s discuss iOS and Android, because there are too many devices that run Android to compare devices, and people usually argue about the OS, not the device it’s running on.

Both operating systems are pretty niche, in my opinion. I believe that’s why this argument can get so heated sometimes. iOS users are typically (in my experience) no-nonsense people who want a quality device that won’t slow them down in any way. This can range from cool hipsters who are more occupied with their other hobbies to worry about a cell phone to older people (like my grandparents) who just want a reliable device to handle the occasional call. Android users tend to be more into tinkering (with a few exceptions here and there). There’s the possibility of rooting the device (gaining root access to the device to bypass certain rules the OS has baked in), and there are undoubtedly more customizations to be made on the Android platform.

So, which is better? I’ve personally owned both. I’ve owned numerous Android devices but temporarily switched to an iPhone 5 for a few years. While there are great things about each, I would like to argue that the Android operating system is superior to iOS. But after you’ve heard my reasoning, you should comment below to let me know what you think!

iOS has a beautiful interface. I will never tell anybody differently. iOS is reliable and quick, all the time. There’s a reason no-nonsense users tend to find themselves on iPhones. iOS is simple. It’s clean. It’s very sexy. There’s no doubt about that. However, for me, this is where it ends. Its simplicity and beauty only go so far for me. I need more.

The Android platform can almost compete with iOS in terms of being clean and beautiful. I’ll admit that it’s not as fast and responsive and can get bogged down under heavy usage. However, this is rare and doesn’t at all ruin the system for me. Where it wins, though, is its customizability. I’m not talking about the ability to root and flash different system images on the devices. And I’m just talking about sheer customization and user experience. When you use an Android, you get the feeling that the phone was made for you. Google Now will tell you where you parked your car, what you wanted to buy at the store (via Wunderlist integration), what your schedule looks like today, how your stocks are doing, how your team did last night, and display articles of interest (that are actually relevant), all on the same screen! Oh, and saying ‘OK Google’ and searching the web actually returns super accurate results, unlike Siri. The great thing about Android is that if you don’t want to customize it or use all of its features, that’s totally fine. The phone still will deliver the same value that an iPhone does.

Also, you can get a phone running the latest Android version for a few hundred bucks, while iPhones cost an arm and a leg.

But this is just my opinion; what do I know? Let me know what you think–and why–by commenting below!

Sincerely,
Brandon from the Bunch

TinyPNG

panda
TinyPNG was used to compress this image and subsequently decrease this page’s load time.

TinyPNG is easily the coolest tool I’ve come across recently. I was looking for an easy way to compress images used on LunchBunch’s website to improve load times, and TinyPNG couldn’t have made it any easier. I’ve compressed PNGs and JPGs (it works with both) with average compression results between 40% and 80% depending on the source and original size. The website is very easy to use too–just upload your images and download a zipped file containing the compressed versions (or optionally save directly to Dropbox). And it works just as well on PNGs with transparency.

Compression is awesome, but what about the quality? PNGs are lossless, meaning that an image won’t change when compressed, but the quality of JPGs deteriorates as the file size shrinks. You don’t have to worry about image quality with TinyJPG–see for yourself at the bottom of TinyJPG’s homepage. The compressed version is barely a quarter of the size of the original, but I can’t tell the difference between the two images!

So after learning all of this, I was hooked. I was excited to use TinyPNG for everything, but what if I want to tinify my images programmatically? Lo and behold, the developer API! With libraries for Ruby, PHP, Node.js, Python, and Java, it is very easy to incorporate TinyPNG into any project. For example, my first attempt in Python was just a few lines:

import tinify
tinify.key = "<your-developer-api-key>"

def tiny(input_filepath, output_filepath):
    source = tinify.from_file(input_filepath)
    source.to_file(output_filepath)

And it just worked!

It seems easy to preserve metadata, integrate with Amazon S3, and even crop/resize before compressing (though I haven’t explored these features yet).

Every once in a while you stumble across a tool that’s exactly what you were looking for. For me, TinyPNG was that and more. If you have a website or use pictures in any way, this is a must-have tool for your project. There’s also a WordPress plugin that is super simple and highly-recommended for your blog.

How do you use TinyPNG in your projects? Let us know in the comments below!

Happy coding!
Ryan from The Bunch

Happy First Birthday!

birthday_cake
One candle for one year; the 44 is for April 4th 😉

The Bunch turns one year old today! 366 days ago, Matt, Brandon, and I had our first video conference to discuss the idea of developing LunchBunch into a fully-realized mobile application. In November of 2015, we launched LunchBunch publicly, and over the past few months, we’ve been updating it and adding new features. It’s time to start growing, so be sure to tell all of your friends about LunchBunch!

I’ve had a ton of fun working on LunchBunch over the past year, and I’d like to thank Brandon and Matt for all of the work they’ve put into making LunchBunch awesome. Seeing the app progress over the past 12 months has been amazing, and their diligence is why LunchBunch has come as far as it has. I couldn’t be prouder of my team and all of the time they’ve devoted to this project.

I especially want to thank you, our blog readers, app users, and general supporters of LunchBunch! This project wouldn’t be possible without you, and we really do appreciate all of the feedback and encouragement you’ve provided along the way. Thanks for cheering us on this past year! With so many exciting changes in the pipeline, I can’t wait to see where LunchBunch ends up on its second birthday!

Sincerely,
Ryan from The Bunch