Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions Animora/.github/workflows/generateAnimora.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Animora CI/CD

run-name: "Building Animora APK And Release"

on:
push:
tags:
- v*.*.*

permissions:
contents: write

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup JDK 17 + Gradle cache
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
cache: gradle

- name: Grant execute permission
run: chmod +x gradlew

- name: Build Debug APK (MVP)
run: ./gradlew assembleDebug --no-daemon

- name: Upload Release
uses: softprops/action-gh-release@v2
if: github.ref_type == 'tag'
with:
files: app/build/outputs/apk/debug/app-debug.apk
Comment on lines +32 to +38
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The CI/CD workflow is configured to build and upload a debug APK (assembleDebug, app-debug.apk) when a release tag is pushed. For a public release, you should always build and distribute a signed release APK. Debug builds are not optimized, are insecure, and are not suitable for distribution.

        run: ./gradlew assembleRelease --no-daemon

      - name: Upload Release
        uses: softprops/action-gh-release@v2
        if: github.ref_type == 'tag'
        with:
          files: app/build/outputs/apk/release/app-release.apk

body_path: releases/${{ github.ref_name }}.md
15 changes: 15 additions & 0 deletions Animora/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties

# Kotlin
.kotlin

# Android Studio
.idea
437 changes: 437 additions & 0 deletions Animora/LICENSE

Large diffs are not rendered by default.

109 changes: 109 additions & 0 deletions Animora/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Animora

[本文中文版](README_zh-CN.md)

An open source Material Design Animation Textbook and Teaching Equipment

## Preview

<p>
<img src="/publicAsset/images/AnimoraSplash.png" width="32%" />
<img src="/publicAsset/images/AnimoraHome.png" width="32%" />
<img src="/publicAsset/images/AnimoraInfo.png" width="32%" />
<img src="/publicAsset/images/AnimoraList.png" width="32%" />
<img src="/publicAsset/images/AnimoraBlur.png" width="32%" />
<img src="/publicAsset/images/AnimoraStudio.png" width="32%" />
Comment on lines +10 to +15
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The image paths in the preview section appear to be incorrect. They start with a leading slash (/), which makes them root-relative paths. This will likely result in broken images when viewed on GitHub. To fix this, you should use relative paths from the README.md file's location or absolute URLs to the images in the repository.

Suggested change
<img src="/publicAsset/images/AnimoraSplash.png" width="32%" />
<img src="/publicAsset/images/AnimoraHome.png" width="32%" />
<img src="/publicAsset/images/AnimoraInfo.png" width="32%" />
<img src="/publicAsset/images/AnimoraList.png" width="32%" />
<img src="/publicAsset/images/AnimoraBlur.png" width="32%" />
<img src="/publicAsset/images/AnimoraStudio.png" width="32%" />
<img src="publicAsset/images/AnimoraSplash.png" width="32%" />
<img src="publicAsset/images/AnimoraHome.png" width="32%" />
<img src="publicAsset/images/AnimoraInfo.png" width="32%" />
<img src="publicAsset/images/AnimoraList.png" width="32%" />
<img src="publicAsset/images/AnimoraBlur.png" width="32%" />
<img src="publicAsset/images/AnimoraStudio.png" width="32%" />


</p>

## Features

- Animation Gallery: A centralized list showcasing a wide variety of Jetpack Compose animation effects.
- Interactive Demos: Users can directly interact with animation samples to intuitively experience how they work.
- Categorized Browsing: Animations are organized by type and complexity for easy discovery and learning.
- Detail Views: Each animation has a dedicated detail page with more in-depth demonstrations and explanations.
- Modern UI Design: Built entirely with Jetpack Compose, following Material Design principles for a sleek and smooth interface.
- Code References: Provides core implementation code snippets for each animation, enabling developers to learn and apply them quickly.
- 100% Kotlin: The entire project is written in Kotlin.

## Future planning

- [x] Basic Feature Available
- [x] Add necessary SpringSpec API discovery
- [x] Add sharedTransition API for list view
- [x] Add more annotations for the project
- [x] Use CI/CD for best practice
- [ ] Upload the application to F-Droid
- [ ] Upload the application to GooglePlay

## Why I Made Animora?

Because I fell in love with Material Design long before I became an Android developer.

When I was still a student, Google’s **Material You** design language deeply resonated with me.
I had always hoped that one day, I could build a **Material Design app of my own** — not as a demo, not as a concept, but as a real, usable product.

Animora is the result of that long-standing aspiration.

---

Because I believe technology should be equal and transparent.

My first online name was **Free-Terder**, literally meaning *“Free Trader”*.
It was built upon a single belief that has stayed with me for many years:

> **Truth will eventually pierce lies, and technology should belong to everyone.**

This belief accompanied me from Android ROM flashing, through Linux fundamentals, and finally to software development itself.
In 2024, I made a firm decision to become an **Android Developer**, and Animora is a concrete step forward on that path.

---

Because learning Android should not feel hopeless.

While learning **Kotlin**, **Android development**, and **Jetpack Compose**,
this belief repeatedly pulled me back from frustration and self-doubt.

Animora was created during those moments —
as something I wished had existed when I was learning animations, state, and interaction in Compose.

---

Because doing the right thing is harder than doing the reasonable thing.

While preparing Animora for release, I was reading *Silo*, which left a strong impression on me:

> **Doing the right thing is not the same as doing the reasonable thing.
> And between the two, the reasonable choice is always easier.**

Still, I believe the light of human civilization is real.
There are always people willing to carry the weight and choose what is right —
and I choose to stand among them.

---

Because I chose open source, deliberately.

I did not choose the common path of **closed source + paid access**.
That is simply not the future I want to see.

Closed information barriers breed ignorance.
Animora exists — and is fully open source — precisely because I want to resist that outcome.

---

Because I want Animora to help more people.

- To help struggling developers **feel less alone**, and have something reliable to lean on
- To help students learning *Java for Android* **realize early that academic knowledge is often outdated or incomplete**
- To contribute, even in a small way, to a **healthier and more honest open-source ecosystem**
- To find like-minded people and **build things together**

---

In a word, Animora tries to do the right thing —
with clean code, modern Android practices, and an honest intent.

---

### For those who still have the courage to choose hope.
113 changes: 113 additions & 0 deletions Animora/README_zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Animora

[For English Version](README.md)

一个开源的 Material Design 动画教材与教学工具

## 预览

<p>
<img src="/publicAsset/images/AnimoraSplash.png" width="32%" />
<img src="/publicAsset/images/AnimoraHome.png" width="32%" />
<img src="/publicAsset/images/AnimoraInfo.png" width="32%" />
<img src="/publicAsset/images/AnimoraList.png" width="32%" />
<img src="/publicAsset/images/AnimoraBlur.png" width="32%" />
<img src="/publicAsset/images/AnimoraStudio.png" width="32%" />
</p>

## 功能特性

- 动画画廊:集中展示多种 Jetpack Compose 动画效果,便于系统性学习。
- 可交互示例:用户可以直接与动画示例交互,直观理解动画的运行方式。
- 分类浏览:按动画类型与复杂度进行分类,方便查找与循序渐进地学习。
- 详情页面:每个动画都配有独立的详情页,提供更深入的演示与讲解。
- 现代化 UI 设计:完全基于 Jetpack Compose 构建,遵循 Material Design 设计规范,界面简洁流畅。
- 代码参考:为每个动画提供核心实现代码,帮助开发者快速理解并应用。
- 100% Kotlin:整个项目完全使用 Kotlin 编写。

## 未来规划

- [x] 基础功能已完成
- [x] 补充必要的 SpringSpec API 探索
- [x] 为列表视图引入 SharedTransition API
- [x] 为项目补充更多注释与文档说明
- [x] 使用 CI/CD 作为最佳实践
- [ ] 将应用发布到 F-Droid
- [ ] 将应用发布到 Google Play

## 为什么我做了 Animora?

因为我很早就喜欢上了 Material Design。

在我还是学生的时候,就被 Google 的 **Material You** 设计语言深深吸引。
那时我就希望,有一天能亲手做出一款真正属于自己的 **Material Design 应用**——
不是概念,不是练习,而是一个真实、可用、经得起推敲的产品。

Animora,正是这个愿望的结果。

---

因为我相信:真相终将戳破谎言,科技应人人平等。

我的第一个网名是 **Free-Terder**,意为「免费商人」。
它存在的理由,始终只有一句话:

> **真相终将戳破谎言,科技应人人平等**

这句座右铭陪伴了我很多年——
从折腾手机系统,到学习 Linux 基础,再到真正走上软件开发这条路。
直到今年,我终于下定决心,成为一名 **Android Developer**,
而 Animora,是我迈出的重要一步。

---

因为学习 Android,不应该让人感到绝望。

在学习 **Kotlin、Android 开发** 与 **Jetpack Compose** 的过程中,
这句座右铭一次次把我从迷茫和挫败中拉回来。

Animora,正是诞生在这些时刻。
它是我在学习动画、状态与交互时,**最希望当时就能拥有的工具与示例集合**。

---

因为做正确的事,往往比做合理的事更难。

在 Animora 发布前夕,我正在阅读《**Silo**》,其中一句话让我印象深刻:

> **做正确的事,并不等同于做合理的事;
> 而在二者之间,后者显然更容易。**

但我依然相信,
属于人类文明的光辉是真实存在的。
这个世界从不缺少那些肩负重担、依然选择做正确之事的人。
我也愿意成为其中一员。

---

因为我有意选择了开源。

我没有选择闭源 + 收费的道路。
这并不是我愿意看到的未来。

封闭的信息壁垒容易滋生愚昧,
而 Animora 的完全开源,正是对这种趋势的一次微小反抗。

---

因为我希望 Animora 能帮助更多人。

- 让正在苦苦挣扎的开发者,**少一些焦虑,多一份可以信赖的依靠**
- 让正在学习 *Java for Android* 的学生,**尽早意识到:学校里的知识并不总是正确的**
- 尽自己微薄的力量,**推动一个更加开放、真实、健康的开源社区**
- 找到志同道合的人,**一起并肩作战**

---

总而言之,Animora 想做的事情很简单:
**遵循最佳实践,保持代码整洁,做正确的事。**

---

### 为了那些
**依然有勇气选择希望的人**
3 changes: 3 additions & 0 deletions Animora/app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/build
/release
/debug
79 changes: 79 additions & 0 deletions Animora/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
kotlin("plugin.serialization") version "2.0.21"
}

android {
namespace = "com.baidaidai.animora"
compileSdk = 35

defaultConfig {
applicationId = "com.baidaidai.animora"
minSdk = 24
targetSdk = 35
versionCode = 1
versionName = "1.2.8"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
isMinifyEnabled = false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For release builds, it's highly recommended to enable minification by setting isMinifyEnabled = true. This helps reduce the size of your APK and obfuscates the code, which is a good practice for production releases.

            isMinifyEnabled = true

proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
}
buildFeatures {
compose = true
}
}

dependencies {

testImplementation("junit:junit:4.13.2")

implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
implementation("androidx.compose.material3:material3-adaptive-navigation-suite")
implementation(libs.material)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
debugImplementation("androidx.compose.ui:ui-test-manifest:1.6.8")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.6")
implementation("androidx.navigation:navigation-compose:2.8.6")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
implementation("androidx.window:window:1.5.0")
implementation("androidx.compose.material:material-icons-core:1.7.5")
implementation("androidx.compose.material:material-icons-extended:1.7.5")
implementation("androidx.compose.material3:material3:1.4.0-alpha14")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
implementation("androidx.compose.ui:ui:1.9.0")
implementation("androidx.compose.ui:ui-graphics:1.9.0")
implementation("androidx.compose.ui:ui-tooling-preview:1.9.0")
implementation("androidx.core:core-splashscreen:1.0.0")
implementation("com.github.jeziellago:compose-markdown:0.5.8")

}
21 changes: 21 additions & 0 deletions Animora/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -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
Loading