initial
32
lib/TextDrawable/.gitignore
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
#built application files
|
||||
*.apk
|
||||
*.ap_
|
||||
|
||||
# files for the dex VM
|
||||
*.dex
|
||||
|
||||
# Java class files
|
||||
*.class
|
||||
|
||||
# generated files
|
||||
bin/
|
||||
gen/
|
||||
|
||||
# Local configuration file (sdk path, etc)
|
||||
local.properties
|
||||
|
||||
# Windows thumbnail db
|
||||
Thumbs.db
|
||||
|
||||
# OSX files
|
||||
.DS_Store
|
||||
|
||||
# Eclipse project files
|
||||
.classpath
|
||||
.project
|
||||
|
||||
# Android Studio
|
||||
.idea
|
||||
#.idea/workspace.xml - remove # and delete .idea if it better suit your needs.
|
||||
.gradle
|
||||
build/
|
||||
22
lib/TextDrawable/LICENSE
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Amulya Khare
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
133
lib/TextDrawable/README.md
Normal file
@@ -0,0 +1,133 @@
|
||||
###TextDrawable
|
||||
This light-weight library provides images with letter/text like the Gmail app. It extends the `Drawable` class thus can be used with existing/custom/network `ImageView` classes. Also included is a [fluent interface](http://en.wikipedia.org/wiki/Fluent_interface) for creating drawables and a customizable `ColorGenerator`.
|
||||
|
||||
<p align="center"><img src ="https://github.com/amulyakhare/TextDrawable/blob/master/screens/screen1-material.png" width="350"/>
|
||||
<img src ="https://github.com/amulyakhare/TextDrawable/blob/master/screens/screen2-material.png" width="350"/>
|
||||
</p>
|
||||
|
||||
###How to use
|
||||
|
||||
#### Import with Gradle:
|
||||
|
||||
```groovy
|
||||
repositories{
|
||||
maven {
|
||||
url 'http://dl.bintray.com/amulyakhare/maven'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
|
||||
}
|
||||
```
|
||||
|
||||
####1. Create simple tile:
|
||||
|
||||
<p align="center"><img src ="https://github.com/amulyakhare/TextDrawable/blob/master/screens/screen3.png"/>
|
||||
</p>
|
||||
|
||||
```xml
|
||||
<ImageView android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:id="@+id/image_view"/>
|
||||
```
|
||||
**Note:** Specify width/height for the `ImageView` and the `drawable` will auto-scale to fit the size.
|
||||
```java
|
||||
TextDrawable drawable = TextDrawable.builder()
|
||||
.buildRect("A", Color.RED);
|
||||
|
||||
ImageView image = (ImageView) findViewById(R.id.image_view);
|
||||
image.setImageDrawable(drawable);
|
||||
```
|
||||
|
||||
####2. Create rounded corner or circular tiles:
|
||||
|
||||
<p align="center"><img src ="https://github.com/amulyakhare/TextDrawable/blob/master/screens/screen6.png"/>
|
||||
</p>
|
||||
|
||||
```java
|
||||
TextDrawable drawable1 = TextDrawable.builder()
|
||||
.buildRoundRect("A", Color.RED, 10); // radius in px
|
||||
|
||||
TextDrawable drawable2 = TextDrawable.builder()
|
||||
.buildRound("A", Color.RED);
|
||||
```
|
||||
|
||||
####3. Add border:
|
||||
|
||||
<p align="center"><img src ="https://github.com/amulyakhare/TextDrawable/blob/master/screens/screen5.png"/>
|
||||
</p>
|
||||
|
||||
```java
|
||||
TextDrawable drawable = TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.withBorder(4) /* thickness in px */
|
||||
.endConfig()
|
||||
.buildRoundRect("A", Color.RED, 10);
|
||||
```
|
||||
|
||||
####4. Modify font style:
|
||||
|
||||
```java
|
||||
TextDrawable drawable = TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.textColor(Color.BLACK)
|
||||
.useFont(Typeface.DEFAULT)
|
||||
.fontSize(30) /* size in px */
|
||||
.bold()
|
||||
.toUpperCase()
|
||||
.endConfig()
|
||||
.buildRect("a", Color.RED)
|
||||
```
|
||||
|
||||
####5. Built-in color generator:
|
||||
|
||||
```java
|
||||
ColorGenerator generator = ColorGenerator.MATERIAL; // or use DEFAULT
|
||||
// generate random color
|
||||
int color1 = generator.getRandomColor();
|
||||
// generate color based on a key (same key returns the same color), useful for list/grid views
|
||||
int color2 = generator.getColor("user@gmail.com")
|
||||
|
||||
// declare the builder object once.
|
||||
TextDrawable.IBuilder builder = TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.withBorder(4)
|
||||
.endConfig()
|
||||
.rect();
|
||||
|
||||
// reuse the builder specs to create multiple drawables
|
||||
TextDrawable ic1 = builder.build("A", color1);
|
||||
TextDrawable ic2 = builder.build("B", color2);
|
||||
```
|
||||
|
||||
####6. Specify the width / height:
|
||||
|
||||
```xml
|
||||
<ImageView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/image_view"/>
|
||||
```
|
||||
**Note:** The `ImageView` could use `wrap_content` width/height. You could set the width/height of the `drawable` using code.
|
||||
|
||||
```java
|
||||
TextDrawable drawable = TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.width(60) // width in px
|
||||
.height(60) // height in px
|
||||
.endConfig()
|
||||
.buildRect("A", Color.RED);
|
||||
|
||||
ImageView image = (ImageView) findViewById(R.id.image_view);
|
||||
image.setImageDrawable(drawable);
|
||||
```
|
||||
|
||||
####7. Other features:
|
||||
|
||||
1. Mix-match with other drawables. Use it in conjunction with `LayerDrawable`, `InsetDrawable`, `AnimationDrawable`, `TransitionDrawable` etc.
|
||||
|
||||
2. Compatible with other views (not just `ImageView`). Use it as background drawable, compound drawable for `TextView`, `Button` etc.
|
||||
|
||||
3. Use multiple letters or `unicode` characters to create interesting tiles.
|
||||
|
||||
<p align="center"><img src ="https://github.com/amulyakhare/TextDrawable/blob/master/screens/screen7.png" width="350"/></p>
|
||||
18
lib/TextDrawable/build.gradle
Normal file
@@ -0,0 +1,18 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.0.0'
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
18
lib/TextDrawable/gradle.properties
Normal file
@@ -0,0 +1,18 @@
|
||||
# Project-wide Gradle settings.
|
||||
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Settings specified in this file will override any Gradle settings
|
||||
# configured through the IDE.
|
||||
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
# Default value: -Xmx10248m -XX:MaxPermSize=256m
|
||||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
6
lib/TextDrawable/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#Mon Mar 02 14:59:31 WIB 2026
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
164
lib/TextDrawable/gradlew
vendored
Executable file
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
90
lib/TextDrawable/gradlew.bat
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
1
lib/TextDrawable/library/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
39
lib/TextDrawable/library/build.gradle
Normal file
@@ -0,0 +1,39 @@
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
namespace 'com.amulyakhare.textdrawable'
|
||||
compileSdkVersion 33
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 10
|
||||
targetSdkVersion 33
|
||||
versionCode 2
|
||||
versionName "1.1"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
srcDir 'src/main/java'
|
||||
}
|
||||
resources {
|
||||
srcDir 'src/main/res'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
archiveClassifier.set('sources')
|
||||
from sourceSets.main.java, sourceSets.main.resources
|
||||
}
|
||||
17
lib/TextDrawable/library/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /home/gardev/android/adt-bundle-linux/sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
3
lib/TextDrawable/library/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<manifest package="com.amulyakhare.textdrawable">
|
||||
<application/>
|
||||
</manifest>
|
||||
@@ -0,0 +1,316 @@
|
||||
package com.amulyakhare.textdrawable;
|
||||
|
||||
import android.graphics.*;
|
||||
import android.graphics.drawable.ShapeDrawable;
|
||||
import android.graphics.drawable.shapes.OvalShape;
|
||||
import android.graphics.drawable.shapes.RectShape;
|
||||
import android.graphics.drawable.shapes.RoundRectShape;
|
||||
|
||||
/**
|
||||
* @author amulya
|
||||
* @datetime 14 Oct 2014, 3:53 PM
|
||||
*/
|
||||
public class TextDrawable extends ShapeDrawable {
|
||||
|
||||
private final Paint textPaint;
|
||||
private final Paint borderPaint;
|
||||
private static final float SHADE_FACTOR = 0.9f;
|
||||
private final String text;
|
||||
private final int color;
|
||||
private final RectShape shape;
|
||||
private final int height;
|
||||
private final int width;
|
||||
private final int fontSize;
|
||||
private final float radius;
|
||||
private final int borderThickness;
|
||||
|
||||
private TextDrawable(Builder builder) {
|
||||
super(builder.shape);
|
||||
|
||||
// shape properties
|
||||
shape = builder.shape;
|
||||
height = builder.height;
|
||||
width = builder.width;
|
||||
radius = builder.radius;
|
||||
|
||||
// text and color
|
||||
text = builder.toUpperCase ? builder.text.toUpperCase() : builder.text;
|
||||
color = builder.color;
|
||||
|
||||
// text paint settings
|
||||
fontSize = builder.fontSize;
|
||||
textPaint = new Paint();
|
||||
textPaint.setColor(builder.textColor);
|
||||
textPaint.setAntiAlias(true);
|
||||
textPaint.setFakeBoldText(builder.isBold);
|
||||
textPaint.setStyle(Paint.Style.FILL);
|
||||
textPaint.setTypeface(builder.font);
|
||||
textPaint.setTextAlign(Paint.Align.CENTER);
|
||||
textPaint.setStrokeWidth(builder.borderThickness);
|
||||
|
||||
// border paint settings
|
||||
borderThickness = builder.borderThickness;
|
||||
borderPaint = new Paint();
|
||||
borderPaint.setColor(getDarkerShade(color));
|
||||
borderPaint.setStyle(Paint.Style.STROKE);
|
||||
borderPaint.setStrokeWidth(borderThickness);
|
||||
|
||||
// drawable paint color
|
||||
Paint paint = getPaint();
|
||||
paint.setColor(color);
|
||||
|
||||
}
|
||||
|
||||
private int getDarkerShade(int color) {
|
||||
return Color.rgb((int)(SHADE_FACTOR * Color.red(color)),
|
||||
(int)(SHADE_FACTOR * Color.green(color)),
|
||||
(int)(SHADE_FACTOR * Color.blue(color)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
super.draw(canvas);
|
||||
Rect r = getBounds();
|
||||
|
||||
|
||||
// draw border
|
||||
if (borderThickness > 0) {
|
||||
drawBorder(canvas);
|
||||
}
|
||||
|
||||
int count = canvas.save();
|
||||
canvas.translate(r.left, r.top);
|
||||
|
||||
// draw text
|
||||
int width = this.width < 0 ? r.width() : this.width;
|
||||
int height = this.height < 0 ? r.height() : this.height;
|
||||
int fontSize = this.fontSize < 0 ? (Math.min(width, height) / 2) : this.fontSize;
|
||||
textPaint.setTextSize(fontSize);
|
||||
canvas.drawText(text, width / 2, height / 2 - ((textPaint.descent() + textPaint.ascent()) / 2), textPaint);
|
||||
|
||||
canvas.restoreToCount(count);
|
||||
|
||||
}
|
||||
|
||||
private void drawBorder(Canvas canvas) {
|
||||
RectF rect = new RectF(getBounds());
|
||||
rect.inset(borderThickness/2, borderThickness/2);
|
||||
|
||||
if (shape instanceof OvalShape) {
|
||||
canvas.drawOval(rect, borderPaint);
|
||||
}
|
||||
else if (shape instanceof RoundRectShape) {
|
||||
canvas.drawRoundRect(rect, radius, radius, borderPaint);
|
||||
}
|
||||
else {
|
||||
canvas.drawRect(rect, borderPaint);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
textPaint.setAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter cf) {
|
||||
textPaint.setColorFilter(cf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public static IShapeBuilder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder implements IConfigBuilder, IShapeBuilder, IBuilder {
|
||||
|
||||
private String text;
|
||||
|
||||
private int color;
|
||||
|
||||
private int borderThickness;
|
||||
|
||||
private int width;
|
||||
|
||||
private int height;
|
||||
|
||||
private Typeface font;
|
||||
|
||||
private RectShape shape;
|
||||
|
||||
public int textColor;
|
||||
|
||||
private int fontSize;
|
||||
|
||||
private boolean isBold;
|
||||
|
||||
private boolean toUpperCase;
|
||||
|
||||
public float radius;
|
||||
|
||||
private Builder() {
|
||||
text = "";
|
||||
color = Color.GRAY;
|
||||
textColor = Color.WHITE;
|
||||
borderThickness = 0;
|
||||
width = -1;
|
||||
height = -1;
|
||||
shape = new RectShape();
|
||||
font = Typeface.create("sans-serif-light", Typeface.NORMAL);
|
||||
fontSize = -1;
|
||||
isBold = false;
|
||||
toUpperCase = false;
|
||||
}
|
||||
|
||||
public IConfigBuilder width(int width) {
|
||||
this.width = width;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IConfigBuilder height(int height) {
|
||||
this.height = height;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IConfigBuilder textColor(int color) {
|
||||
this.textColor = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IConfigBuilder withBorder(int thickness) {
|
||||
this.borderThickness = thickness;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IConfigBuilder useFont(Typeface font) {
|
||||
this.font = font;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IConfigBuilder fontSize(int size) {
|
||||
this.fontSize = size;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IConfigBuilder bold() {
|
||||
this.isBold = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IConfigBuilder toUpperCase() {
|
||||
this.toUpperCase = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IConfigBuilder beginConfig() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IShapeBuilder endConfig() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBuilder rect() {
|
||||
this.shape = new RectShape();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBuilder round() {
|
||||
this.shape = new OvalShape();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBuilder roundRect(int radius) {
|
||||
this.radius = radius;
|
||||
float[] radii = {radius, radius, radius, radius, radius, radius, radius, radius};
|
||||
this.shape = new RoundRectShape(radii, null, null);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextDrawable buildRect(String text, int color) {
|
||||
rect();
|
||||
return build(text, color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextDrawable buildRoundRect(String text, int color, int radius) {
|
||||
roundRect(radius);
|
||||
return build(text, color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextDrawable buildRound(String text, int color) {
|
||||
round();
|
||||
return build(text, color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextDrawable build(String text, int color) {
|
||||
this.color = color;
|
||||
this.text = text;
|
||||
return new TextDrawable(this);
|
||||
}
|
||||
}
|
||||
|
||||
public interface IConfigBuilder {
|
||||
public IConfigBuilder width(int width);
|
||||
|
||||
public IConfigBuilder height(int height);
|
||||
|
||||
public IConfigBuilder textColor(int color);
|
||||
|
||||
public IConfigBuilder withBorder(int thickness);
|
||||
|
||||
public IConfigBuilder useFont(Typeface font);
|
||||
|
||||
public IConfigBuilder fontSize(int size);
|
||||
|
||||
public IConfigBuilder bold();
|
||||
|
||||
public IConfigBuilder toUpperCase();
|
||||
|
||||
public IShapeBuilder endConfig();
|
||||
}
|
||||
|
||||
public static interface IBuilder {
|
||||
|
||||
public TextDrawable build(String text, int color);
|
||||
}
|
||||
|
||||
public static interface IShapeBuilder {
|
||||
|
||||
public IConfigBuilder beginConfig();
|
||||
|
||||
public IBuilder rect();
|
||||
|
||||
public IBuilder round();
|
||||
|
||||
public IBuilder roundRect(int radius);
|
||||
|
||||
public TextDrawable buildRect(String text, int color);
|
||||
|
||||
public TextDrawable buildRoundRect(String text, int color, int radius);
|
||||
|
||||
public TextDrawable buildRound(String text, int color);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.amulyakhare.textdrawable.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* @author amulya
|
||||
* @datetime 14 Oct 2014, 5:20 PM
|
||||
*/
|
||||
public class ColorGenerator {
|
||||
|
||||
public static ColorGenerator DEFAULT;
|
||||
|
||||
public static ColorGenerator MATERIAL;
|
||||
|
||||
static {
|
||||
DEFAULT = create(Arrays.asList(
|
||||
0xfff16364,
|
||||
0xfff58559,
|
||||
0xfff9a43e,
|
||||
0xffe4c62e,
|
||||
0xff67bf74,
|
||||
0xff59a2be,
|
||||
0xff2093cd,
|
||||
0xffad62a7,
|
||||
0xff805781
|
||||
));
|
||||
MATERIAL = create(Arrays.asList(
|
||||
0xffe57373,
|
||||
0xfff06292,
|
||||
0xffba68c8,
|
||||
0xff9575cd,
|
||||
0xff7986cb,
|
||||
0xff64b5f6,
|
||||
0xff4fc3f7,
|
||||
0xff4dd0e1,
|
||||
0xff4db6ac,
|
||||
0xff81c784,
|
||||
0xffaed581,
|
||||
0xffff8a65,
|
||||
0xffd4e157,
|
||||
0xffffd54f,
|
||||
0xffffb74d,
|
||||
0xffa1887f,
|
||||
0xff90a4ae
|
||||
));
|
||||
}
|
||||
|
||||
private final List<Integer> mColors;
|
||||
private final Random mRandom;
|
||||
|
||||
public static ColorGenerator create(List<Integer> colorList) {
|
||||
return new ColorGenerator(colorList);
|
||||
}
|
||||
|
||||
private ColorGenerator(List<Integer> colorList) {
|
||||
mColors = colorList;
|
||||
mRandom = new Random(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public int getRandomColor() {
|
||||
return mColors.get(mRandom.nextInt(mColors.size()));
|
||||
}
|
||||
|
||||
public int getColor(Object key) {
|
||||
return mColors.get(Math.abs(key.hashCode()) % mColors.size());
|
||||
}
|
||||
}
|
||||
1
lib/TextDrawable/sample/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
26
lib/TextDrawable/sample/build.gradle
Normal file
@@ -0,0 +1,26 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 21
|
||||
buildToolsVersion "21.1.1"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.amulyakhare.td"
|
||||
minSdkVersion 10
|
||||
targetSdkVersion 21
|
||||
versionCode 2
|
||||
versionName "1.0"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile project(':library')
|
||||
compile 'com.android.support:appcompat-v7:21.0.3'
|
||||
}
|
||||
17
lib/TextDrawable/sample/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /home/gardev/android/adt-bundle-linux/sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
25
lib/TextDrawable/sample/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.amulyakhare.td" >
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" >
|
||||
<activity
|
||||
android:name="com.amulyakhare.td.sample.MainActivity"
|
||||
android:label="@string/app_name" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name="com.amulyakhare.td.sample.ListActivity"
|
||||
android:label="@string/title_activity_check_box" >
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,193 @@
|
||||
package com.amulyakhare.td.sample;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.amulyakhare.td.R;
|
||||
import com.amulyakhare.td.sample.sample.DrawableProvider;
|
||||
import com.amulyakhare.textdrawable.TextDrawable;
|
||||
import com.amulyakhare.textdrawable.util.ColorGenerator;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class ListActivity extends ActionBarActivity {
|
||||
|
||||
private static final int HIGHLIGHT_COLOR = 0x999be6ff;
|
||||
|
||||
// list of data items
|
||||
private List<ListData> mDataList = Arrays.asList(
|
||||
new ListData("Iron Man"),
|
||||
new ListData("Captain America"),
|
||||
new ListData("James Bond"),
|
||||
new ListData("Harry Potter"),
|
||||
new ListData("Sherlock Holmes"),
|
||||
new ListData("Black Widow"),
|
||||
new ListData("Hawk Eye"),
|
||||
new ListData("Iron Man"),
|
||||
new ListData("Guava"),
|
||||
new ListData("Tomato"),
|
||||
new ListData("Pineapple"),
|
||||
new ListData("Strawberry"),
|
||||
new ListData("Watermelon"),
|
||||
new ListData("Pears"),
|
||||
new ListData("Kiwi"),
|
||||
new ListData("Plums")
|
||||
);
|
||||
|
||||
// declare the color generator and drawable builder
|
||||
private ColorGenerator mColorGenerator = ColorGenerator.MATERIAL;
|
||||
private TextDrawable.IBuilder mDrawableBuilder;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_list);
|
||||
|
||||
Intent intent = getIntent();
|
||||
int type = intent.getIntExtra(MainActivity.TYPE, DrawableProvider.SAMPLE_RECT);
|
||||
|
||||
// initialize the builder based on the "TYPE"
|
||||
switch (type) {
|
||||
case DrawableProvider.SAMPLE_RECT:
|
||||
mDrawableBuilder = TextDrawable.builder()
|
||||
.rect();
|
||||
break;
|
||||
case DrawableProvider.SAMPLE_ROUND_RECT:
|
||||
mDrawableBuilder = TextDrawable.builder()
|
||||
.roundRect(10);
|
||||
break;
|
||||
case DrawableProvider.SAMPLE_ROUND:
|
||||
mDrawableBuilder = TextDrawable.builder()
|
||||
.round();
|
||||
break;
|
||||
case DrawableProvider.SAMPLE_RECT_BORDER:
|
||||
mDrawableBuilder = TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.withBorder(4)
|
||||
.endConfig()
|
||||
.rect();
|
||||
break;
|
||||
case DrawableProvider.SAMPLE_ROUND_RECT_BORDER:
|
||||
mDrawableBuilder = TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.withBorder(4)
|
||||
.endConfig()
|
||||
.roundRect(10);
|
||||
break;
|
||||
case DrawableProvider.SAMPLE_ROUND_BORDER:
|
||||
mDrawableBuilder = TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.withBorder(4)
|
||||
.endConfig()
|
||||
.round();
|
||||
break;
|
||||
}
|
||||
|
||||
// init the list view and its adapter
|
||||
ListView listView = (ListView) findViewById(R.id.listView);
|
||||
listView.setAdapter(new SampleAdapter());
|
||||
}
|
||||
|
||||
private class SampleAdapter extends BaseAdapter {
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mDataList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListData getItem(int position) {
|
||||
return mDataList.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||
final ViewHolder holder;
|
||||
if (convertView == null) {
|
||||
convertView = View.inflate(ListActivity.this, R.layout.list_item_layout, null);
|
||||
holder = new ViewHolder(convertView);
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
ListData item = getItem(position);
|
||||
|
||||
// provide support for selected state
|
||||
updateCheckedState(holder, item);
|
||||
holder.imageView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// when the image is clicked, update the selected state
|
||||
ListData data = getItem(position);
|
||||
data.setChecked(!data.isChecked);
|
||||
updateCheckedState(holder, data);
|
||||
}
|
||||
});
|
||||
holder.textView.setText(item.data);
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
private void updateCheckedState(ViewHolder holder, ListData item) {
|
||||
if (item.isChecked) {
|
||||
holder.imageView.setImageDrawable(mDrawableBuilder.build(" ", 0xff616161));
|
||||
holder.view.setBackgroundColor(HIGHLIGHT_COLOR);
|
||||
holder.checkIcon.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
TextDrawable drawable = mDrawableBuilder.build(String.valueOf(item.data.charAt(0)), mColorGenerator.getColor(item.data));
|
||||
holder.imageView.setImageDrawable(drawable);
|
||||
holder.view.setBackgroundColor(Color.TRANSPARENT);
|
||||
holder.checkIcon.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ViewHolder {
|
||||
|
||||
private View view;
|
||||
|
||||
private ImageView imageView;
|
||||
|
||||
private TextView textView;
|
||||
|
||||
private ImageView checkIcon;
|
||||
|
||||
private ViewHolder(View view) {
|
||||
this.view = view;
|
||||
imageView = (ImageView) view.findViewById(R.id.imageView);
|
||||
textView = (TextView) view.findViewById(R.id.textView);
|
||||
checkIcon = (ImageView) view.findViewById(R.id.check_icon);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ListData {
|
||||
|
||||
private String data;
|
||||
|
||||
private boolean isChecked;
|
||||
|
||||
public ListData(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public void setChecked(boolean isChecked) {
|
||||
this.isChecked = isChecked;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package com.amulyakhare.td.sample;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.AnimationDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.*;
|
||||
|
||||
import com.amulyakhare.td.R;
|
||||
import com.amulyakhare.td.sample.sample.DataItem;
|
||||
import com.amulyakhare.td.sample.sample.DataSource;
|
||||
|
||||
public class MainActivity extends ActionBarActivity implements AdapterView.OnItemClickListener {
|
||||
|
||||
public static final String TYPE = "TYPE";
|
||||
private DataSource mDataSource;
|
||||
private ListView mListView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
mListView = (ListView) findViewById(R.id.listView);
|
||||
mDataSource = new DataSource(this);
|
||||
mListView.setAdapter(new SampleAdapter());
|
||||
mListView.setOnItemClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
DataItem item = (DataItem) mListView.getItemAtPosition(position);
|
||||
|
||||
// if navigation is supported, open the next activity
|
||||
if (item.getNavigationInfo() != DataSource.NO_NAVIGATION) {
|
||||
Intent intent = new Intent(this, ListActivity.class);
|
||||
intent.putExtra(TYPE, item.getNavigationInfo());
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
private class SampleAdapter extends BaseAdapter {
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mDataSource.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataItem getItem(int position) {
|
||||
return mDataSource.getItem(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
ViewHolder holder;
|
||||
if (convertView == null) {
|
||||
convertView = View.inflate(MainActivity.this, R.layout.list_item_layout, null);
|
||||
holder = new ViewHolder(convertView);
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
DataItem item = getItem(position);
|
||||
|
||||
final Drawable drawable = item.getDrawable();
|
||||
holder.imageView.setImageDrawable(drawable);
|
||||
holder.textView.setText(item.getLabel());
|
||||
|
||||
// if navigation is supported, show the ">" navigation icon
|
||||
if (item.getNavigationInfo() != DataSource.NO_NAVIGATION) {
|
||||
holder.textView.setCompoundDrawablesWithIntrinsicBounds(null,
|
||||
null,
|
||||
getResources().getDrawable(R.drawable.ic_action_next_item),
|
||||
null);
|
||||
}
|
||||
else {
|
||||
holder.textView.setCompoundDrawablesWithIntrinsicBounds(null,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
}
|
||||
|
||||
// fix for animation not playing for some below 4.4 devices
|
||||
if (drawable instanceof AnimationDrawable) {
|
||||
holder.imageView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
((AnimationDrawable) drawable).stop();
|
||||
((AnimationDrawable) drawable).start();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return convertView;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ViewHolder {
|
||||
|
||||
private ImageView imageView;
|
||||
|
||||
private TextView textView;
|
||||
|
||||
private ViewHolder(View view) {
|
||||
imageView = (ImageView) view.findViewById(R.id.imageView);
|
||||
textView = (TextView) view.findViewById(R.id.textView);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.amulyakhare.td.sample.sample;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
/**
|
||||
* @author amulya
|
||||
* @datetime 17 Oct 2014, 3:50 PM
|
||||
*/
|
||||
public class DataItem {
|
||||
|
||||
private String label;
|
||||
|
||||
private Drawable drawable;
|
||||
|
||||
private int navigationInfo;
|
||||
|
||||
public DataItem(String label, Drawable drawable, int navigationInfo) {
|
||||
this.label = label;
|
||||
this.drawable = drawable;
|
||||
this.navigationInfo = navigationInfo;
|
||||
}
|
||||
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public Drawable getDrawable() {
|
||||
return drawable;
|
||||
}
|
||||
|
||||
public int getNavigationInfo() {
|
||||
return navigationInfo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.amulyakhare.td.sample.sample;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author amulya
|
||||
* @datetime 17 Oct 2014, 3:49 PM
|
||||
*/
|
||||
public class DataSource {
|
||||
|
||||
public static final int NO_NAVIGATION = -1;
|
||||
|
||||
private ArrayList<DataItem> mDataSource;
|
||||
private DrawableProvider mProvider;
|
||||
|
||||
public DataSource(Context context) {
|
||||
mProvider = new DrawableProvider(context);
|
||||
mDataSource = new ArrayList<DataItem>();
|
||||
mDataSource.add(itemFromType(DrawableProvider.SAMPLE_RECT));
|
||||
mDataSource.add(itemFromType(DrawableProvider.SAMPLE_ROUND_RECT));
|
||||
mDataSource.add(itemFromType(DrawableProvider.SAMPLE_ROUND));
|
||||
mDataSource.add(itemFromType(DrawableProvider.SAMPLE_RECT_BORDER));
|
||||
mDataSource.add(itemFromType(DrawableProvider.SAMPLE_ROUND_RECT_BORDER));
|
||||
mDataSource.add(itemFromType(DrawableProvider.SAMPLE_ROUND_BORDER));
|
||||
mDataSource.add(itemFromType(DrawableProvider.SAMPLE_MULTIPLE_LETTERS));
|
||||
mDataSource.add(itemFromType(DrawableProvider.SAMPLE_FONT));
|
||||
mDataSource.add(itemFromType(DrawableProvider.SAMPLE_SIZE));
|
||||
mDataSource.add(itemFromType(DrawableProvider.SAMPLE_ANIMATION));
|
||||
mDataSource.add(itemFromType(DrawableProvider.SAMPLE_MISC));
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return mDataSource.size();
|
||||
}
|
||||
|
||||
public DataItem getItem(int position) {
|
||||
return mDataSource.get(position);
|
||||
}
|
||||
|
||||
private DataItem itemFromType(int type) {
|
||||
String label = null;
|
||||
Drawable drawable = null;
|
||||
switch (type) {
|
||||
case DrawableProvider.SAMPLE_RECT:
|
||||
label = "Rectangle with Text";
|
||||
drawable = mProvider.getRect("A");
|
||||
break;
|
||||
case DrawableProvider.SAMPLE_ROUND_RECT:
|
||||
label = "Round Corner with Text";
|
||||
drawable = mProvider.getRoundRect("B");
|
||||
break;
|
||||
case DrawableProvider.SAMPLE_ROUND:
|
||||
label = "Round with Text";
|
||||
drawable = mProvider.getRound("C");
|
||||
break;
|
||||
case DrawableProvider.SAMPLE_RECT_BORDER:
|
||||
label = "Rectangle with Border";
|
||||
drawable = mProvider.getRectWithBorder("D");
|
||||
break;
|
||||
case DrawableProvider.SAMPLE_ROUND_RECT_BORDER:
|
||||
label = "Round Corner with Border";
|
||||
drawable = mProvider.getRoundRectWithBorder("E");
|
||||
break;
|
||||
case DrawableProvider.SAMPLE_ROUND_BORDER:
|
||||
label = "Round with Border";
|
||||
drawable = mProvider.getRoundWithBorder("F");
|
||||
break;
|
||||
case DrawableProvider.SAMPLE_MULTIPLE_LETTERS:
|
||||
label = "Support multiple letters";
|
||||
drawable = mProvider.getRectWithMultiLetter();
|
||||
type = NO_NAVIGATION;
|
||||
break;
|
||||
case DrawableProvider.SAMPLE_FONT:
|
||||
label = "Support variable font styles";
|
||||
drawable = mProvider.getRoundWithCustomFont();
|
||||
type = NO_NAVIGATION;
|
||||
break;
|
||||
case DrawableProvider.SAMPLE_SIZE:
|
||||
label = "Support for custom size";
|
||||
drawable = mProvider.getRectWithCustomSize();
|
||||
type = NO_NAVIGATION;
|
||||
break;
|
||||
case DrawableProvider.SAMPLE_ANIMATION:
|
||||
label = "Support for animations";
|
||||
drawable = mProvider.getRectWithAnimation();
|
||||
type = NO_NAVIGATION;
|
||||
break;
|
||||
case DrawableProvider.SAMPLE_MISC:
|
||||
label = "Miscellaneous";
|
||||
drawable = mProvider.getRect("\u03c0");
|
||||
type = NO_NAVIGATION;
|
||||
break;
|
||||
}
|
||||
return new DataItem(label, drawable, type);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
package com.amulyakhare.td.sample.sample;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.AnimationDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.InsetDrawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import com.amulyakhare.textdrawable.TextDrawable;
|
||||
import com.amulyakhare.textdrawable.util.ColorGenerator;
|
||||
|
||||
/**
|
||||
* @author amulya
|
||||
* @datetime 17 Oct 2014, 4:02 PM
|
||||
*/
|
||||
public class DrawableProvider {
|
||||
|
||||
public static final int SAMPLE_RECT = 1;
|
||||
public static final int SAMPLE_ROUND_RECT = 2;
|
||||
public static final int SAMPLE_ROUND = 3;
|
||||
public static final int SAMPLE_RECT_BORDER = 4;
|
||||
public static final int SAMPLE_ROUND_RECT_BORDER = 5;
|
||||
public static final int SAMPLE_ROUND_BORDER = 6;
|
||||
public static final int SAMPLE_MULTIPLE_LETTERS = 7;
|
||||
public static final int SAMPLE_FONT = 8;
|
||||
public static final int SAMPLE_SIZE = 9;
|
||||
public static final int SAMPLE_ANIMATION = 10;
|
||||
public static final int SAMPLE_MISC = 11;
|
||||
|
||||
private final ColorGenerator mGenerator;
|
||||
private final Context mContext;
|
||||
|
||||
public DrawableProvider(Context context) {
|
||||
mGenerator = ColorGenerator.DEFAULT;
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
public TextDrawable getRect(String text) {
|
||||
return TextDrawable.builder()
|
||||
.buildRect(text, mGenerator.getColor(text));
|
||||
}
|
||||
|
||||
public TextDrawable getRound(String text) {
|
||||
return TextDrawable.builder()
|
||||
.buildRound(text, mGenerator.getColor(text));
|
||||
}
|
||||
|
||||
public TextDrawable getRoundRect(String text) {
|
||||
return TextDrawable.builder()
|
||||
.buildRoundRect(text, mGenerator.getColor(text), toPx(10));
|
||||
}
|
||||
|
||||
public TextDrawable getRectWithBorder(String text) {
|
||||
return TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.withBorder(toPx(2))
|
||||
.endConfig()
|
||||
.buildRect(text, mGenerator.getColor(text));
|
||||
}
|
||||
|
||||
public TextDrawable getRoundWithBorder(String text) {
|
||||
return TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.withBorder(toPx(2))
|
||||
.endConfig()
|
||||
.buildRound(text, mGenerator.getColor(text));
|
||||
}
|
||||
|
||||
public TextDrawable getRoundRectWithBorder(String text) {
|
||||
return TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.withBorder(toPx(2))
|
||||
.endConfig()
|
||||
.buildRoundRect(text, mGenerator.getColor(text), toPx(10));
|
||||
}
|
||||
|
||||
public TextDrawable getRectWithMultiLetter() {
|
||||
String text = "AK";
|
||||
return TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.fontSize(toPx(20))
|
||||
.toUpperCase()
|
||||
.endConfig()
|
||||
.buildRect(text, mGenerator.getColor(text));
|
||||
}
|
||||
|
||||
public TextDrawable getRoundWithCustomFont() {
|
||||
String text = "Bold";
|
||||
return TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.useFont(Typeface.DEFAULT)
|
||||
.fontSize(toPx(15))
|
||||
.textColor(0xfff58559)
|
||||
.bold()
|
||||
.endConfig()
|
||||
.buildRect(text, Color.DKGRAY /*toPx(5)*/);
|
||||
}
|
||||
|
||||
public Drawable getRectWithCustomSize() {
|
||||
String leftText = "I";
|
||||
String rightText = "J";
|
||||
|
||||
TextDrawable.IBuilder builder = TextDrawable.builder()
|
||||
.beginConfig()
|
||||
.width(toPx(29))
|
||||
.withBorder(toPx(2))
|
||||
.endConfig()
|
||||
.rect();
|
||||
|
||||
TextDrawable left = builder
|
||||
.build(leftText, mGenerator.getColor(leftText));
|
||||
|
||||
TextDrawable right = builder
|
||||
.build(rightText, mGenerator.getColor(rightText));
|
||||
|
||||
Drawable[] layerList = {
|
||||
new InsetDrawable(left, 0, 0, toPx(31), 0),
|
||||
new InsetDrawable(right, toPx(31), 0, 0, 0)
|
||||
};
|
||||
return new LayerDrawable(layerList);
|
||||
}
|
||||
|
||||
public Drawable getRectWithAnimation() {
|
||||
TextDrawable.IBuilder builder = TextDrawable.builder()
|
||||
.rect();
|
||||
|
||||
AnimationDrawable animationDrawable = new AnimationDrawable();
|
||||
for (int i = 10; i > 0; i--) {
|
||||
TextDrawable frame = builder.build(String.valueOf(i), mGenerator.getRandomColor());
|
||||
animationDrawable.addFrame(frame, 1200);
|
||||
}
|
||||
animationDrawable.setOneShot(false);
|
||||
animationDrawable.start();
|
||||
|
||||
return animationDrawable;
|
||||
}
|
||||
|
||||
public int toPx(int dp) {
|
||||
Resources resources = mContext.getResources();
|
||||
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, resources.getDisplayMetrics());
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 980 B |
|
After Width: | Height: | Size: 585 B |
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 688 B |
|
After Width: | Height: | Size: 942 B |
|
After Width: | Height: | Size: 427 B |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 727 B |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 1021 B |
|
After Width: | Height: | Size: 19 KiB |
@@ -0,0 +1,16 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
tools:context="com.amulyakhare.td.sample.ListActivity">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/imageButton"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp" />
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,8 @@
|
||||
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/listView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="com.amulyakhare.td.sample.MiscActivity">
|
||||
|
||||
</ListView>
|
||||
@@ -0,0 +1,8 @@
|
||||
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/listView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="com.amulyakhare.td.sample.MiscActivity">
|
||||
|
||||
</ListView>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:id="@+id/imageView"/>
|
||||
|
||||
<ImageView
|
||||
android:visibility="gone"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:src="@drawable/check_sm"
|
||||
android:id="@+id/check_icon"/>
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:id="@+id/textView"/>
|
||||
|
||||
</LinearLayout>
|
||||
9
lib/TextDrawable/sample/src/main/res/menu/check_box.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context="com.amulyakhare.td.sample.ListActivity" >
|
||||
<item android:id="@+id/action_settings"
|
||||
android:title="@string/action_settings"
|
||||
android:orderInCategory="100"
|
||||
app:showAsAction="never" />
|
||||
</menu>
|
||||
9
lib/TextDrawable/sample/src/main/res/menu/list.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context="com.amulyakhare.td.sample.MiscActivity" >
|
||||
<item android:id="@+id/action_settings"
|
||||
android:title="@string/action_settings"
|
||||
android:orderInCategory="100"
|
||||
app:showAsAction="never" />
|
||||
</menu>
|
||||
9
lib/TextDrawable/sample/src/main/res/menu/main.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context=".MainActivity" >
|
||||
<item android:id="@+id/action_settings"
|
||||
android:title="@string/action_settings"
|
||||
android:orderInCategory="100"
|
||||
app:showAsAction="never" />
|
||||
</menu>
|
||||
@@ -0,0 +1,6 @@
|
||||
<resources>
|
||||
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
|
||||
(such as screen margins) for screens with more than 820dp of available width. This
|
||||
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
|
||||
<dimen name="activity_horizontal_margin">64dp</dimen>
|
||||
</resources>
|
||||
5
lib/TextDrawable/sample/src/main/res/values/dimens.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<resources>
|
||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
</resources>
|
||||
10
lib/TextDrawable/sample/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="app_name">TextDrawable Sample</string>
|
||||
<string name="hello_world">Hello world!</string>
|
||||
<string name="action_settings">Settings</string>
|
||||
<string name="title_activity_list">TextDrawable Sample</string>
|
||||
<string name="title_activity_check_box">TextDrawable Sample</string>
|
||||
|
||||
</resources>
|
||||
8
lib/TextDrawable/sample/src/main/res/values/styles.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
BIN
lib/TextDrawable/screens/screen1-material.png
Normal file
|
After Width: | Height: | Size: 88 KiB |
BIN
lib/TextDrawable/screens/screen1.png
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
lib/TextDrawable/screens/screen2-material.png
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
lib/TextDrawable/screens/screen2.png
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
lib/TextDrawable/screens/screen3.png
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
lib/TextDrawable/screens/screen4.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
lib/TextDrawable/screens/screen5.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
lib/TextDrawable/screens/screen6.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
lib/TextDrawable/screens/screen7.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
4
lib/TextDrawable/settings.gradle
Normal file
@@ -0,0 +1,4 @@
|
||||
include ':sample'
|
||||
|
||||
include 'library'
|
||||
project(':library').projectDir = new File('library')
|
||||