Libraries that

should be known

for every Android dev

by Valeriy Palamarchuk

 

  • Network

  • View

  • Database

  • Workflow

Network

1. Picasso

A powerful image downloading and 

caching library for Android

  • Handling ImageView recycling and cancelation (adapter)

  • Transformations (minimal memory use)

  • Automatic memory and disk caching

Picasso.with(context)
  .load(url)
  .resize(50, 50)
  .centerCrop()
  .placeholder(R.drawable.p)          
  .error(R.drawable.error)
  .into(imageView)
Picasso
.with(context)
.load(new File(...))
.into(imageView2);

DEBUG INDICATORS

2. Retrofit

A type-safe REST client 

for Android and Java

  • URL parameter replacement and request parameter support

  • Object conversion to request body

  • Multipart request body and file upload

public interface GitHubService {
  @GET("/users/{user}/repos")
  List<Repo> listRepos(@Path("user") String user);
}

Retrofit turns your REST API

into a Java interface.

RestAdapter restAdapter = new RestAdapter.Builder()
    .setEndpoint("https://api.github.com")
    .build();

GitHubService service = restAdapter.create(GitHubService.class);

Implementation of the GitHubService interface

List<Repo> repos = service.listRepos("octocat");

HTTP request

to the remote webserver

@GET("/group/{id}/users")
List<User> groupList(
   @Path("id") int groupId, 
   @Query("sort") String sort);
@GET("/user")
void getUser(
   @Header("Authorization") String authorization, 
   Callback<User> callback)

3. Volley

HTTP library

that makes networking

easier and  faster

  • Automatic scheduling of network requests

  • Multiple concurrent network connections

  • Disk and memory response caching

  • Prioritization

  • ​Cancellation

String url = "http://i.imgur.com/7spzG.png";
ImageRequest request = new ImageRequest(url,
    new Response.Listener() {
        @Override
        public void onResponse(Bitmap bitmap) {
            mImageView.setImageBitmap(bitmap);
        }
    }, 0, 0, null,
    new Response.ErrorListener() {
        public void onErrorResponse(VolleyError error) {
            mImageView.setImageResource(R.drawable.image_load_error);
        }
    });
MySingleton.getInstance(this).addToRequestQueue(request);

Simple request

4. OkHTTP

An HTTP and SPDY client

for Android and Java applications

  • Response caching 

  • Connection pooling reduces request latency

  • SPDY support 

OkHttpClient client = new OkHttpClient();

String run(String url) throws IOException {
  Request request = new Request.Builder()
      .url(url)
      .build();

  Response response = client.newCall(request).execute();
  return response.body().string();
}

Downloads a URL and print its contents

public static final MediaType JSON
    = MediaType.parse("application/json; charset=utf-8");

OkHttpClient client = new OkHttpClient();

String post(String url, String json) throws IOException {
  RequestBody body = RequestBody.create(JSON, json);
  Request request = new Request.Builder()
      .url(url)
      .post(body)
      .build();
  Response response = client.newCall(request).execute();
  return response.body().string();
}

Posting data to a service

View

1. Nine old androids

Android library for using

the Android 3.0 animation API 

  • All versions of the platform back to 1.0

  • Includes support for animating rotation, translation, alpha, and scale

ObjectAnimator
.ofFloat(myObject, "translationY", -myObject.getHeight())
.start();

Animate a View vertically off

ValueAnimator colorAnim = ObjectAnimator.ofInt(this, "backgroundColor", /*Red*/ 0xFFFF8080, /*Blue*/ 0xFF8080FF);

colorAnim.setDuration(3000);
colorAnim.setEvaluator(new ArgbEvaluator());
colorAnim.setRepeatCount(ValueAnimator.INFINITE);
colorAnim.setRepeatMode(ValueAnimator.REVERSE);
colorAnim.start();

Go from red to blue and then back again forever

Button myButton = (Button)findViewById(R.id.myButton);

animate(myButton)
.setDuration(2000)
.rotationYBy(720)
.x(100)
.y(100);

Animating views in a much more declarative manner

2. ViewPagerIndicator

Paging indicator widgets that used to improve discoverability of content

<com.viewpagerindicator.TitlePageIndicator
    android:id="@+id/titles"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent" />

Include one of the widgets in your view

ViewPager pager = (ViewPager)findViewById(R.id.pager);
pager.setAdapter(new TestAdapter(getSupportFragmentManager()));

TitlePageIndicator titleIndicator = (TitlePageIndicator)findViewById(R.id.titles);
titleIndicator.setViewPager(pager);

Bind the indicator to theViewPager

3. Jjoe64 GraphView

Chart and Graph Library

for Android

  • Programmatically create flexible and nice-looking diagramms

  • ​​Scrollable, Scaleable

  • Multiple series

  • Chart legend

  • Realtime/Live Graph

GraphViewSeries exampleSeries = new GraphViewSeries(new GraphViewData[] {

    new GraphViewData(1, 2.0d)

    , new GraphViewData(2, 1.5d)

    , new GraphViewData(3, 2.5d)

    , new GraphViewData(4, 1.0d)

});

GraphView graphView = new LineGraphView(context, "GraphViewDemo");

graphView.addSeries(exampleSeries); 

 

layout.addView(graphView);

See how easy create a simple graph

4. ActionBarSherlock

Extension to use

action bar design pattern

  • Works on API 2.x and up

  • Easy customization

  • Supports sliding menu

<style name="Theme.Styled" parent="Theme.Sherlock.Light.DarkActionBar">
    <item name="actionBarStyle">@style/Widget.Styled.ActionBar</item>
    <item name="android:actionBarStyle">@style/Widget.Styled.ActionBar</item>
</style>

 

<style name="Widget.Styled.ActionBar" parent="Widget.Sherlock.Light.ActionBar.Solid.Inverse">
    <item name="background">@drawable/bg_striped</item>
    <item name="android:background">@drawable/bg_striped</item>

    <item name="backgroundSplit">@drawable/bg_striped_split</item>
    <item name="android:backgroundSplit">@drawable/bg_striped_split</item>
</style>

Theming

5. Slidingmenu

Allows developers to easily create applications with sliding menus

  • Foursquare

  • LinkedIn

  • Zappos

  • Rdio

  • Evernote Food

  • Plume

  • VLC for Android

  • MW3 Barracks

SlidingMenu is currently used in:

  • ESPN ScoreCenter

  • MLS MatchDay

  • 9GAG

  • Wunderlist 2

  • The Verge

  • MTG Familiar

  • Mantano Reader

  • Falcon Pro (BETA)

  • Compatible with ActionBarSherlock

  • Easy and fast implementation

  • Simple customization

public class SlidingExample extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        ...
        setContentView(R.layout.content);
        SlidingMenu menu = new SlidingMenu(this);
        menu.setMode(SlidingMenu.LEFT);
        ...
        menu.setShadowWidthRes(R.dimen.shadow_width);
        menu.setShadowDrawable(R.drawable.shadow);
        menu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT);
        menu.setMenu(R.layout.menu);
    }

}

Simple Example

<com.jeremyfeinstein.slidingmenu.lib.SlidingMenu
    xmlns:sliding="http://schemas.android.com/apk/res-auto"
    android:id="@+id/slidingmenulayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    sliding:viewAbove="@layout/YOUR_ABOVE_VIEW"
    sliding:viewBehind="@layout/YOUR_BEHIND_BEHIND"
    sliding:touchModeAbove="margin|fullscreen"
    sliding:behindOffset="@dimen/YOUR_OFFSET"
    sliding:behindWidth="@dimen/YOUR_WIDTH"
    sliding:behindScrollScale="@dimen/YOUR_SCALE"
    sliding:shadowDrawable="@drawable/YOUR_SHADOW"
    sliding:shadowWidth="@dimen/YOUR_SHADOW_WIDTH"
    sliding:fadeEnabled="true|false"
    sliding:fadeDegree="float"
    sliding:selectorEnabled="true|false"
    sliding:selectorDrawable="@drawable/YOUR_SELECTOR"/>

XML Usage

6. AndroidStaggeredGrid

Android staggered grid view which supports multiple columns with rows of varying sizes

  • Configurable column count (portrait and landscape)

  • Sync'd row position across orientation changes

  • Support for headers & footers

<com.etsy.android.grid.StaggeredGridView
xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/grid_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:item_margin="8dp"
        app:column_count="@integer/column_count" />

Usage

  • item_margin
  • column_count
  • column_count_portrait
  • column_count_landscape 
  • grid_paddingLeft
  • grid_paddingRight
  • grid_paddingTop
  • grid_paddingBottom

Configure attributes

ListAdapter adapter = ...;

StaggeredGridView gridView = (StaggeredGridView) findViewById(R.id.grid_view);

gridView.setAdapter(adapter);

Setup an adapter just like you would with a GridView/ListView

The StaggeredGridView does not support the following:

  • Item selector drawables

  • Item long press event

  • Scroll bars

  • Row dividers

  • Edge effect

  • Fading edge

  • Overscroll

Row dividers

Edge effect

Fading edge

Overscroll

7. Clusterkraf

A clustering library

for the Google Maps Android API v2.

  • Clustering based on pixel proximity

  • Animated cluster transitions

  • Supports Android v2.2 (Froyo) and up 

YourMapPointModel[] yourMapPointModels = new YourMapPointModel[] { new YourMapPointModel(new LatLng(0d, 1d) /* etc */ ) };
    
ArrayList<InputPoint> inputPoints = new ArrayList<InputPoint>(yourMapPointModels.length);

private void buildInputPoints() {
   for (YourMapPointModel model : this.yourMapPointModels) {
        this.inputPoints.add(new InputPoint(model.latLng, model));
   }
}

Initialize Clusterkraf

 Clusterkraf clusterkraf;

private void initClusterkraf() {
   if (this.map != null 
   && this.inputPoints != null 
   && this.inputPoints.size() > 0) {
      com.twotoasters.clusterkraf.Options options = new         
      com.twotoasters.clusterkraf.Options();

      // customize the options
      this.clusterkraf = new Clusterkraf(this.map, 
      this.options, 
      this.inputPoints);
   }
}

8. JazzyListView

Extension of ListView designed to animate list item views

  • There are a number of pre-built, bundled effects

  • Possible to use a custom effect 

  • Easy implementation process

private JazzyListView mList;

 

@Override

protected void onCreate(Bundle savedInstanceState) {

    mList = (JazzyListView) findViewById(android.R.id.list);

    mList.setAdapter(new ListAdapter(this, R.layout.item));

    setupJazziness(mCurrentTransitionEffect);

}

Sample

Database

GreenDAO

Open source project

to help Android developers working

with data stored in SQLite

  • Maximum performance (probably the fastest ORM for Android)

  • Easy to use APIs

  • Highly optimized for Android

  • Minimal memory consumption

  • Small library size

Performance

helper = new DaoMaster.DevOpenHelper(this"notes-db"null);
db = helper.getWritableDatabase();

You do not have to code “CREATE TABLE” SQL scripts

greenDAO does that for you

daoMaster = new DaoMaster(db);
daoSession = daoMaster.newSession();
noteDao = daoSession.getNoteDao();

 

Note note = new Note(null, noteText, comment, new Date());
noteDao.insert(note);

 

noteDao.deleteByKey(id);

Inserting and deleting

Workflow

1. Butter Knife

View "injection" library

for Android

protected TextView mWelcomeLabel;
protected EditText mUsernameField;
protected EditText mPasswordField;
protected Button mSubmitButton;

 


mWelcomeLabel = (TextView) findViewById(R.id.welcomeLabel);
mUsernameField = (EditText) findViewById(R.id.usernameField);
mPasswordField = (EditText) findViewById(R.id.passwordField);
mSubmitButton = (Button) findViewById(R.id.submitButton);

Introduction

@InjectView(R.id.welcomeLabel) TextView mWelcomeLabel;
@InjectView(R.id.usernameField) EditText mUsernameField;
@InjectView(R.id.passwordField) EditText mPasswordField;
@InjectView(R.id.submitButton) Button mSubmitButton;

 

​ButterKnife.inject(this);

or

public class FancyFragment extends Fragment {
  @InjectView(R.id.button1) Button button1;
  @InjectView(R.id.button2) Button button2;

  @Override View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.ff, container, false);
    ButterKnife.inject(this, view);
    // TODO Use "injected" views...
    return view;
  }
}

NON-ACTIVITY INJECTION

@InjectViews({ R.id.one_name, R.id.middle_name, R.id.last_name })
List<EditText> nameViews;

VIEW LISTS

@OnClick(R.id.submit)
public void sayHi(Button button) {
  button.setText("Hello!");
}

LISTENER INJECTION

@OnItemSelected(R.id.list_view)
void onItemSelected(int position) {
}

MULTI-METHOD LISTENERS

2. Gson

Gson can convert Java Objects

into their JSON representation

  • Provide simple toJson() and fromJson() methods

  • Extensive support of Java Generics

  • Allow custom representations for objects

class BagOfPrimitives {
  private int value1 = 1;
  private String value2 = "abc";
}

BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String json = gson.toJson(obj);

Serialization

json -> {"value1":1,"value2":"abc"}
MyObject obj = gson.fromJson(json, MyObject.class);   

Deserialization

json -> {"value1":1,"value2":"abc"}
class MyObject {
  private int value1 = 1;
  private String value2 = "abc";
}

3. Otto

An enhanced event bus 

with emphasis on Android support

Bus bus = new Bus();
bus.post(new AnswerAvailableEvent(42));

PUBLISHING

@Subscribe public void answerAvailable(AnswerAvailableEvent event) {
    // TODO: React to the event somehow!
}

SUBSCRIBING

// Both of these are functionally equivalent.
Bus bus1 = new Bus();
Bus bus2 = new Bus(ThreadEnforcer.MAIN);

THREADING

4. Android-scripting

Brings scripting languages

to Android

  • Python (CPython)

  • Perl

  • Ruby (JRuby)

  • Lua

  • BeanShell

  • JavaScript (Rhino)

Languages

5. Android-validator

Form Validator Library

for Android

  • Based on Zend_Validator coded in PHP

  • Simplify the code to validate a form

  • Can just handle the EditText

Validate emailField = new Validate(email);

 

emailField.addValidator(new NotEmptyValidator(mContext));
emailField.addValidator(new EmailValidator(mContext));

. . .

Form mForm = new Form();
mForm.addValidates(emailField);
mForm.addValidates(confirmFields);
mForm.addValidates(urlField);

 

if(mForm.validate()) -> true\false

Use

6. LruCache

A cache that uses a bounded

amount of space on a filesystem

mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
        @Override
        protected int sizeOf(String key, Bitmap bitmap) {
            return bitmap.getByteCount() / 1024;
        }
    };

Use

public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
    if (getBitmapFromMemCache(key) == null) {
        mMemoryCache.put(key, bitmap);
    }
}
public Bitmap getBitmapFromMemCache(String key) {
    return mMemoryCache.get(key);
}

7. Rajawali

Rajawali is a 3D engine for

Android based on OpenGL ES 2.0/3.0

Augmented Reality

mLight = new DirectionalLight(1f, 0.2f, -1.0f);
mLight.setColor(1.0f, 1.0f, 1.0f);
mLight.setPower(2);

Light

DiffuseMaterial material = new DiffuseMaterial();
material.addTexture(new TextureInfo(R.drawable.earth));
mSphere = new Sphere(1, 24, 24);
mSphere.setMaterial(material);
mSphere.addLight(mLight);

Material

mCamera.setZ(4.2f);

Position of the camera

mRenderer = new RajawaliTutorial1Renderer(this);
mRenderer.setSurfaceView(mSurfaceView);

Render

8. ZXing

Open-source, multi-format

1D/2D barcode image processing library

Intent intent = new Intent("com.google.zxing.client.android.SCAN");

intent.putExtra("SCAN_MODE", "QR_CODE_MODE");

startActivityForResult(intent, 0);

Use

public void onActivityResult(int requestCode, int resultCode, Intent intent) {

           if (resultCode == RESULT_OK) {

                 String contents = intent.getStringExtra("SCAN_RESULT");

                 String format = intent.getStringExtra("SCAN_RESULT_FORMAT");

           }

}

9. Android Query

Doing asynchronous tasks and manipulating UI elements in Android

  • Light-weight library

  • Make Android coding simpler, easier

  • Asynchronous

public void renderContent(Content content, View view) {
ImageView tbView = (ImageView) view.findViewById(R.id.icon);
if(tbView != null){
   tbView.setImageBitmap(R.drawable.icon);
   tbView.setVisibility(View.VISIBLE);
   tbView.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
            someMethod(v);
      }
   });
}

TextView nameView = (TextView) view.findViewById(R.id.name);    
   if(nameView != null){
      nameView.setText(content.getPname());
   }

Before AQuery

public void renderContent(Content content, View view) {
AQuery aq = new AQuery(view);

aq.id(R.id.icon).image(R.drawable.icon).visible().clicked(this, "someMethod"); 
 
aq.id(R.id.name).text(content.getPname());   
}

With AQuery

aq.id(R.id.image1).image("http://www.vikicom/z/images/1.png");

Image Loading

String name = "My name in black text, red background, visible, and invoke nameClicked when clicked";
aq.id(R.id.name).text(name).background(R.color.red)
.textColor(R.color.black).enabled(true).visible()
.clicked(this, "nameClicked");

Chaining

Libraries that should be known for every Android dev

By Valeriy Palamarchuk

Libraries that should be known for every Android dev

  • 2,449