diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 9d0d2a8..940be6c 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -12,6 +12,7 @@ <option value="$PROJECT_DIR$" /> <option value="$PROJECT_DIR$/app" /> <option value="$PROJECT_DIR$/library" /> + <option value="$PROJECT_DIR$/togaetherLib" /> </set> </option> <option name="resolveModulePerSourceSet" value="false" /> diff --git a/.idea/misc.xml b/.idea/misc.xml index fafeeed..54da72f 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -72,6 +72,9 @@ <entry key="..\:/Users/Yul2/AndroidStudioProjects/TOGAETHER/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml" value="0.4345" /> <entry key="..\:/Users/Yul2/AndroidStudioProjects/TOGAETHER/app/src/main/res/xml/custom_item.xml" value="0.3067708333333333" /> <entry key="..\:/Users/Yul2/AndroidStudioProjects/TOGAETHER/app/src/main/res/xml/network_security_config.xml" value="0.31302083333333336" /> + <entry key="..\:/Users/Yul2/AndroidStudioProjects/TOGAETHER/togaetherLib/src/main/res/drawable/cir_shadow.xml" value="0.2865" /> + <entry key="..\:/Users/Yul2/AndroidStudioProjects/TOGAETHER/togaetherLib/src/main/res/layout/activity_sample.xml" value="0.28229166666666666" /> + <entry key="..\:/Users/Yul2/AndroidStudioProjects/TOGAETHER/togaetherLib/src/main/res/layout/puppy_view.xml" value="0.28229166666666666" /> </map> </option> </component> diff --git a/app/build.gradle b/app/build.gradle index 578ea12..0a8fde0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -55,6 +55,7 @@ dependencies { implementation 'io.grpc:grpc-netty-shaded:1.46.0' implementation 'io.grpc:grpc-okhttp:1.46.0' implementation files('D:\\학교\\2022 1학기\\공소\\commons-net-3.6.jar') + implementation 'com.github.dcendents:android-maven-gradle-plugin:2.1' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' diff --git a/app/togaether/.gitignore b/app/togaether/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/togaether/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/togaether/build.gradle b/app/togaether/build.gradle new file mode 100644 index 0000000..7ab730c --- /dev/null +++ b/app/togaether/build.gradle @@ -0,0 +1,35 @@ +plugins { + id 'com.android.library' +} + +android { + compileSdk 32 + + defaultConfig { + minSdk 21 + targetSdk 32 + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + + implementation 'androidx.appcompat:appcompat:1.4.2' + implementation 'com.google.android.material:material:1.6.1' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' +} \ No newline at end of file diff --git a/app/togaether/consumer-rules.pro b/app/togaether/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/app/togaether/proguard-rules.pro b/app/togaether/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/togaether/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# 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 *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/togaether/src/androidTest/java/com/example/togaether/ExampleInstrumentedTest.java b/app/togaether/src/androidTest/java/com/example/togaether/ExampleInstrumentedTest.java new file mode 100644 index 0000000..1fb6eff --- /dev/null +++ b/app/togaether/src/androidTest/java/com/example/togaether/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.example.togaether; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.example.togaether.test", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/app/togaether/src/main/AndroidManifest.xml b/app/togaether/src/main/AndroidManifest.xml new file mode 100644 index 0000000..02da19c --- /dev/null +++ b/app/togaether/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.example.togaether"> + +</manifest> \ No newline at end of file diff --git a/app/togaether/src/test/java/com/example/togaether/ExampleUnitTest.java b/app/togaether/src/test/java/com/example/togaether/ExampleUnitTest.java new file mode 100644 index 0000000..0d7f5b5 --- /dev/null +++ b/app/togaether/src/test/java/com/example/togaether/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.example.togaether; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index ffac50d..697e9b1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -15,3 +15,4 @@ dependencyResolutionManagement { rootProject.name = "TOGAETHER" include ':app' include ':library' +include ':togaetherLib' diff --git a/togaetherLib/.gitignore b/togaetherLib/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/togaetherLib/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/togaetherLib/build.gradle b/togaetherLib/build.gradle new file mode 100644 index 0000000..4b0812d --- /dev/null +++ b/togaetherLib/build.gradle @@ -0,0 +1,43 @@ +apply plugin: 'com.github.dcendents.android-maven' +group='com.github.Yuls2' + +plugins { + id 'com.android.library' +} + +android { + compileSdk 32 + + defaultConfig { + minSdk 21 + targetSdk 32 + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + + implementation 'androidx.appcompat:appcompat:1.4.2' + implementation 'com.google.android.material:material:1.6.1' + implementation 'com.squareup.retrofit2:retrofit:2.9.0' + implementation 'com.squareup.retrofit2:converter-gson:2.9.0' + implementation 'com.github.bumptech.glide:glide:4.13.2' + implementation 'jp.wasabeef:glide-transformations:4.3.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' +} \ No newline at end of file diff --git a/togaetherLib/consumer-rules.pro b/togaetherLib/consumer-rules.pro new file mode 100644 index 0000000..e69de29 diff --git a/togaetherLib/proguard-rules.pro b/togaetherLib/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/togaetherLib/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# 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 *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/togaetherLib/src/androidTest/java/com/example/togaetherlib/ExampleInstrumentedTest.java b/togaetherLib/src/androidTest/java/com/example/togaetherlib/ExampleInstrumentedTest.java new file mode 100644 index 0000000..0433330 --- /dev/null +++ b/togaetherLib/src/androidTest/java/com/example/togaetherlib/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.example.togaetherlib; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.example.togaetherlib.test", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/togaetherLib/src/main/AndroidManifest.xml b/togaetherLib/src/main/AndroidManifest.xml new file mode 100644 index 0000000..4809586 --- /dev/null +++ b/togaetherLib/src/main/AndroidManifest.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.example.togaetherlib"> + + +</manifest> \ No newline at end of file diff --git a/togaetherLib/src/main/java/com/example/togaetherlib/CustomType.java b/togaetherLib/src/main/java/com/example/togaetherlib/CustomType.java new file mode 100644 index 0000000..36e6f8d --- /dev/null +++ b/togaetherLib/src/main/java/com/example/togaetherlib/CustomType.java @@ -0,0 +1,6 @@ +package com.example.togaetherlib; +//FACE2: 입 주변 털 등 +//FACE3: 무늬 +public enum CustomType { + EAR_L, EAR_R, EYE_L, EYE_R, EYEBROW_L, EYEBROW_R, FACE1, FACE2, FACE3, MOUTH, NOSE, BODY +} diff --git a/togaetherLib/src/main/java/com/example/togaetherlib/MaskTransformation2.java b/togaetherLib/src/main/java/com/example/togaetherlib/MaskTransformation2.java new file mode 100644 index 0000000..4de98ba --- /dev/null +++ b/togaetherLib/src/main/java/com/example/togaetherlib/MaskTransformation2.java @@ -0,0 +1,66 @@ +package com.example.togaetherlib; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; + +import jp.wasabeef.glide.transformations.MaskTransformation; + +public class MaskTransformation2 extends MaskTransformation { + private static final Paint paint = new Paint(); + + static { + paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); + } + Drawable maskD; + Bitmap maskB; + /** + * @param maskId If you change the mask file, please also rename the mask file, or Glide will get + * the cache with the old mask. Because key() return the same values if using the + * same make file name. If you have a good idea please tell us, thanks. + */ + public MaskTransformation2(int maskId) { + super(maskId); + } + + public MaskTransformation2(Drawable maskD) { + super(0); + this.maskD = maskD; + } + + public MaskTransformation2(Context con, Bitmap maskB) { + super(0); + this.maskB = maskB; + maskD = new BitmapDrawable(con.getResources(), maskB); + } + + protected Bitmap transform(@NonNull Context context, @NonNull BitmapPool pool, + @NonNull Bitmap toTransform, int outWidth, int outHeight) { + int width = toTransform.getWidth(); + int height = toTransform.getHeight(); + + Bitmap bitmap = pool.get(width, height, Bitmap.Config.ARGB_8888); + bitmap.setHasAlpha(true); + + Drawable mask = maskD; + + bitmap.setDensity(toTransform.getDensity()); + + Canvas canvas = new Canvas(bitmap); + mask.setBounds(0, 0, width, height); + mask.draw(canvas); + canvas.drawBitmap(toTransform, 0, 0, paint); + + return bitmap; + } + +} diff --git a/togaetherLib/src/main/java/com/example/togaetherlib/PuppyInfoItem.java b/togaetherLib/src/main/java/com/example/togaetherlib/PuppyInfoItem.java new file mode 100644 index 0000000..f22f8a0 --- /dev/null +++ b/togaetherLib/src/main/java/com/example/togaetherlib/PuppyInfoItem.java @@ -0,0 +1,162 @@ +package com.example.togaetherlib; + +import android.os.Build; + +import androidx.annotation.RequiresApi; + +import com.google.gson.annotations.SerializedName; + +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + +public class PuppyInfoItem { + @SerializedName("pid") + private int pid; + @SerializedName("uid") + private String uid; + @SerializedName("pname") + private String pname; + @SerializedName("psex") + private String psex; + @SerializedName("pcall") + private String pcall; + @SerializedName("pbdate") + private String pbdate; + @SerializedName("pshare") + private int pshare; + @SerializedName("pcustom") + private PuppyItem pcustom; + //visit info + @SerializedName("visit") + private boolean visit; + @SerializedName("vpid") + private int vpid; + @SerializedName("vname") + private String vname; + //more info + @SerializedName("uname") + private String uname; + @SerializedName("isFriend") + private boolean friend; + + public PuppyInfoItem(int pid, String uid, String pname, String psex, String pcall, String pbdate, int pshare, PuppyItem pcustom, boolean visit, int vpid) { + this.pid = pid; + this.uid = uid; + this.pname = pname; + this.psex = psex; + this.pcall = pcall; + this.pbdate = pbdate; + this.pshare = pshare; + this.pcustom = pcustom; + this.visit = visit; + this.vpid = vpid; + } + + public int getPid() { + return pid; + } + + public void setPid(int pid) { + this.pid = pid; + } + + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public String getPname() { + return pname; + } + + public void setPname(String pname) { + this.pname = pname; + } + + public String getPsex() { + return psex; + } + + public void setPsex(String psex) { + this.psex = psex; + } + + public String getPcall() { + return pcall; + } + + public void setPcall(String pcall) { + this.pcall = pcall; + } + + @RequiresApi(api = Build.VERSION_CODES.O) + public LocalDate getPbdate() { + LocalDate bdate = LocalDate.parse(pbdate, DateTimeFormatter.ISO_DATE); + return bdate; + } + + public void setPbdate(String pbdate) { + this.pbdate = pbdate; + } + + public int getPshare() { + return pshare; + } + + public void setPshare(int pshare) { + this.pshare = pshare; + } + + public PuppyItem getPcustom() { + return pcustom; + } + + public void setPcustom(PuppyItem pcustom) { + this.pcustom = pcustom; + } + + // visit info + + public boolean isVisit() { + return visit; + } + + public void setVisit(boolean visit) { + this.visit = visit; + } + + public int getVpid() { + return vpid; + } + + public void setVpid(int vpid) { + this.vpid = vpid; + } + + public String getVname() { + return vname; + } + + public void setVname(String vname) { + this.vname = vname; + } + + public String getUname() { + return uname; + } + + public void setUname(String uname) { + this.uname = uname; + } + + public boolean isFriend() { + return friend; + } + + public void setFriend(boolean friend) { + this.friend = friend; + } +} diff --git a/togaetherLib/src/main/java/com/example/togaetherlib/PuppyItem.java b/togaetherLib/src/main/java/com/example/togaetherlib/PuppyItem.java new file mode 100644 index 0000000..8fdbfeb --- /dev/null +++ b/togaetherLib/src/main/java/com/example/togaetherlib/PuppyItem.java @@ -0,0 +1,141 @@ +package com.example.togaetherlib; + +import com.google.gson.annotations.SerializedName; + +public class PuppyItem { + @SerializedName("FACE1") + private PuppyPartItem face1; + @SerializedName("FACE2") + private PuppyPartItem face2; + @SerializedName("FACE3") + private PuppyPartItem face3; + @SerializedName("BODY") + private PuppyPartItem body; + @SerializedName("MOUTH") + private PuppyPartItem mouth; + @SerializedName("NOSE") + private PuppyPartItem nose; + @SerializedName("EAR_L") + private PuppyPartItem ear_l; + @SerializedName("EAR_R") + private PuppyPartItem ear_r; + @SerializedName("EYE_L") + private PuppyPartItem eye_l; + @SerializedName("EYE_R") + private PuppyPartItem eye_r; + @SerializedName("EYEBROW_L") + private PuppyPartItem eyebrow_l; + @SerializedName("EYEBROW_R") + private PuppyPartItem eyebrow_r; + + public PuppyItem(PuppyPartItem face1, PuppyPartItem face2, PuppyPartItem face3, PuppyPartItem body, PuppyPartItem mouth, PuppyPartItem nose, PuppyPartItem ear_l, PuppyPartItem ear_r, PuppyPartItem eye_l, PuppyPartItem eye_r, PuppyPartItem eyebrow_l, PuppyPartItem eyebrow_r) { + this.face1 = face1; + this.face2 = face2; + this.face3 = face3; + this.body = body; + this.mouth = mouth; + this.nose = nose; + this.ear_l = ear_l; + this.ear_r = ear_r; + this.eye_l = eye_l; + this.eye_r = eye_r; + this.eyebrow_l = eyebrow_l; + this.eyebrow_r = eyebrow_r; + } + + public PuppyPartItem getBody() { + return body; + } + + public PuppyPartItem getEar_l() { + return ear_l; + } + + public PuppyPartItem getEar_r() { + return ear_r; + } + + public PuppyPartItem getEye_l() { + return eye_l; + } + + public PuppyPartItem getEye_r() { + return eye_r; + } + + public PuppyPartItem getEyebrow_l() { + return eyebrow_l; + } + + public PuppyPartItem getEyebrow_r() { + return eyebrow_r; + } + + public PuppyPartItem getFace1() { + return face1; + } + + public PuppyPartItem getFace2() { + return face2; + } + + public PuppyPartItem getFace3() { + return face3; + } + + public PuppyPartItem getMouth() { + return mouth; + } + + public PuppyPartItem getNose() { + return nose; + } + + public void setBody(PuppyPartItem body) { + this.body = body; + } + + public void setEar_l(PuppyPartItem ear_l) { + this.ear_l = ear_l; + } + + public void setEar_r(PuppyPartItem ear_r) { + this.ear_r = ear_r; + } + + public void setEye_l(PuppyPartItem eye_l) { + this.eye_l = eye_l; + } + + public void setEye_r(PuppyPartItem eye_r) { + this.eye_r = eye_r; + } + + public void setEyebrow_l(PuppyPartItem eyebrow_l) { + this.eyebrow_l = eyebrow_l; + } + + public void setEyebrow_r(PuppyPartItem eyebrow_r) { + this.eyebrow_r = eyebrow_r; + } + + public void setFace1(PuppyPartItem face1) { + this.face1 = face1; + } + + public void setFace2(PuppyPartItem face2) { + this.face2 = face2; + } + + public void setFace3(PuppyPartItem face3) { + this.face3 = face3; + } + + public void setMouth(PuppyPartItem mouth) { + this.mouth = mouth; + } + + public void setNose(PuppyPartItem nose) { + this.nose = nose; + } +} diff --git a/togaetherLib/src/main/java/com/example/togaetherlib/PuppyPartItem.java b/togaetherLib/src/main/java/com/example/togaetherlib/PuppyPartItem.java new file mode 100644 index 0000000..1432165 --- /dev/null +++ b/togaetherLib/src/main/java/com/example/togaetherlib/PuppyPartItem.java @@ -0,0 +1,64 @@ +package com.example.togaetherlib; + +import com.google.gson.annotations.SerializedName; + +public class PuppyPartItem { + @SerializedName("source") + private String source; + @SerializedName("dy") + private int dy; + @SerializedName("dist") + private int dist; + @SerializedName("size") + private int size; + @SerializedName("color") + private int color; + + public PuppyPartItem(String source, int dy, int dist, int size, int color) { + this.source = source; + this.dy = dy; + this.dist = dist; + this.size = size; + this.color = color; + } + + public void setColor(int color) { + this.color = color; + } + + public void setDist(int dist) { + this.dist = dist; + } + + public void setDy(int dy) { + this.dy = dy; + } + + public void setSize(int size) { + this.size = size; + } + + public void setSource(String source) { + this.source = source; + } + + public int getColor() { + return color; + } + + public int getDist() { + return dist; + } + + public int getDy() { + return dy; + } + + public int getSize() { + return size; + } + + public String getSource() { + return source; + } +} diff --git a/togaetherLib/src/main/java/com/example/togaetherlib/PuppyView.java b/togaetherLib/src/main/java/com/example/togaetherlib/PuppyView.java new file mode 100644 index 0000000..0cfd3b0 --- /dev/null +++ b/togaetherLib/src/main/java/com/example/togaetherlib/PuppyView.java @@ -0,0 +1,559 @@ +package com.example.togaetherlib; + +import static com.bumptech.glide.request.RequestOptions.bitmapTransform; + +import android.animation.ValueAnimator; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.util.Log; +import android.util.TypedValue; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.widget.ImageView; +import android.widget.ProgressBar; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.load.DataSource; +import com.bumptech.glide.load.MultiTransformation; +import com.bumptech.glide.load.engine.DiskCacheStrategy; +import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.load.resource.bitmap.CenterCrop; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.target.Target; + +import java.time.LocalDate; +import java.util.HashMap; +import java.util.Random; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +public class PuppyView { + LayoutInflater layoutInflater; + AppCompatActivity act; + View puppyView, puppy, vShadow, puppyOnly; + ProgressBar pgPuppy; + + HashMap<CustomType, ImageView> imgMap = new HashMap<>(); + ImageView eyeWL, eyeWR; + HashMap<CustomType, PartXY> xyMap = new HashMap<>(); + HashMap<CustomType, Integer> dyMap = new HashMap<>(); + HashMap<CustomType, Integer> distMap = new HashMap<>(); + HashMap<CustomType, Integer> sizeMap = new HashMap<>(); + HashMap<CustomType, Integer> colorMap = new HashMap<>(); + HashMap<CustomType, String> sourceMap = new HashMap<>(); + int w, h; + int oriS; + ViewGroup lay; + boolean isSleep = false; + + + private String name, callString, sex, uid; + private int id; + private LocalDate bdate; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public LocalDate getBdate() { + return bdate; + } + public void setBdate(LocalDate bdate) { + this.bdate = bdate; + } + public String getCallString() { + return callString; + } + public void setCallString(String callString) { + this.callString = callString; + } + public String getSex() { + return sex; + } + public void setSex(String sex) { + this.sex = sex; + } + public String getUid() { + return uid; + } + public void setUid(String uid) { + this.uid = uid; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + PuppyView(ViewGroup lay, AppCompatActivity act) { + setInit(lay, act, 1); + setInitCustom(); + pgPuppy.setVisibility(View.GONE); + } + + PuppyView(ViewGroup lay, AppCompatActivity act, int id) { + setInit(lay, act, 1); + setId(id); + setInitCustom(id); + } + + PuppyView(ViewGroup lay, AppCompatActivity act, PuppyItem item, float scale) { + setInit(lay, act, scale); + setInitCustom(item); + } + + PuppyView(ViewGroup lay, AppCompatActivity act, PuppyInfoItem item, float scale) { + setInit(lay, act, scale); + setName(item.getPname()); + setCallString(item.getPcall()); + setSex(item.getPsex()); + setUid(item.getUid()); + setBdate(item.getPbdate()); + setId(item.getPid()); + setInitCustom(item.getPcustom()); + } + + PuppyView(ViewGroup lay, AppCompatActivity act, PuppyInfoItem item) { + this(lay, act, item, 1); + } + + PuppyView(ViewGroup lay, AppCompatActivity act, PuppyItem item) { + this(lay, act, item, 1); + } + + + public void setInit(ViewGroup lay, AppCompatActivity act, float scale) { + this.lay = lay; + this.act = act; + layoutInflater = (LayoutInflater) act.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + puppyView = (View) layoutInflater.inflate(R.layout.puppy_view, lay, false); + lay.addView(puppyView); + puppy = puppyView.findViewById(R.id.lay_puppy); + puppyOnly = puppy.findViewById(R.id.lay_puppy_only); + pgPuppy = puppy.findViewById(R.id.pg_puppy); + + puppy.setScaleX(scale); + puppy.setScaleY(scale); + + oriS = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 100, act.getResources().getDisplayMetrics()); + + imgMap.put(CustomType.FACE1,(ImageView) puppy.findViewById(R.id.img_face1)); + imgMap.put(CustomType.FACE2,(ImageView) puppy.findViewById(R.id.img_face2)); + imgMap.put(CustomType.FACE3,(ImageView) puppy.findViewById(R.id.img_face3)); + imgMap.put(CustomType.BODY,(ImageView) puppy.findViewById(R.id.img_body)); + imgMap.put(CustomType.MOUTH,(ImageView) puppy.findViewById(R.id.img_mouth)); + imgMap.put(CustomType.NOSE,(ImageView) puppy.findViewById(R.id.img_nose)); + imgMap.put(CustomType.EAR_L,(ImageView) puppy.findViewById(R.id.img_ear_left)); + imgMap.put(CustomType.EAR_R,(ImageView) puppy.findViewById(R.id.img_ear_right)); + imgMap.put(CustomType.EYE_L,(ImageView) puppy.findViewById(R.id.img_eye_left)); + imgMap.put(CustomType.EYE_R,(ImageView) puppy.findViewById(R.id.img_eye_right)); + imgMap.put(CustomType.EYEBROW_L,(ImageView) puppy.findViewById(R.id.img_eyebrow_left)); + imgMap.put(CustomType.EYEBROW_R,(ImageView) puppy.findViewById(R.id.img_eyebrow_right)); + vShadow = (View) puppy.findViewById(R.id.v_shadow); + eyeWL = (ImageView) puppy.findViewById(R.id.img_eyew_left); + eyeWR = (ImageView) puppy.findViewById(R.id.img_eyew_right); + + for(CustomType t: CustomType.values()) { + ImageView targetView = imgMap.get(t); + xyMap.put(t,new PartXY(targetView.getX(),targetView.getY())); + } + + puppy.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + w = puppy.getWidth(); + h = puppy.getHeight(); + //oriS = imgMap.get(CustomType.FACE1).getWidth(); + puppy.setTranslationX(puppy.getX() - w/2); + puppy.setTranslationY(puppy.getY() - h/2); + puppy.setPivotX((float) w/2); + puppy.setPivotY((float) h*3/4); + + final ValueAnimator bubbleAnim = ValueAnimator.ofFloat(-0.25f, 0.25f); + bubbleAnim.setDuration(1000); + bubbleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + puppy.setScaleY(puppy.getScaleX()-(float) animation.getAnimatedValue()/20); + } + }); + bubbleAnim.setRepeatCount(-1); + bubbleAnim.setRepeatMode(ValueAnimator.REVERSE); + bubbleAnim.start(); + + puppy.getViewTreeObserver().removeOnGlobalLayoutListener(this); + } + }); + + puppy.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Random rand = new Random(); + Float rate = rand.nextFloat()+0.7F; + final ValueAnimator anim = ValueAnimator.ofFloat(-puppy.getScaleX()*0.5f, puppy.getScaleX()*0.5f); + anim.setDuration((int)(200/rate)); + anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + puppy.setScaleY(puppy.getScaleX()-(float) animation.getAnimatedValue()/20); + } + }); + anim.setRepeatCount(2); + anim.setRepeatMode(ValueAnimator.REVERSE); + anim.start(); + } + }); + } + //커스터마이징 화면에서 초기화 + public void setInitCustom() { + sourceMap.put(CustomType.FACE1,"https://togaether.cafe24.com/images/custom/img_cus_f1_1.png"); + sourceMap.put(CustomType.FACE2,"https://togaether.cafe24.com/images/custom/img_cus_none.png"); + sourceMap.put(CustomType.FACE3,"https://togaether.cafe24.com/images/custom/img_cus_none.png"); + sourceMap.put(CustomType.BODY,"https://togaether.cafe24.com/images/custom/img_cus_body_1.png"); + sourceMap.put(CustomType.MOUTH,"https://togaether.cafe24.com/images/custom/img_cus_mouth_1.png"); + sourceMap.put(CustomType.NOSE,"https://togaether.cafe24.com/images/custom/img_cus_nose_1.png"); + sourceMap.put(CustomType.EAR_L,"https://togaether.cafe24.com/images/custom/img_cus_ear_1.png"); + sourceMap.put(CustomType.EAR_R,"https://togaether.cafe24.com/images/custom/img_cus_ear_1.png"); + sourceMap.put(CustomType.EYE_L,"https://togaether.cafe24.com/images/custom/img_cus_eye_1.png"); + sourceMap.put(CustomType.EYE_R,"https://togaether.cafe24.com/images/custom/img_cus_eye_1.png"); + sourceMap.put(CustomType.EYEBROW_L,"https://togaether.cafe24.com/images/custom/img_cus_none.png"); + sourceMap.put(CustomType.EYEBROW_R,"https://togaether.cafe24.com/images/custom/img_cus_none.png"); + + Glide.with(lay).load(sourceMap.get(CustomType.FACE3)) + .diskCacheStrategy(DiskCacheStrategy.NONE) + .skipMemoryCache(true) + .apply(bitmapTransform(new MultiTransformation<Bitmap>(new CenterCrop(), new MaskTransformation2(imgMap.get(CustomType.FACE1).getDrawable())))).into(imgMap.get(CustomType.FACE3)); + + for(CustomType t: CustomType.values()) { + ImageView targetView = imgMap.get(t); + dyMap.put(t,0); + distMap.put(t,0); + sizeMap.put(t,100); + colorMap.put(t,Color.parseColor("#ffffff")); + xyMap.put(t,new PartXY(targetView.getX(),targetView.getY())); + } + colorMap.put(CustomType.FACE2,Color.parseColor("#e6e6e6")); + colorMap.put(CustomType.FACE3,Color.parseColor("#6e6e6e")); + colorMap.put(CustomType.EYEBROW_L,Color.parseColor("#6e6e6e")); + colorMap.put(CustomType.EYEBROW_R,Color.parseColor("#6e6e6e")); + colorMap.put(CustomType.EAR_L,Color.parseColor("#452d00")); + colorMap.put(CustomType.EAR_R,Color.parseColor("#452d00")); + colorMap.put(CustomType.EYE_L,Color.parseColor("#000000")); + colorMap.put(CustomType.EYE_R,Color.parseColor("#000000")); + + //색상 초기화 + for(CustomType t: CustomType.values()) { + setColor(t, colorMap.get(t)); + } + } + //id로 가져와서 초기화 + public void setInitCustom(int id) { + Retrofit retrofit = new Retrofit.Builder() + .baseUrl("http://togaether.cafe24.com") + .addConverterFactory(GsonConverterFactory.create()) + .build(); + RetrofitPuppy retrofitAPI = retrofit.create(RetrofitPuppy.class); + //HashMap<String, Object> input = new HashMap<>(); + retrofitAPI.getData(id).enqueue(new Callback<PuppyInfoItem>() { + @Override + public void onResponse(Call<PuppyInfoItem> call, Response<PuppyInfoItem> response) { + if(response.isSuccessful()) { + PuppyInfoItem data = response.body(); + if(data.getPid() != -1) { + setName(data.getPname()); + setCallString(data.getPcall()); + setSex(data.getPsex()); + setUid(data.getUid()); + setBdate(data.getPbdate()); + setId(data.getPid()); + setInitCustom(data.getPcustom()); + } + else { + //error + } + } + } + + @Override + public void onFailure(Call<PuppyInfoItem> call, Throwable t) { + Log.e("=========OMG","here" + t); + } + }); + } + //PuppyItem 받아서 초기화 + public void setInitCustom(PuppyItem data) { + PuppyPartItem partData[] = {data.getEar_l(), data.getEar_r(), data.getEye_l(), data.getEye_r(), data.getEyebrow_l(), data.getEyebrow_r(), data.getFace1(), data.getFace2(), data.getFace3(), data.getMouth(), data.getNose(), data.getBody()}; + // EAR_L, EAR_R, EYE_L, EYE_R, EYEBROW_L, EYEBROW_R, FACE1, FACE2, FACE3, MOUTH, NOSE, BODY + int i = 0; + for(CustomType t: CustomType.values()) { + setMap(t, partData[i++]); + } + i = 0; + for(CustomType t: CustomType.values()) { + setCustom(t, partData[i++]); + } + } + private void setMap(CustomType t, PuppyPartItem item) { + dyMap.put(t,item.getDy()); + distMap.put(t,-item.getDist()); + sizeMap.put(t,item.getSize()); + colorMap.put(t,item.getColor()); + sourceMap.put(t,item.getSource()); + } + + private void setCustom(CustomType t, PuppyPartItem item) { + if(t!=CustomType.FACE3 || (!isSleep && (t==CustomType.EYE_L || t==CustomType.EYE_R))) { + setImgSource(t, item.getSource()); + } + setSize(t, item.getSize()); + setDy(t, item.getDy()); + setColor(t, item.getColor()); + setPartPosition(t); + if(t==CustomType.EAR_L || t==CustomType.EYE_L || t==CustomType.EYEBROW_L) { + setDist(t, -item.getDist()); + } + } + + public void setPosition(int x, int y) { + puppy.setTranslationX((int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, x, act.getResources().getDisplayMetrics()) - w/2); //puppy.findViewById(R.id.lay_puppy). + puppy.setTranslationY((int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, y, act.getResources().getDisplayMetrics()) - h/2); + } + public void setPositionPXX(float x) { + float x60 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60, act.getResources().getDisplayMetrics()); + puppy.setTranslationX(x - x60); + } + public void setPositionPXY(float y) { + float y142 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 142.5f, act.getResources().getDisplayMetrics()); + puppy.setTranslationY(y - y142); + } + public float getPositionPXX() { + return puppy.getX() + w/2; + } + public float getPositionPXY() { + return puppy.getY(); + } + public void setPositionPX(int x, int y) { + puppy.setTranslationX(x - w/2); + puppy.setTranslationY(y - h/2); + } + public void setColor(CustomType type, int color) { + imgMap.get(type).setColorFilter(color, PorterDuff.Mode.MULTIPLY); + colorMap.put(type,color); + } + public void setImgSource(CustomType type, String url) { + sourceMap.put(type, url); + if(type == CustomType.FACE1) { + pgPuppy.setVisibility(View.VISIBLE); + puppyOnly.setVisibility(View.GONE); + Glide.with(lay).load(url) + .listener(new RequestListener<Drawable>() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { + pgPuppy.setVisibility(View.GONE); + puppyOnly.setVisibility(View.VISIBLE); + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { + Glide.with(lay).load(sourceMap.get(CustomType.FACE3)) + .listener(new RequestListener<Drawable>() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { + pgPuppy.setVisibility(View.GONE); + puppyOnly.setVisibility(View.VISIBLE); + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { + pgPuppy.setVisibility(View.GONE); + puppyOnly.setVisibility(View.VISIBLE); + return false; + } + }) + .diskCacheStrategy(DiskCacheStrategy.NONE) + .skipMemoryCache(true) + .apply(bitmapTransform(new MultiTransformation<Bitmap>(new CenterCrop(), new MaskTransformation2(resource)))).into(imgMap.get(CustomType.FACE3)); + return false; + } + }) + .into(imgMap.get(type)); + } + else if(type == CustomType.FACE3) { + Glide.with(lay).load(url) + .diskCacheStrategy(DiskCacheStrategy.NONE) + .skipMemoryCache(true) + .apply(bitmapTransform(new MultiTransformation<Bitmap>(new CenterCrop(), new MaskTransformation2(imgMap.get(CustomType.FACE1).getDrawable())))).into(imgMap.get(CustomType.FACE3)); + } + else { + Glide.with(lay).load(url).into(imgMap.get(type)); + if (type == CustomType.EYE_L) + Glide.with(lay).load(url.replace("eye","eyew")).into(eyeWL); + if (type == CustomType.EYE_R) + Glide.with(lay).load(url.replace("eye","eyew")).into(eyeWR); + } + } + public void setSize(CustomType type, int size) { + int s = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, size, act.getResources().getDisplayMetrics()); + ImageView targetView = imgMap.get(type); + ViewGroup.LayoutParams newSize = targetView.getLayoutParams(); + newSize.width = s; + newSize.height = s; + targetView.setLayoutParams(newSize); + sizeMap.put(type, size); + setPartPosition(type); + if (type == CustomType.EYE_L) { + eyeWL.setLayoutParams(newSize); + } + else if (type == CustomType.EYE_R) { + eyeWR.setLayoutParams(newSize); + } + } + public void setCSize(CustomType type, int size) { + setSize(type, size); + if(type == CustomType.FACE1) { + setSize(CustomType.FACE3, size); + sizeMap.put(CustomType.FACE3, size); + setPartPosition(CustomType.FACE3); + } + } + public void setDy(CustomType type, int dy) { + dyMap.put(type, dy); + setPartPosition(type); + } + public void setCDy(CustomType type, int dy) { + // dDy, preDy는 FACE1 움직일 때 따라 움직이는 애들 용 + int dDy, preDy = dyMap.get(type); + setDy(type, dy); + dDy = dy - preDy; + if(type == CustomType.FACE1) { + CustomType[] ts = {CustomType.FACE2, CustomType.FACE3, CustomType.EAR_L, CustomType.EAR_R, CustomType.NOSE, CustomType.MOUTH, CustomType.EYE_L, CustomType.EYE_R, CustomType.EYEBROW_L, CustomType.EYEBROW_R}; + for(CustomType t: ts) { + dyMap.put(t, dyMap.get(t) + dDy); + setPartPosition(t); + } + } + } + // 왼쪽 타입에만 적용 + public void setDist(CustomType type, int dist) { + distMap.put(type, -dist); + setPartPosition(type); + CustomType targetType = CustomType.valueOf(type.name().substring(0, type.name().length() - 1) + "R"); + distMap.put(targetType, dist); + setPartPosition(targetType); + } + public void setPartPosition(CustomType type) { + int size = sizeMap.get(type); + int s = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, size, act.getResources().getDisplayMetrics()); + float dy = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dyMap.get(type), act.getResources().getDisplayMetrics()); + float dist = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, distMap.get(type), act.getResources().getDisplayMetrics()); + + ImageView targetView = imgMap.get(type); + targetView.setTranslationX(xyMap.get(type).getX() + dist - (float)(s - oriS)/2); + + float tempYCenter; + if(type == CustomType.BODY) { tempYCenter = (float)(s - oriS)*3/4; } + else { tempYCenter = (float)(s - oriS)/2; } + + targetView.setTranslationY(xyMap.get(type).getY() + dy - tempYCenter); + if(type == CustomType.EYE_L || type == CustomType.EYE_R) { + eyeWL.setTranslationX(imgMap.get(CustomType.EYE_L).getX()); + eyeWL.setTranslationY(imgMap.get(CustomType.EYE_L).getY()); + + eyeWR.setTranslationX(imgMap.get(CustomType.EYE_R).getX()); + eyeWR.setTranslationY(imgMap.get(CustomType.EYE_R).getY()); + } + + if(type == CustomType.BODY) { + float _dy = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 65, act.getResources().getDisplayMetrics()); + vShadow.setTranslationY(imgMap.get(CustomType.BODY).getY() + tempYCenter + _dy); + } + } + public String getCustomJSON() { + String jString = "{"; + for(CustomType t: CustomType.values()) { + jString += "\"" + t.name() + "\":"; + jString += "{"; + jString += "\"source\":" + "\"" + sourceMap.get(t) + "\","; + jString += "\"dy\":" + dyMap.get(t) + ","; + jString += "\"dist\":" + distMap.get(t) + ","; + jString += "\"size\":" + sizeMap.get(t) + ","; + jString += "\"color\":" + colorMap.get(t); + jString += "}"; + if(t != CustomType.BODY) { jString += ","; } + } + jString += "}"; + return jString; + } + + public void setSleep(boolean isSleep){ + this.isSleep = isSleep; + if(isSleep) { + setImgSource(CustomType.EYE_L, "http://togaether.cafe24.com/images/custom/img_cus_eye_0_sleep.png"); + setImgSource(CustomType.EYE_R, "http://togaether.cafe24.com/images/custom/img_cus_eye_0_sleep.png"); + } + else { + //setImgSource(CustomType.EYE_L, sourceMap.get(CustomType.EYE_L)); + //setImgSource(CustomType.EYE_R, sourceMap.get(CustomType.EYE_R)); + } + } + + public float pxToDp(Context context, float px) { + + // 해상도 마다 다른 density 를 반환. xxxhdpi는 density = 4 + float density = context.getResources().getDisplayMetrics().density; + + if (density == 1.0) // mpdi (160dpi) -- xxxhdpi (density = 4)기준으로 density 값을 재설정 한다 + density *= 4.0; + else if (density == 1.5) // hdpi (240dpi) + density *= (8 / 3); + else if (density == 2.0) // xhdpi (320dpi) + density *= 2.0; + + return px / density; // dp 값 반환 + } +} + +class PartXY{ + private float x, y; + + public PartXY(float x, float y){ + this.x = x; + this.y = y; + } + + public float getX() { + return x; + } + + public float getY() { + return y; + } + + public void setX(float x) { + this.x = x; + } + + public void setY(float y) { + this.y = y; + } +} \ No newline at end of file diff --git a/togaetherLib/src/main/java/com/example/togaetherlib/RetrofitPuppy.java b/togaetherLib/src/main/java/com/example/togaetherlib/RetrofitPuppy.java new file mode 100644 index 0000000..3a5cfff --- /dev/null +++ b/togaetherLib/src/main/java/com/example/togaetherlib/RetrofitPuppy.java @@ -0,0 +1,48 @@ +package com.example.togaetherlib; + +import java.util.HashMap; +import java.util.List; + +import okhttp3.ResponseBody; +import retrofit2.Call; +import retrofit2.http.FieldMap; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.POST; +import retrofit2.http.Query; + +public interface RetrofitPuppy { + @POST("/puppyListForPid.php") + Call<PuppyInfoItem> getData(@Query("pid") int id); + + @FormUrlEncoded + @POST("/puppyInfoForPid.php") + Call<PuppyInfoItem> getMoreInfo(@FieldMap HashMap<String, Object> param); + + @FormUrlEncoded + @POST("/test.json") + Call<PuppyItem> postData(@FieldMap HashMap<String, Object> param); + + @FormUrlEncoded + @POST("/puppyInsert.php") + Call<ResponseBody> insertPuppy(@FieldMap HashMap<String, Object> param); + + @FormUrlEncoded + @POST("/puppyListForUid.php") + Call<List<PuppyInfoItem>> getPuppyListById(@FieldMap HashMap<String, Object> param); + + @FormUrlEncoded + @POST("/puppyFriendList.php") + Call<List<PuppyInfoItem>> getPuppyFriendList(@FieldMap HashMap<String, Object> param); + + @FormUrlEncoded + @POST("/puppyListForRandom.php") + Call<PuppyInfoItem> getVisitPuppy(@FieldMap HashMap<String, Object> param); + + @FormUrlEncoded + @POST("/puppySetFriend.php") + Call<ResponseBody> setFriend(@FieldMap HashMap<String, Object> param); + + @FormUrlEncoded + @POST("/puppyListForAddrPid.php") + Call<List<PuppyInfoItem>> getPuppyListByAddrPid(@FieldMap HashMap<String, Object> param); +} diff --git a/togaetherLib/src/main/res/drawable/cir_shadow.xml b/togaetherLib/src/main/res/drawable/cir_shadow.xml new file mode 100644 index 0000000..34f7659 --- /dev/null +++ b/togaetherLib/src/main/res/drawable/cir_shadow.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> + <solid android:color="#5B000000"/> + <size android:width="100dp" android:height="25dp"/> +</shape> \ No newline at end of file diff --git a/togaetherLib/src/main/res/drawable/img_cus_body_1.png b/togaetherLib/src/main/res/drawable/img_cus_body_1.png new file mode 100644 index 0000000..879d7f0 Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_body_1.png differ diff --git a/togaetherLib/src/main/res/drawable/img_cus_ear_1.png b/togaetherLib/src/main/res/drawable/img_cus_ear_1.png new file mode 100644 index 0000000..6780664 Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_ear_1.png differ diff --git a/togaetherLib/src/main/res/drawable/img_cus_eye_1.png b/togaetherLib/src/main/res/drawable/img_cus_eye_1.png new file mode 100644 index 0000000..5bbf2e6 Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_eye_1.png differ diff --git a/togaetherLib/src/main/res/drawable/img_cus_eyebrow_1.png b/togaetherLib/src/main/res/drawable/img_cus_eyebrow_1.png new file mode 100644 index 0000000..8cd9a6e Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_eyebrow_1.png differ diff --git a/togaetherLib/src/main/res/drawable/img_cus_eyew_1.png b/togaetherLib/src/main/res/drawable/img_cus_eyew_1.png new file mode 100644 index 0000000..b8c60bf Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_eyew_1.png differ diff --git a/togaetherLib/src/main/res/drawable/img_cus_f1_1.png b/togaetherLib/src/main/res/drawable/img_cus_f1_1.png new file mode 100644 index 0000000..565c34c Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_f1_1.png differ diff --git a/togaetherLib/src/main/res/drawable/img_cus_f2_1.png b/togaetherLib/src/main/res/drawable/img_cus_f2_1.png new file mode 100644 index 0000000..40805ff Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_f2_1.png differ diff --git a/togaetherLib/src/main/res/drawable/img_cus_f3_1.png b/togaetherLib/src/main/res/drawable/img_cus_f3_1.png new file mode 100644 index 0000000..1387e25 Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_f3_1.png differ diff --git a/togaetherLib/src/main/res/drawable/img_cus_mouth_1.png b/togaetherLib/src/main/res/drawable/img_cus_mouth_1.png new file mode 100644 index 0000000..dc512c7 Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_mouth_1.png differ diff --git a/togaetherLib/src/main/res/drawable/img_cus_none.png b/togaetherLib/src/main/res/drawable/img_cus_none.png new file mode 100644 index 0000000..cfad488 Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_none.png differ diff --git a/togaetherLib/src/main/res/drawable/img_cus_nose_1.png b/togaetherLib/src/main/res/drawable/img_cus_nose_1.png new file mode 100644 index 0000000..cfeb5e8 Binary files /dev/null and b/togaetherLib/src/main/res/drawable/img_cus_nose_1.png differ diff --git a/togaetherLib/src/main/res/layout/puppy_view.xml b/togaetherLib/src/main/res/layout/puppy_view.xml new file mode 100644 index 0000000..80ceabf --- /dev/null +++ b/togaetherLib/src/main/res/layout/puppy_view.xml @@ -0,0 +1,166 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout 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" + android:layout_width="120dp" + android:layout_height="190dp" + android:id="@+id/lay_puppy" + tools:ignore="InvalidId"> + <ProgressBar + android:id="@+id/pg_puppy" + android:layout_width="match_parent" + android:layout_height="match_parent"/> + + <androidx.constraintlayout.widget.ConstraintLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:id="@+id/lay_puppy_only"> + + <View + android:id="@+id/v_shadow" + android:layout_width="100dp" + android:layout_height="25dp" + android:translationY="125dp" + android:translationX="10dp" + android:background="@drawable/cir_shadow" + tools:ignore="MissingConstraints" /> + + <ImageView + android:id="@+id/img_body" + android:layout_width="100dp" + android:layout_height="100dp" + android:translationY="60dp" + android:translationX="10dp" + app:srcCompat="@drawable/img_cus_body_1" + tools:ignore="MissingConstraints" + tools:layout_editor_absoluteX="0dp" /> + + <ImageView + android:id="@+id/img_face1" + android:layout_width="100dp" + android:layout_height="100dp" + android:translationY="20dp" + android:translationX="10dp" + app:srcCompat="@drawable/img_cus_f1_1" + tools:ignore="MissingConstraints" /> + + <ImageView + android:id="@+id/img_face3" + android:layout_width="100dp" + android:layout_height="100dp" + android:translationY="20dp" + android:translationX="10dp" + app:srcCompat="@drawable/img_cus_none" + tools:ignore="MissingConstraints" /> + + <ImageView + android:id="@+id/img_mouth" + android:layout_width="100dp" + android:layout_height="100dp" + android:translationY="40dp" + android:translationX="10dp" + app:srcCompat="@drawable/img_cus_mouth_1" + tools:ignore="MissingConstraints" /> + + <ImageView + android:id="@+id/img_eye_left" + android:layout_width="100dp" + android:layout_height="100dp" + android:translationX="-5dp" + android:translationY="15dp" + app:srcCompat="@drawable/img_cus_eye_1" + tools:ignore="MissingConstraints" + tools:layout_editor_absoluteX="0dp" /> + + <ImageView + android:id="@+id/img_eye_right" + android:layout_width="100dp" + android:layout_height="100dp" + android:translationX="25dp" + android:translationY="15dp" + android:scaleX="-1" + app:srcCompat="@drawable/img_cus_eye_1" + tools:ignore="MissingConstraints" + tools:layout_editor_absoluteX="0dp" /> + + <ImageView + android:id="@+id/img_eyew_left" + android:layout_width="100dp" + android:layout_height="100dp" + android:translationX="-5dp" + android:translationY="15dp" + app:srcCompat="@drawable/img_cus_eyew_1" + tools:ignore="MissingConstraints" + tools:layout_editor_absoluteX="0dp" /> + + <ImageView + android:id="@+id/img_eyew_right" + android:layout_width="100dp" + android:layout_height="100dp" + android:translationX="25dp" + android:translationY="15dp" + app:srcCompat="@drawable/img_cus_eyew_1" + tools:ignore="MissingConstraints" + tools:layout_editor_absoluteX="0dp" /> + + <ImageView + android:id="@+id/img_face2" + android:layout_width="100dp" + android:layout_height="100dp" + android:translationY="35dp" + android:translationX="10dp" + app:srcCompat="@drawable/img_cus_none" + tools:ignore="MissingConstraints" /> + + <ImageView + android:id="@+id/img_nose" + android:layout_width="100dp" + android:layout_height="100dp" + android:translationY="30dp" + android:translationX="10dp" + app:srcCompat="@drawable/img_cus_nose_1" + tools:ignore="MissingConstraints" + tools:layout_editor_absoluteX="0dp" /> + + <ImageView + android:id="@+id/img_eyebrow_left" + android:layout_width="100dp" + android:layout_height="100dp" + android:translationY="8dp" + android:translationX="-10dp" + app:srcCompat="@drawable/img_cus_none" + tools:ignore="MissingConstraints" /> + + <ImageView + android:id="@+id/img_eyebrow_right" + android:layout_width="100dp" + android:layout_height="100dp" + android:translationY="8dp" + android:translationX="30dp" + app:srcCompat="@drawable/img_cus_none" + android:scaleX="-1" + tools:ignore="MissingConstraints" /> + + <ImageView + android:id="@+id/img_ear_left" + android:layout_width="100dp" + android:layout_height="100dp" + android:translationX="-15dp" + android:translationY="-10dp" + app:srcCompat="@drawable/img_cus_ear_1" + tools:ignore="MissingConstraints" + tools:layout_editor_absoluteX="0dp" /> + + <ImageView + android:id="@+id/img_ear_right" + android:layout_width="100dp" + android:layout_height="100dp" + android:translationX="35dp" + android:translationY="-10dp" + android:scaleX="-1" + app:srcCompat="@drawable/img_cus_ear_1" + tools:ignore="MissingConstraints" + tools:layout_editor_absoluteX="0dp" /> + + </androidx.constraintlayout.widget.ConstraintLayout> +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/togaetherLib/src/main/res/values/strings.xml b/togaetherLib/src/main/res/values/strings.xml new file mode 100644 index 0000000..73862c4 --- /dev/null +++ b/togaetherLib/src/main/res/values/strings.xml @@ -0,0 +1 @@ +<resources></resources> \ No newline at end of file diff --git a/togaetherLib/src/test/java/com/example/togaetherlib/ExampleUnitTest.java b/togaetherLib/src/test/java/com/example/togaetherlib/ExampleUnitTest.java new file mode 100644 index 0000000..1dd1718 --- /dev/null +++ b/togaetherLib/src/test/java/com/example/togaetherlib/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.example.togaetherlib; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file