diff --git a/app/src/main/java/com/melnykov/letterimageview/LetterImageView.java b/app/src/main/java/com/melnykov/letterimageview/LetterImageView.java index 819ad63..2e19e3c 100644 --- a/app/src/main/java/com/melnykov/letterimageview/LetterImageView.java +++ b/app/src/main/java/com/melnykov/letterimageview/LetterImageView.java @@ -1,61 +1,143 @@ package com.melnykov.letterimageview; import android.content.Context; +import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.widget.ImageView; -import com.melnykov.initialsimageview.R; import java.util.Random; +@SuppressWarnings({"UnusedDeclaration", "NullableProblems"}) public class LetterImageView extends ImageView { + public static final int SHAPE_RECTANGLE = 0; + public static final int SHAPE_OVAL = 1; + + private static String[] colorsArray; + private static int defaultShape; + private char mLetter; private Paint mTextPaint; private Paint mBackgroundPaint; private int mTextColor = Color.WHITE; - private boolean isOval; + private int shape; + private Rect textBounds; + private float textPadding = -1; + private int shapeColor = -1; + + /** + * Initialize default parameters. + * @param context not null context + * @param colorsArrayRes resource ID of string-array with colors + * @param defaultShape default shape + */ + public static void init(final Context context, int colorsArrayRes, int defaultShape) throws Resources.NotFoundException { + LetterImageView.defaultShape = defaultShape; + LetterImageView.colorsArray = context.getResources().getStringArray(colorsArrayRes); + } public LetterImageView(Context context, AttributeSet attrs) { super(context, attrs); init(); } + /** + * Init default values + */ private void init() { mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mTextPaint.setColor(mTextColor); mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mBackgroundPaint.setStyle(Paint.Style.FILL); - mBackgroundPaint.setColor(randomColor()); + mBackgroundPaint.setColor(shapeColor = randomColor()); + textBounds = new Rect(); + // Set a default padding to 8dp + textPadding = 8 * getResources().getDisplayMetrics().density; + shape = defaultShape; } + /** + * Get letter + * @return letter + */ public char getLetter() { return mLetter; } + /** + * Set letter + * @param letter letter + */ public void setLetter(char letter) { mLetter = letter; invalidate(); } + /** + * Get text color + * @return text color + */ public int getTextColor() { return mTextColor; } + /** + * Set text color + * @param textColor text color + */ public void setTextColor(int textColor) { mTextColor = textColor; invalidate(); } + /** + * Set shape of image view.
+ * Deprecated. Use {@link com.melnykov.letterimageview.LetterImageView#setShape(int) setShape} instead. + */ + @Deprecated public void setOval(boolean oval) { - isOval = oval; + if (oval) + shape = SHAPE_OVAL; + else + shape = SHAPE_RECTANGLE; } + /** + * Get shape of image view + * @return true if shape is oval + * @see com.melnykov.letterimageview.LetterImageView#setShape(int) + * @see com.melnykov.letterimageview.LetterImageView#getShape() + */ + @Deprecated public boolean isOval() { - return isOval; + return shape == SHAPE_OVAL; + } + + /** + * Set shape of image view + * @param shape shape constant + */ + public void setShape(int shape) { + if ( + shape != SHAPE_RECTANGLE && // is rectangle + shape != SHAPE_OVAL && // is oval + !isCustomShape(shape) // is custom shape + ) + // no, throw an error + throw new IllegalArgumentException("Shape value should be taken from constants"); + this.shape = shape; + } + + /** + * Get shape of image view + * @return shape of image view + */ + public int getShape() { + return shape; } @Override @@ -64,15 +146,21 @@ protected void onDraw(Canvas canvas) { if (getDrawable() == null) { // Set a text font size based on the height of the view - mTextPaint.setTextSize(canvas.getHeight() - getTextPadding() * 2); - if (isOval()) { - canvas.drawCircle(canvas.getWidth() / 2f, canvas.getHeight() / 2f, Math.min(canvas.getWidth(), canvas.getHeight()) / 2f, - mBackgroundPaint); - } else { - canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), mBackgroundPaint); + mTextPaint.setTextSize(canvas.getHeight() - getTextPadding(true)); + if (!drawShape(canvas)) { + // if children can't draw shape, try to draw it on our own + switch (shape) { + case SHAPE_RECTANGLE: + drawRectangle(canvas); + break; + case SHAPE_OVAL: + drawOval(canvas); + break; + default: + throw new IllegalArgumentException("Invalid shape value"); + } } // Measure a text - Rect textBounds = new Rect(); mTextPaint.getTextBounds(String.valueOf(mLetter), 0, 1, textBounds); float textWidth = mTextPaint.measureText(String.valueOf(mLetter)); float textHeight = textBounds.height(); @@ -82,14 +170,89 @@ protected void onDraw(Canvas canvas) { } } - private float getTextPadding() { - // Set a default padding to 8dp - return 8 * getResources().getDisplayMetrics().density; + private void drawRectangle(final Canvas canvas) { + canvas.drawRect(getPaddingLeft(), getPaddingTop(), canvas.getWidth() - getPaddingRight(), + canvas.getHeight() - getPaddingBottom(), mBackgroundPaint); } + private void drawOval(final Canvas canvas) { + // check for padding + final int minSize = Math.min(canvas.getWidth(), canvas.getHeight()); + final int padding; + if (minSize == canvas.getWidth()) + padding = getPaddingRight() + getPaddingLeft(); + else + padding = getPaddingTop() + getPaddingBottom(); + float radius = (minSize - padding) / 2f; + canvas.drawCircle(canvas.getWidth() / 2f, canvas.getHeight() / 2f, radius, mBackgroundPaint); + } + + /** + * Get text padding + * @param withImageViewPadding set true if need padding with image view's padding + * @return text padding + */ + public float getTextPadding(boolean withImageViewPadding) { + float padding = textPadding; + if (withImageViewPadding) + padding += getPaddingTop() + getPaddingBottom(); + return padding; + } + + /** + * Set additional text padding + * @param textPadding text padding + */ + public void setTextPadding(float textPadding) { + if (textPadding < 0) + throw new IllegalArgumentException("Text padding must be greater or equals zero"); + this.textPadding = textPadding; + } + + /** + * Get shape color + * @return shape color + */ + public int getShapeColor() { + return shapeColor; + } + + /** + * Set shape color + * @param shapeColor shape color + */ + public void setShapeColor(int shapeColor) { + this.shapeColor = shapeColor; + mBackgroundPaint.setColor(shapeColor); + invalidate(); + } + + /** + * Generate random color + * @return random color or {@link Color#TRANSPARENT} if colors array not specified + */ private int randomColor() { + if (colorsArray == null) + return Color.TRANSPARENT; Random random = new Random(); - String[] colorsArr = getResources().getStringArray(R.array.colors); - return Color.parseColor(colorsArr[random.nextInt(colorsArr.length)]); + return Color.parseColor(colorsArray[random.nextInt(colorsArray.length)]); + } + + /** + * Draw custom shape. Place your custom implementation of drawShape here. + * @param canvas canvas + * @return true if shape was drawn + */ + protected boolean drawShape(Canvas canvas) { + return false; + } + + /** + * Check if specified shape can be drawn + * @param shape shape constant + * @return true if shape can be drawn + */ + protected boolean isCustomShape(int shape) { + return false; } } \ No newline at end of file diff --git a/app/src/main/java/com/melnykov/letterimageview/MainActivity.java b/app/src/main/java/com/melnykov/letterimageview/MainActivity.java index b10a7d6..85cfedd 100644 --- a/app/src/main/java/com/melnykov/letterimageview/MainActivity.java +++ b/app/src/main/java/com/melnykov/letterimageview/MainActivity.java @@ -3,14 +3,13 @@ import android.app.ListActivity; import android.content.Context; import android.os.Bundle; -import android.view.*; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; import android.widget.ArrayAdapter; -import android.widget.ListAdapter; import android.widget.TextView; -import com.melnykov.initialsimageview.R; -import java.util.Arrays; -import java.util.List; +import com.melnykov.initialsimageview.R; public class MainActivity extends ListActivity { @@ -18,31 +17,50 @@ public class MainActivity extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - - ListAdapter listAdapter = new SampleListAdapter(this, Arrays.asList(getResources().getStringArray(R.array.names))); + LetterImageView.init(this, R.array.colors, LetterImageView.SHAPE_OVAL); + Adapter listAdapter = new Adapter(this); + String[] names = getResources().getStringArray(R.array.names); + for (String name : names) + listAdapter.add(new Data(name)); setListAdapter(listAdapter); } - private static class SampleListAdapter extends ArrayAdapter { + private static class Adapter extends ArrayAdapter { - public SampleListAdapter(Context context, List objects) { - super(context, R.layout.list_item, objects); + public Adapter(Context context) { + super(context, R.layout.list_item); } @Override public View getView(int position, View convertView, ViewGroup parent) { - String name = getItem(position); + Data data = getItem(position); if (convertView == null) { convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false); } LetterImageView letterImageView = (LetterImageView) convertView.findViewById(R.id.iv_avatar); - letterImageView.setOval(true); TextView textView = (TextView) convertView.findViewById(R.id.tv_name); - letterImageView.setLetter(name.charAt(0)); - textView.setText(name); + if (position % 2 == 0) + letterImageView.setShape(LetterImageView.SHAPE_OVAL); + else + letterImageView.setShape(LetterImageView.SHAPE_RECTANGLE); + // store current color + if (data.color == 0) + data.color = letterImageView.getShapeColor(); + letterImageView.setShapeColor(data.color); + letterImageView.setLetter(data.text.charAt(0)); + textView.setText(data.text); return convertView; } } + + private static class Data { + private int color; + private String text; + + private Data(String text) { + this.text = text; + } + } } diff --git a/app/src/main/res/layout/list_item.xml b/app/src/main/res/layout/list_item.xml index a6a4df0..11c0651 100644 --- a/app/src/main/res/layout/list_item.xml +++ b/app/src/main/res/layout/list_item.xml @@ -1,19 +1,22 @@ + android:layout_width="match_parent" + android:layout_height="wrap_content"> + android:id="@+id/iv_avatar" + android:layout_width="70dp" + android:layout_height="70dp" + android:layout_margin="8dp" + android:padding="8dp" /> - + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 80eec1a..18d3abf 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:0.9.+' + classpath 'com.android.tools.build:gradle:0.13.2' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5de946b..81ac6e8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Apr 10 15:27:10 PDT 2013 +#Sun Nov 16 12:18:07 EET 2014 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.1-all.zip