Skip to content

Commit

Permalink
avatar library and sample project
Browse files Browse the repository at this point in the history
  • Loading branch information
Pedroafa committed Feb 23, 2014
1 parent 7143566 commit bf6090b
Show file tree
Hide file tree
Showing 40 changed files with 1,323 additions and 1 deletion.
58 changes: 57 additions & 1 deletion README.md
@@ -1,2 +1,58 @@
avatar-android
Avatars for Android
==============

This project provides a easy way to build avatar compositions for Android applications, as you can see in the screenshot.

![Screenshot]()

## How to Use

Inside the layout, you only needs a ImageView in order to show the avatar.

``` xml
<ImageView
android:id="@+id/doubleSquaredAvatar"
android:layout_height="fill_parent"
android:layout_width="fill_parent"/>
```

The AvatarDrawableFactory will abstract you about how the avatars are built. We will be able to create a rounded or a
squared avatar from this entry point.

For the squared avatars depending of the number of images passed to the factory, a composition for one, two, three or four
will be created. Returning the specific implementation for that case.

There are this types of compositions:

* RoundedAvatarDrawable
* BorderedRoundedAvatarDrawable
* SquaredAvatarDrawable
* DoubleSquaredAvatarDrawable
* TripleSquaredAvatarDrawable
* QuadrupleSquaredAvatarDrawable

``` java
Drawable doubleSquaredAvatarDrawable = avatarDrawableFactory.getSquaredAvatarDrawable(avatar, avatar);
ImageView doubleSquaredAvatarView = (ImageView)rootView.findViewById(R.id.doubleSquaredAvatar);
doubleSquaredAvatarView.setImageDrawable(doubleSquaredAvatarDrawable);
```

## Contributors

* Evelio Tarazona Cáceres - <https://gist.github.com/eveliotc/6051367>

## License

Copyright 2014 Pedro Álvarez Fernández

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
1 change: 1 addition & 0 deletions avatars/.gitignore
@@ -0,0 +1 @@
/build
26 changes: 26 additions & 0 deletions avatars/build.gradle
@@ -0,0 +1,26 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.6.+'
}
}
apply plugin: 'android-library'

repositories {
mavenCentral()
}

android {
compileSdkVersion 19
buildToolsVersion "19.0.0"

defaultConfig {
minSdkVersion 9
targetSdkVersion 19
}
}

dependencies {
}
12 changes: 12 additions & 0 deletions avatars/src/main/AndroidManifest.xml
@@ -0,0 +1,12 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.sectorsieteg.avatars"
android:versionCode="1"
android:versionName="1.0">

<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="19" />

<application android:allowBackup="true">

</application>

</manifest>
39 changes: 39 additions & 0 deletions avatars/src/main/java/net/sectorsieteg/avatars/AvatarBorder.java
@@ -0,0 +1,39 @@
package net.sectorsieteg.avatars;

/*
* Copyright 2014 Pedro Álvarez Fernández <pedroafa@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import android.content.res.Resources;

public class AvatarBorder {

private final Resources mResources;

public AvatarBorder(Resources resources) {
mResources = resources;
}

public int getColor() {
return mResources.getColor(R.color.avatar_border);
}

public float getRoundWidth() {
return mResources.getDimension(R.dimen.avatar_round_border_size);
}

public int getSquareWidth() {
return (int)mResources.getDimension(R.dimen.avatar_square_border_size);
}
}
@@ -0,0 +1,67 @@
package net.sectorsieteg.avatars;

/*
* Copyright 2014 Pedro Álvarez Fernández <pedroafa@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;

import net.sectorsieteg.avatars.round.BorderedRoundedAvatarDrawable;
import net.sectorsieteg.avatars.round.RoundedAvatarDrawable;
import net.sectorsieteg.avatars.square.DoubleSquaredAvatarDrawable;
import net.sectorsieteg.avatars.square.QuadrupleSquaredAvatarDrawable;
import net.sectorsieteg.avatars.square.SquaredAvatarDrawable;
import net.sectorsieteg.avatars.square.utils.SquareCanvasProvider;
import net.sectorsieteg.avatars.square.TripleSquaredAvatarDrawable;
import net.sectorsieteg.avatars.square.utils.SquareUtils;


public class AvatarDrawableFactory {

private final AvatarBorder mAvatarBorder;
private final SquareCanvasProvider mSquareCanvasProvider;

public AvatarDrawableFactory(Resources resources) {
mAvatarBorder = new AvatarBorder(resources);
mSquareCanvasProvider = new SquareCanvasProvider(new SquareUtils(), mAvatarBorder);
}

public RoundedAvatarDrawable getRoundedAvatarDrawable(Bitmap bitmap) {
return new RoundedAvatarDrawable(bitmap);
}

public BorderedRoundedAvatarDrawable getBorderedRoundedAvatarDrawable(Bitmap bitmap) {
return new BorderedRoundedAvatarDrawable(mAvatarBorder, bitmap);
}

public Drawable getSquaredAvatarDrawable(Bitmap bitmap) {
return new SquaredAvatarDrawable(mSquareCanvasProvider, bitmap);
}

public Drawable getSquaredAvatarDrawable(Bitmap leftBitmap, Bitmap rightBitmap) {
return new DoubleSquaredAvatarDrawable(mSquareCanvasProvider, leftBitmap, rightBitmap);
}

public Drawable getSquaredAvatarDrawable(Bitmap leftBitmap, Bitmap rightBitmapTop, Bitmap rightBitmapBottom) {
return new TripleSquaredAvatarDrawable(mSquareCanvasProvider, leftBitmap, rightBitmapTop, rightBitmapBottom);
}

public Drawable getSquaredAvatarDrawable(Bitmap leftBitmapTop, Bitmap leftBitmapBottom, Bitmap rightBitmapTop,
Bitmap rightBitmapBottom) {
return new QuadrupleSquaredAvatarDrawable(mSquareCanvasProvider, leftBitmapTop, leftBitmapBottom, rightBitmapTop,
rightBitmapBottom);
}
}
@@ -0,0 +1,55 @@
package net.sectorsieteg.avatars.round;

/*
* Copyright 2014 Pedro Álvarez Fernández <pedroafa@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;

import net.sectorsieteg.avatars.AvatarBorder;

/**
* A Drawable that draws an oval with given {@link android.graphics.Bitmap} adding a border with a given
* color and width
*/
public class BorderedRoundedAvatarDrawable extends RoundedAvatarDrawable {

private final AvatarBorder mAvatarBorder;

public BorderedRoundedAvatarDrawable(AvatarBorder avatarBorder, Bitmap bitmap) {
super(bitmap);
mAvatarBorder = avatarBorder;
}

@Override
public void draw(Canvas canvas) {
float borderWidth = mAvatarBorder.getRoundWidth();

Paint paintBorder = new Paint();
paintBorder.setAntiAlias(true);
paintBorder.setColor(mAvatarBorder.getColor());
paintBorder.setStyle(Paint.Style.STROKE);
paintBorder.setStrokeWidth(borderWidth);

int viewWidth = getIntrinsicWidth() - ((int)borderWidth * 2);
int circleCenter = viewWidth / 2;

canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth,
circleCenter + borderWidth - 4.0f, paintBorder);
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth,
circleCenter, getPaint());
}
}
@@ -0,0 +1,115 @@
package net.sectorsieteg.avatars.round;

/*
* Copyright 2013 Evelio Tarazona Cáceres <evelio@evelio.info>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;

/**
* A Drawable that draws an oval with given {@link android.graphics.Bitmap}
*/
public class RoundedAvatarDrawable extends Drawable {
private final Bitmap mBitmap;
private final Paint mPaint;
private final RectF mRectF;
private final int mBitmapWidth;
private final int mBitmapHeight;

public RoundedAvatarDrawable(Bitmap bitmap) {
mBitmap = bitmap;
mRectF = new RectF();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
final BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint.setShader(shader);

// NOTE: we assume bitmap is properly scaled to current density
mBitmapWidth = mBitmap.getWidth();
mBitmapHeight = mBitmap.getHeight();
}

@Override
public void draw(Canvas canvas) {
canvas.drawOval(mRectF, mPaint);
}

@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);

mRectF.set(bounds);
}

@Override
public void setAlpha(int alpha) {
if (mPaint.getAlpha() != alpha) {
mPaint.setAlpha(alpha);
invalidateSelf();
}
}

@Override
public void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
}

@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}

@Override
public int getIntrinsicWidth() {
return mBitmapWidth;
}

@Override
public int getIntrinsicHeight() {
return mBitmapHeight;
}

public void setAntiAlias(boolean aa) {
mPaint.setAntiAlias(aa);
invalidateSelf();
}

@Override
public void setFilterBitmap(boolean filter) {
mPaint.setFilterBitmap(filter);
invalidateSelf();
}

@Override
public void setDither(boolean dither) {
mPaint.setDither(dither);
invalidateSelf();
}

protected Paint getPaint() {
return mPaint;
}

// TODO allow set and use target density, mutate, constant state, changing configurations, etc.
}

0 comments on commit bf6090b

Please sign in to comment.