parent
042099a6ef
commit
d35cfae97b
@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.hmkcode.drawing"
|
||||||
|
android:versionCode="1"
|
||||||
|
android:versionName="1.0" >
|
||||||
|
|
||||||
|
<uses-sdk
|
||||||
|
android:minSdkVersion="11"
|
||||||
|
android:targetSdkVersion="13" />
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:icon="@drawable/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:theme="@style/AppTheme"
|
||||||
|
android:hardwareAccelerated="false">e
|
||||||
|
<activity
|
||||||
|
android:name=".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>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 7.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 440 KiB |
@ -0,0 +1,26 @@
|
|||||||
|
<LinearLayout 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:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
|
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||||
|
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||||
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
|
tools:context="com.hmkcode.faces.MainActivity"
|
||||||
|
xmlns:faceview="http://schemas.android.com/apk/res/com.hmkcode.drawing"
|
||||||
|
android:background="@drawable/woodgraybg"
|
||||||
|
android:gravity="center"
|
||||||
|
>
|
||||||
|
|
||||||
|
<com.hmkcode.drawing.FaceView
|
||||||
|
android:id="@+id/fvHappy"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
faceview:radius="50dp"
|
||||||
|
android:layout_margin="5dp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:background="#80000000"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
<resources>
|
||||||
|
<declare-styleable name="FaceView">
|
||||||
|
<attr name="radius" format="dimension"/>
|
||||||
|
</declare-styleable>
|
||||||
|
</resources>
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
<resources>
|
||||||
|
|
||||||
|
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||||
|
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||||
|
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||||
|
|
||||||
|
</resources>
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<string name="app_name">DrawFace</string>
|
||||||
|
<string name="hello_world">Hello world!</string>
|
||||||
|
<string name="action_settings">Settings</string>
|
||||||
|
|
||||||
|
</resources>
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
<resources>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Base application theme, dependent on API level. This theme is replaced
|
||||||
|
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
|
||||||
|
-->
|
||||||
|
<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
|
||||||
|
<!--
|
||||||
|
Theme customizations available in newer API levels can go in
|
||||||
|
res/values-vXX/styles.xml, while customizations related to
|
||||||
|
backward-compatibility can go here.
|
||||||
|
-->
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Application theme. -->
|
||||||
|
<style name="AppTheme" parent="AppBaseTheme">
|
||||||
|
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
||||||
@ -0,0 +1,97 @@
|
|||||||
|
package com.hmkcode.drawing;
|
||||||
|
|
||||||
|
|
||||||
|
import com.hmkcode.drawing.shapes.Face;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
public class FaceView extends View {
|
||||||
|
private float radius;
|
||||||
|
Face face;
|
||||||
|
public FaceView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
|
||||||
|
// get radius value
|
||||||
|
TypedArray a = context.getTheme().obtainStyledAttributes(
|
||||||
|
attrs,
|
||||||
|
R.styleable.FaceView,
|
||||||
|
0, 0
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
radius = a.getDimension(R.styleable.FaceView_radius, 20.0f);
|
||||||
|
} finally {
|
||||||
|
a.recycle();
|
||||||
|
}
|
||||||
|
|
||||||
|
// initiate Face class
|
||||||
|
face = new Face(radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
face.draw(canvas);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
|
||||||
|
int desiredWidth = (int) radius*2+(int) Math.ceil((radius/1.70));
|
||||||
|
int desiredHeight = (int) radius*2+(int)Math.ceil((radius/1.70));
|
||||||
|
|
||||||
|
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
|
||||||
|
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
|
||||||
|
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||||
|
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
|
||||||
|
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
|
||||||
|
//Measure Width
|
||||||
|
if (widthMode == MeasureSpec.EXACTLY) {
|
||||||
|
//Must be this size
|
||||||
|
width = widthSize;
|
||||||
|
} else if (widthMode == MeasureSpec.AT_MOST) {
|
||||||
|
//Can't be bigger than...
|
||||||
|
width = Math.min(desiredWidth, widthSize);
|
||||||
|
Log.d("Width AT_MOST", "width: "+width);
|
||||||
|
} else {
|
||||||
|
//Be whatever you want
|
||||||
|
width = desiredWidth;
|
||||||
|
Log.d("Width ELSE", "width: "+width);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Measure Height
|
||||||
|
if (heightMode == MeasureSpec.EXACTLY) {
|
||||||
|
//Must be this size
|
||||||
|
height = heightSize;
|
||||||
|
} else if (heightMode == MeasureSpec.AT_MOST) {
|
||||||
|
//Can't be bigger than...
|
||||||
|
height = Math.min(desiredHeight, heightSize);
|
||||||
|
} else {
|
||||||
|
//Be whatever you want
|
||||||
|
height = desiredHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
//MUST CALL THIS
|
||||||
|
setMeasuredDimension(width, height);
|
||||||
|
}
|
||||||
|
public float getRadius() {
|
||||||
|
return radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRadius(float radius) {
|
||||||
|
this.radius = radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
package com.hmkcode.drawing;
|
||||||
|
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
|
||||||
|
public class MainActivity extends Activity {
|
||||||
|
|
||||||
|
protected void onCreate(android.os.Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_main);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,96 @@
|
|||||||
|
package com.hmkcode.drawing.shapes;
|
||||||
|
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.CornerPathEffect;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
|
||||||
|
public class Face {
|
||||||
|
|
||||||
|
Paint facePaint;
|
||||||
|
Paint mePaint;
|
||||||
|
|
||||||
|
|
||||||
|
float radius;
|
||||||
|
float adjust;
|
||||||
|
|
||||||
|
float mouthLeftX, mouthRightX, mouthTopY, mouthBottomY;
|
||||||
|
RectF mouthRectF;
|
||||||
|
Path mouthPath;
|
||||||
|
|
||||||
|
RectF eyeLeftRectF, eyeRightRectF;
|
||||||
|
float eyeLeftX, eyeRightx, eyeTopY, eyeBottomY;
|
||||||
|
|
||||||
|
|
||||||
|
public Face(float radius){
|
||||||
|
this.radius= radius;
|
||||||
|
|
||||||
|
facePaint = new Paint();
|
||||||
|
facePaint.setColor(0xfffed325); // yellow
|
||||||
|
facePaint.setDither(true);
|
||||||
|
facePaint.setStrokeJoin(Paint.Join.ROUND);
|
||||||
|
facePaint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
facePaint.setPathEffect(new CornerPathEffect(10) );
|
||||||
|
facePaint.setAntiAlias(true);
|
||||||
|
facePaint.setShadowLayer(4, 2, 2, 0x80000000);
|
||||||
|
|
||||||
|
mePaint = new Paint();
|
||||||
|
mePaint.setColor(0xff2a2a2a);
|
||||||
|
mePaint.setDither(true);
|
||||||
|
mePaint.setStyle(Paint.Style.STROKE);
|
||||||
|
mePaint.setStrokeJoin(Paint.Join.ROUND);
|
||||||
|
mePaint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
mePaint.setPathEffect(new CornerPathEffect(10) );
|
||||||
|
mePaint.setAntiAlias(true);
|
||||||
|
mePaint.setStrokeWidth(radius / 14.0f);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
adjust = radius / 3.2f;
|
||||||
|
|
||||||
|
|
||||||
|
// Left Eye
|
||||||
|
eyeLeftX = radius-(radius*0.43f);
|
||||||
|
eyeRightx = eyeLeftX+ (radius*0.3f);
|
||||||
|
eyeTopY = radius-(radius*0.5f);
|
||||||
|
eyeBottomY = eyeTopY + (radius*0.4f);
|
||||||
|
|
||||||
|
eyeLeftRectF = new RectF(eyeLeftX+adjust,eyeTopY+adjust,eyeRightx+adjust,eyeBottomY+adjust);
|
||||||
|
|
||||||
|
// Right Eye
|
||||||
|
eyeLeftX = eyeRightx + (radius*0.3f);
|
||||||
|
eyeRightx = eyeLeftX + (radius*0.3f);
|
||||||
|
|
||||||
|
eyeRightRectF = new RectF(eyeLeftX+adjust,eyeTopY+adjust,eyeRightx+adjust,eyeBottomY+adjust);
|
||||||
|
|
||||||
|
|
||||||
|
// Smiley Mouth
|
||||||
|
mouthLeftX = radius-(radius/2.0f);
|
||||||
|
mouthRightX = mouthLeftX+ radius;
|
||||||
|
mouthTopY = radius - (radius*0.2f);
|
||||||
|
mouthBottomY = mouthTopY + (radius*0.5f);
|
||||||
|
|
||||||
|
mouthRectF = new RectF(mouthLeftX+adjust,mouthTopY+adjust,mouthRightX+adjust,mouthBottomY+adjust);
|
||||||
|
mouthPath = new Path();
|
||||||
|
|
||||||
|
mouthPath.arcTo(mouthRectF, 30, 120, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void draw(Canvas canvas) {
|
||||||
|
|
||||||
|
// 1. draw face
|
||||||
|
canvas.drawCircle(radius+adjust, radius+adjust, radius, facePaint);
|
||||||
|
|
||||||
|
// 2. draw mouth
|
||||||
|
mePaint.setStyle(Paint.Style.STROKE);
|
||||||
|
|
||||||
|
canvas.drawPath(mouthPath, mePaint);
|
||||||
|
|
||||||
|
// 3. draw eyes
|
||||||
|
mePaint.setStyle(Paint.Style.FILL);
|
||||||
|
canvas.drawArc(eyeLeftRectF, 0, 360, true, mePaint);
|
||||||
|
canvas.drawArc(eyeRightRectF, 0, 360, true, mePaint);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue