Browse Source
初始化OxFace登录Android项目
初始化OxFace登录Android项目
- 添加基础项目结构和配置文件 - 实现简洁的Material Design登录界面 - 包含用户名和密码输入功能 - 支持界面滚动适配不同屏幕尺寸 - 使用绿色主题色 #009874 - 配置Gradle构建系统和依赖管理main
commit
2b9336a09e
25 changed files with 914 additions and 0 deletions
-
146.gitignore
-
41app/build.gradle
-
21app/proguard-rules.pro
-
26app/src/main/AndroidManifest.xml
-
79app/src/main/java/com/example/oxfacelogin/MainActivity.java
-
11app/src/main/res/drawable/ic_launcher_background.xml
-
15app/src/main/res/drawable/ic_launcher_foreground.xml
-
10app/src/main/res/drawable/ic_lock.xml
-
10app/src/main/res/drawable/ic_login_logo.xml
-
10app/src/main/res/drawable/ic_person.xml
-
153app/src/main/res/layout/activity_main.xml
-
5app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
-
5app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
-
16app/src/main/res/values-night/themes.xml
-
31app/src/main/res/values/colors.xml
-
5app/src/main/res/values/dimens.xml
-
14app/src/main/res/values/strings.xml
-
34app/src/main/res/values/themes.xml
-
12app/src/main/res/xml/backup_rules.xml
-
19app/src/main/res/xml/data_extraction_rules.xml
-
16build.gradle
-
28gradle.properties
-
5gradle/wrapper/gradle-wrapper.properties
-
185gradlew
-
17settings.gradle
@ -0,0 +1,146 @@ |
|||
# Built application files |
|||
*.apk |
|||
*.aar |
|||
*.ap_ |
|||
*.aab |
|||
|
|||
# Files for the ART/Dalvik VM |
|||
*.dex |
|||
|
|||
# Java class files |
|||
*.class |
|||
|
|||
# Generated files |
|||
bin/ |
|||
gen/ |
|||
out/ |
|||
# Uncomment the following line in case you need and you don't have the release build type files in your app |
|||
# release/ |
|||
|
|||
# Gradle files |
|||
.gradle/ |
|||
build/ |
|||
|
|||
# Local configuration file (sdk path, etc) |
|||
local.properties |
|||
|
|||
# Proguard folder generated by Eclipse |
|||
proguard/ |
|||
|
|||
# Log Files |
|||
*.log |
|||
|
|||
# Android Studio Navigation editor temp files |
|||
.navigation/ |
|||
|
|||
# Android Studio captures folder |
|||
captures/ |
|||
|
|||
# IntelliJ |
|||
*.iml |
|||
.idea/workspace.xml |
|||
.idea/tasks.xml |
|||
.idea/gradle.xml |
|||
.idea/assetWizardSettings.xml |
|||
.idea/dictionaries |
|||
.idea/libraries |
|||
# Android Studio 3 in .gitignore file. |
|||
.idea/caches |
|||
.idea/modules.xml |
|||
# Comment next line if keeping position of elements in Navigation Editor is relevant for you |
|||
.idea/navEditor.xml |
|||
|
|||
# Keystore files |
|||
# Uncomment the following lines if you do not want to check your keystore files in. |
|||
#*.jks |
|||
#*.keystore |
|||
|
|||
# External native build folder generated in Android Studio 2.2 and later |
|||
.externalNativeBuild |
|||
.cxx/ |
|||
|
|||
# Google Services (e.g. APIs or Firebase) |
|||
# google-services.json |
|||
|
|||
# Freeline |
|||
freeline.py |
|||
freeline/ |
|||
freeline_project_description.json |
|||
|
|||
# fastlane |
|||
fastlane/report.xml |
|||
fastlane/Preview.html |
|||
fastlane/screenshots |
|||
fastlane/test_output |
|||
fastlane/readme.md |
|||
|
|||
# Version control |
|||
vcs.xml |
|||
|
|||
# lint |
|||
lint/intermediates/ |
|||
lint/generated/ |
|||
lint/outputs/ |
|||
lint/tmp/ |
|||
# lint/reports/ |
|||
|
|||
# Android Profiling |
|||
*.hprof |
|||
|
|||
# IDEs |
|||
*~ |
|||
*.swp |
|||
*.swo |
|||
|
|||
# OS generated files |
|||
.DS_Store |
|||
.DS_Store? |
|||
._* |
|||
.Spotlight-V100 |
|||
.Trashes |
|||
ehthumbs.db |
|||
Thumbs.db |
|||
|
|||
# Gradle Wrapper |
|||
# Uncomment the following line if you want to exclude gradle wrapper |
|||
# gradle/wrapper/gradle-wrapper.jar |
|||
|
|||
# Local Gradle daemon address |
|||
.gradle/daemon/ |
|||
|
|||
# NDK |
|||
obj/ |
|||
|
|||
# Backup files |
|||
*~ |
|||
|
|||
# Temporary files |
|||
*.tmp |
|||
*.temp |
|||
|
|||
# Package Files |
|||
*.jar |
|||
*.war |
|||
*.ear |
|||
|
|||
# virtual machine crash logs (Reference: http://www.java.com/en/download/help/error_hotspot.xml) |
|||
hs_err_pid* |
|||
|
|||
# Crashlytics generated file |
|||
crashlytics-build.properties |
|||
|
|||
# Fabric plugin |
|||
com_crashlytics_export_strings.xml |
|||
crashlytics.properties |
|||
fabric.properties |
|||
|
|||
# Editor-based Rest Client |
|||
.idea/httpRequests |
|||
|
|||
# Android Profiling |
|||
*.hprof |
|||
|
|||
# Test output |
|||
test-results/ |
|||
test-reports/ |
|||
coverage-results/ |
@ -0,0 +1,41 @@ |
|||
plugins { |
|||
id 'com.android.application' |
|||
} |
|||
|
|||
android { |
|||
namespace 'com.example.oxfacelogin' |
|||
compileSdk 35 |
|||
buildToolsVersion "35.0.0" |
|||
|
|||
defaultConfig { |
|||
applicationId "com.example.oxfacelogin" |
|||
minSdk 21 |
|||
targetSdk 35 |
|||
versionCode 1 |
|||
versionName "1.0" |
|||
|
|||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" |
|||
} |
|||
|
|||
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.6.1' |
|||
implementation 'com.google.android.material:material:1.10.0' |
|||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4' |
|||
|
|||
testImplementation 'junit:junit:4.13.2' |
|||
androidTestImplementation 'androidx.test.ext:junit:1.1.5' |
|||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' |
|||
} |
@ -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 |
@ -0,0 +1,26 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
|||
xmlns:tools="http://schemas.android.com/tools"> |
|||
|
|||
<application |
|||
android:allowBackup="true" |
|||
android:dataExtractionRules="@xml/data_extraction_rules" |
|||
android:fullBackupContent="@xml/backup_rules" |
|||
android:icon="@mipmap/ic_launcher" |
|||
android:label="@string/app_name" |
|||
android:roundIcon="@mipmap/ic_launcher_round" |
|||
android:supportsRtl="true" |
|||
android:theme="@style/Theme.OxFaceLogin" |
|||
tools:targetApi="31"> |
|||
<activity |
|||
android:name=".MainActivity" |
|||
android:exported="true" |
|||
android:theme="@style/Theme.OxFaceLogin"> |
|||
<intent-filter> |
|||
<action android:name="android.intent.action.MAIN" /> |
|||
<category android:name="android.intent.category.LAUNCHER" /> |
|||
</intent-filter> |
|||
</activity> |
|||
</application> |
|||
|
|||
</manifest> |
@ -0,0 +1,79 @@ |
|||
package com.example.oxfacelogin; |
|||
|
|||
import androidx.appcompat.app.AppCompatActivity; |
|||
import android.os.Bundle; |
|||
import android.view.View; |
|||
import android.widget.Button; |
|||
import android.widget.EditText; |
|||
import android.widget.Toast; |
|||
|
|||
public class MainActivity extends AppCompatActivity { |
|||
|
|||
private EditText editTextUsername; |
|||
private EditText editTextPassword; |
|||
private Button buttonLogin; |
|||
|
|||
@Override |
|||
protected void onCreate(Bundle savedInstanceState) { |
|||
super.onCreate(savedInstanceState); |
|||
setContentView(R.layout.activity_main); |
|||
|
|||
// 初始化视图组件 |
|||
initViews(); |
|||
|
|||
// 设置登录按钮点击事件 |
|||
setupLoginButton(); |
|||
} |
|||
|
|||
private void initViews() { |
|||
editTextUsername = findViewById(R.id.editTextUsername); |
|||
editTextPassword = findViewById(R.id.editTextPassword); |
|||
buttonLogin = findViewById(R.id.buttonLogin); |
|||
} |
|||
|
|||
private void setupLoginButton() { |
|||
buttonLogin.setOnClickListener(new View.OnClickListener() { |
|||
@Override |
|||
public void onClick(View v) { |
|||
String username = editTextUsername.getText().toString().trim(); |
|||
String password = editTextPassword.getText().toString().trim(); |
|||
|
|||
if (validateInput(username, password)) { |
|||
performLogin(username, password); |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
|
|||
private boolean validateInput(String username, String password) { |
|||
if (username.isEmpty()) { |
|||
editTextUsername.setError("请输入用户名"); |
|||
editTextUsername.requestFocus(); |
|||
return false; |
|||
} |
|||
|
|||
if (password.isEmpty()) { |
|||
editTextPassword.setError("请输入密码"); |
|||
editTextPassword.requestFocus(); |
|||
return false; |
|||
} |
|||
|
|||
if (password.length() < 6) { |
|||
editTextPassword.setError("密码长度至少6位"); |
|||
editTextPassword.requestFocus(); |
|||
return false; |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
private void performLogin(String username, String password) { |
|||
// 这里可以添加实际的登录逻辑 |
|||
// 目前只是显示一个简单的提示 |
|||
if (username.equals("admin") && password.equals("123456")) { |
|||
Toast.makeText(this, "登录成功!欢迎 " + username, Toast.LENGTH_SHORT).show(); |
|||
} else { |
|||
Toast.makeText(this, "用户名或密码错误", Toast.LENGTH_SHORT).show(); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,11 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|||
android:width="108dp" |
|||
android:height="108dp" |
|||
android:viewportWidth="108" |
|||
android:viewportHeight="108"> |
|||
<path android:fillColor="@color/primary_color" |
|||
android:pathData="M0,0h108v108h-108z" /> |
|||
<path android:fillColor="@color/primary_light_color" |
|||
android:pathData="M9,0h90v108h-90z" /> |
|||
</vector> |
@ -0,0 +1,15 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|||
android:width="108dp" |
|||
android:height="108dp" |
|||
android:viewportWidth="108" |
|||
android:viewportHeight="108"> |
|||
<group android:scaleX="2.61" |
|||
android:scaleY="2.61" |
|||
android:translateX="22.68" |
|||
android:translateY="22.68"> |
|||
<path |
|||
android:fillColor="@android:color/white" |
|||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,5c1.66,0 3,1.34 3,3s-1.34,3 -3,3 -3,-1.34 -3,-3 1.34,-3 3,-3zM12,19.2c-2.5,0 -4.71,-1.28 -6,-3.22 0.03,-1.99 4,-3.08 6,-3.08 1.99,0 5.97,1.09 6,3.08 -1.29,1.94 -3.5,3.22 -6,3.22z"/> |
|||
</group> |
|||
</vector> |
@ -0,0 +1,10 @@ |
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|||
android:width="24dp" |
|||
android:height="24dp" |
|||
android:viewportWidth="24" |
|||
android:viewportHeight="24" |
|||
android:tint="@color/secondary_text_color"> |
|||
<path |
|||
android:fillColor="@android:color/white" |
|||
android:pathData="M18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM15.1,8L8.9,8L8.9,6c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2z"/> |
|||
</vector> |
@ -0,0 +1,10 @@ |
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|||
android:width="100dp" |
|||
android:height="100dp" |
|||
android:viewportWidth="24" |
|||
android:viewportHeight="24" |
|||
android:tint="@color/primary_color"> |
|||
<path |
|||
android:fillColor="@android:color/white" |
|||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,5c1.66,0 3,1.34 3,3s-1.34,3 -3,3 -3,-1.34 -3,-3 1.34,-3 3,-3zM12,19.2c-2.5,0 -4.71,-1.28 -6,-3.22 0.03,-1.99 4,-3.08 6,-3.08 1.99,0 5.97,1.09 6,3.08 -1.29,1.94 -3.5,3.22 -6,3.22z"/> |
|||
</vector> |
@ -0,0 +1,10 @@ |
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android" |
|||
android:width="24dp" |
|||
android:height="24dp" |
|||
android:viewportWidth="24" |
|||
android:viewportHeight="24" |
|||
android:tint="@color/secondary_text_color"> |
|||
<path |
|||
android:fillColor="@android:color/white" |
|||
android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/> |
|||
</vector> |
@ -0,0 +1,153 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<ScrollView 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="match_parent" |
|||
android:layout_height="match_parent" |
|||
android:background="@color/background_color" |
|||
android:fillViewport="true"> |
|||
|
|||
<androidx.constraintlayout.widget.ConstraintLayout |
|||
android:layout_width="match_parent" |
|||
android:layout_height="wrap_content" |
|||
android:minHeight="@dimen/min_screen_height" |
|||
tools:context=".MainActivity"> |
|||
|
|||
<!-- 应用Logo --> |
|||
<ImageView |
|||
android:id="@+id/imageViewLogo" |
|||
android:layout_width="100dp" |
|||
android:layout_height="100dp" |
|||
android:layout_marginTop="40dp" |
|||
android:src="@drawable/ic_login_logo" |
|||
android:contentDescription="@string/app_logo" |
|||
app:layout_constraintEnd_toEndOf="parent" |
|||
app:layout_constraintStart_toStartOf="parent" |
|||
app:layout_constraintTop_toTopOf="parent" /> |
|||
|
|||
<!-- 应用标题 --> |
|||
<TextView |
|||
android:id="@+id/textViewTitle" |
|||
android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content" |
|||
android:layout_marginTop="20dp" |
|||
android:text="@string/app_name" |
|||
android:textSize="24sp" |
|||
android:textStyle="bold" |
|||
android:textColor="@color/primary_text_color" |
|||
app:layout_constraintEnd_toEndOf="parent" |
|||
app:layout_constraintStart_toStartOf="parent" |
|||
app:layout_constraintTop_toBottomOf="@+id/imageViewLogo" /> |
|||
|
|||
<!-- 登录卡片容器 --> |
|||
<androidx.cardview.widget.CardView |
|||
android:layout_width="0dp" |
|||
android:layout_height="wrap_content" |
|||
android:layout_marginStart="32dp" |
|||
android:layout_marginTop="40dp" |
|||
android:layout_marginEnd="32dp" |
|||
android:layout_marginBottom="32dp" |
|||
app:cardCornerRadius="16dp" |
|||
app:cardElevation="8dp" |
|||
app:cardBackgroundColor="@color/card_background" |
|||
app:layout_constraintEnd_toEndOf="parent" |
|||
app:layout_constraintStart_toStartOf="parent" |
|||
app:layout_constraintTop_toBottomOf="@+id/textViewTitle" |
|||
app:layout_constraintBottom_toBottomOf="parent"> |
|||
|
|||
<LinearLayout |
|||
android:layout_width="match_parent" |
|||
android:layout_height="wrap_content" |
|||
android:orientation="vertical" |
|||
android:padding="32dp"> |
|||
|
|||
<!-- 登录卡片内的Logo --> |
|||
<ImageView |
|||
android:id="@+id/imageViewLoginLogo" |
|||
android:layout_width="80dp" |
|||
android:layout_height="80dp" |
|||
android:layout_gravity="center" |
|||
android:layout_marginBottom="24dp" |
|||
android:src="@drawable/ic_login_logo" |
|||
android:contentDescription="@string/login_logo" /> |
|||
|
|||
<!-- 用户名输入框 --> |
|||
<com.google.android.material.textfield.TextInputLayout |
|||
android:layout_width="match_parent" |
|||
android:layout_height="wrap_content" |
|||
android:layout_marginBottom="16dp" |
|||
android:hint="@string/hint_username" |
|||
app:startIconDrawable="@drawable/ic_person" |
|||
app:boxStrokeColor="@color/primary_color" |
|||
app:hintTextColor="@color/primary_color" |
|||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"> |
|||
|
|||
<com.google.android.material.textfield.TextInputEditText |
|||
android:id="@+id/editTextUsername" |
|||
android:layout_width="match_parent" |
|||
android:layout_height="wrap_content" |
|||
android:inputType="text" |
|||
android:maxLines="1" |
|||
android:textColor="@color/primary_text_color" |
|||
android:textSize="16sp" /> |
|||
|
|||
</com.google.android.material.textfield.TextInputLayout> |
|||
|
|||
<!-- 密码输入框 --> |
|||
<com.google.android.material.textfield.TextInputLayout |
|||
android:layout_width="match_parent" |
|||
android:layout_height="wrap_content" |
|||
android:layout_marginBottom="24dp" |
|||
android:hint="@string/hint_password" |
|||
app:startIconDrawable="@drawable/ic_lock" |
|||
app:endIconMode="password_toggle" |
|||
app:boxStrokeColor="@color/primary_color" |
|||
app:hintTextColor="@color/primary_color" |
|||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"> |
|||
|
|||
<com.google.android.material.textfield.TextInputEditText |
|||
android:id="@+id/editTextPassword" |
|||
android:layout_width="match_parent" |
|||
android:layout_height="wrap_content" |
|||
android:inputType="textPassword" |
|||
android:maxLines="1" |
|||
android:textColor="@color/primary_text_color" |
|||
android:textSize="16sp" /> |
|||
|
|||
</com.google.android.material.textfield.TextInputLayout> |
|||
|
|||
<!-- 登录按钮 --> |
|||
<com.google.android.material.button.MaterialButton |
|||
android:id="@+id/buttonLogin" |
|||
android:layout_width="match_parent" |
|||
android:layout_height="56dp" |
|||
android:text="@string/login_button" |
|||
android:textSize="16sp" |
|||
android:textStyle="bold" |
|||
android:textColor="@android:color/white" |
|||
app:backgroundTint="@color/primary_color" |
|||
app:cornerRadius="28dp" |
|||
app:elevation="4dp" /> |
|||
|
|||
<!-- 忘记密码链接 --> |
|||
<TextView |
|||
android:id="@+id/textViewForgotPassword" |
|||
android:layout_width="wrap_content" |
|||
android:layout_height="wrap_content" |
|||
android:layout_gravity="center" |
|||
android:layout_marginTop="16dp" |
|||
android:text="@string/forgot_password" |
|||
android:textColor="@color/secondary_text_color" |
|||
android:textSize="14sp" |
|||
android:padding="8dp" |
|||
android:background="?attr/selectableItemBackgroundBorderless" |
|||
android:clickable="true" |
|||
android:focusable="true" /> |
|||
|
|||
</LinearLayout> |
|||
|
|||
</androidx.cardview.widget.CardView> |
|||
|
|||
</androidx.constraintlayout.widget.ConstraintLayout> |
|||
|
|||
</ScrollView> |
@ -0,0 +1,5 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> |
|||
<background android:drawable="@drawable/ic_launcher_background" /> |
|||
<foreground android:drawable="@drawable/ic_launcher_foreground" /> |
|||
</adaptive-icon> |
@ -0,0 +1,5 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> |
|||
<background android:drawable="@drawable/ic_launcher_background" /> |
|||
<foreground android:drawable="@drawable/ic_launcher_foreground" /> |
|||
</adaptive-icon> |
@ -0,0 +1,16 @@ |
|||
<resources xmlns:tools="http://schemas.android.com/tools"> |
|||
<!-- Base application theme. --> |
|||
<style name="Theme.OxFaceLogin" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> |
|||
<!-- Primary brand color. --> |
|||
<item name="colorPrimary">@color/primary_color</item> |
|||
<item name="colorPrimaryVariant">@color/primary_dark_color</item> |
|||
<item name="colorOnPrimary">@color/black</item> |
|||
<!-- Secondary brand color. --> |
|||
<item name="colorSecondary">@color/teal_200</item> |
|||
<item name="colorSecondaryVariant">@color/teal_200</item> |
|||
<item name="colorOnSecondary">@color/black</item> |
|||
<!-- Status bar color. --> |
|||
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item> |
|||
<!-- Customize your theme here. --> |
|||
</style> |
|||
</resources> |
@ -0,0 +1,31 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<resources> |
|||
<!-- 主题色 --> |
|||
<color name="primary_color">#009874</color> |
|||
<color name="primary_dark_color">#007A5E</color> |
|||
<color name="primary_light_color">#B2E0D8</color> |
|||
|
|||
<!-- 强调色 --> |
|||
<color name="accent_color">#FF5722</color> |
|||
|
|||
<!-- 背景色 --> |
|||
<color name="background_color">#F5F5F5</color> |
|||
<color name="card_background">#FFFFFF</color> |
|||
|
|||
<!-- 文字颜色 --> |
|||
<color name="primary_text_color">#212121</color> |
|||
<color name="secondary_text_color">#757575</color> |
|||
|
|||
<!-- 其他颜色 --> |
|||
<color name="divider_color">#BDBDBD</color> |
|||
<color name="error_color">#F44336</color> |
|||
|
|||
<!-- 系统颜色 --> |
|||
<color name="purple_200">#FFBB86FC</color> |
|||
<color name="purple_500">#FF6200EE</color> |
|||
<color name="purple_700">#FF3700B3</color> |
|||
<color name="teal_200">#FF03DAC5</color> |
|||
<color name="teal_700">#FF018786</color> |
|||
<color name="black">#FF000000</color> |
|||
<color name="white">#FFFFFFFF</color> |
|||
</resources> |
@ -0,0 +1,5 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<resources> |
|||
<!-- 最小屏幕高度,确保内容在小屏幕上也能正确显示 --> |
|||
<dimen name="min_screen_height">600dp</dimen> |
|||
</resources> |
@ -0,0 +1,14 @@ |
|||
<resources> |
|||
<string name="app_name">OxFace登录</string> |
|||
<string name="app_logo">应用图标</string> |
|||
<string name="login_logo">登录图标</string> |
|||
<string name="hint_username">用户名</string> |
|||
<string name="hint_password">密码</string> |
|||
<string name="login_button">登录</string> |
|||
<string name="forgot_password">忘记密码?</string> |
|||
<string name="login_success">登录成功!</string> |
|||
<string name="login_failed">用户名或密码错误</string> |
|||
<string name="empty_username">请输入用户名</string> |
|||
<string name="empty_password">请输入密码</string> |
|||
<string name="password_too_short">密码长度至少6位</string> |
|||
</resources> |
@ -0,0 +1,34 @@ |
|||
<resources xmlns:tools="http://schemas.android.com/tools"> |
|||
<!-- Base application theme. --> |
|||
<style name="Theme.OxFaceLogin" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> |
|||
<!-- Primary brand color. --> |
|||
<item name="colorPrimary">@color/primary_color</item> |
|||
<item name="colorPrimaryVariant">@color/primary_dark_color</item> |
|||
<item name="colorOnPrimary">@color/white</item> |
|||
<!-- Secondary brand color. --> |
|||
<item name="colorSecondary">@color/accent_color</item> |
|||
<item name="colorSecondaryVariant">@color/accent_color</item> |
|||
<item name="colorOnSecondary">@color/white</item> |
|||
<!-- Status bar color. --> |
|||
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item> |
|||
<!-- Customize your theme here. --> |
|||
<item name="android:windowBackground">@color/background_color</item> |
|||
</style> |
|||
|
|||
<!-- 登录按钮样式 --> |
|||
<style name="LoginButtonStyle" parent="Widget.MaterialComponents.Button"> |
|||
<item name="android:layout_width">match_parent</item> |
|||
<item name="android:layout_height">56dp</item> |
|||
<item name="android:textSize">16sp</item> |
|||
<item name="android:textStyle">bold</item> |
|||
<item name="backgroundTint">@color/primary_color</item> |
|||
<item name="cornerRadius">28dp</item> |
|||
</style> |
|||
|
|||
<!-- 输入框样式 --> |
|||
<style name="InputLayoutStyle" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox"> |
|||
<item name="boxStrokeColor">@color/primary_color</item> |
|||
<item name="hintTextColor">@color/primary_color</item> |
|||
<item name="android:layout_marginBottom">16dp</item> |
|||
</style> |
|||
</resources> |
@ -0,0 +1,12 @@ |
|||
<?xml version="1.0" encoding="utf-8"?><!-- |
|||
Sample backup rules file; uncomment and customize as necessary. |
|||
See https://developer.android.com/guide/topics/data/autobackup |
|||
for details. |
|||
Note: This file is ignored for devices older that API 23 even if they have backups enabled. |
|||
--> |
|||
<full-backup-content> |
|||
<!-- |
|||
<include domain="sharedpref" path="."/> |
|||
<exclude domain="sharedpref" path="device.xml"/> |
|||
--> |
|||
</full-backup-content> |
@ -0,0 +1,19 @@ |
|||
<?xml version="1.0" encoding="utf-8"?><!-- |
|||
Sample data extraction rules file; uncomment and customize as necessary. |
|||
See https://developer.android.com/about/versions/12/backup-restore#xml-changes |
|||
for details. |
|||
--> |
|||
<data-extraction-rules> |
|||
<cloud-backup> |
|||
<!-- TODO: Use <include> and <exclude> to control what is backed up. |
|||
<include .../> |
|||
<exclude .../> |
|||
--> |
|||
</cloud-backup> |
|||
<!-- |
|||
<device-transfer> |
|||
<include .../> |
|||
<exclude .../> |
|||
</device-transfer> |
|||
--> |
|||
</data-extraction-rules> |
@ -0,0 +1,16 @@ |
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules. |
|||
buildscript { |
|||
repositories { |
|||
google() |
|||
mavenCentral() |
|||
} |
|||
dependencies { |
|||
classpath 'com.android.tools.build:gradle:8.7.2' |
|||
// NOTE: Do not place your application dependencies here; they belong |
|||
// in the individual module build.gradle files |
|||
} |
|||
} |
|||
|
|||
task clean(type: Delete) { |
|||
delete rootProject.buildDir |
|||
} |
@ -0,0 +1,28 @@ |
|||
# Project-wide Gradle settings. |
|||
# IDE (e.g. Android Studio) users: |
|||
# Gradle settings configured through the IDE *will override* |
|||
# any settings specified in this file. |
|||
# 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. |
|||
org.gradle.jvmargs=-Xmx2048m -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 |
|||
# AndroidX package structure to make it clearer which packages are bundled with the |
|||
# Android operating system, and which are packaged with your app's APK |
|||
# https://developer.android.com/topic/libraries/support-library/androidx-rn |
|||
android.useAndroidX=true |
|||
# Kotlin code style for this project: "official" or "obsolete": |
|||
kotlin.code.style=official |
|||
# Enables namespacing of each library's R class so that its R class includes only the |
|||
# resources declared in the library itself and none from the library's dependencies, |
|||
# thereby reducing the size of the R class for that library |
|||
android.nonTransitiveRClass=true |
|||
|
|||
# Disable offline mode for build |
|||
org.gradle.offline=false |
|||
# Android SDK path |
|||
android.sdk.path=/Users/zmt/Library/Android/sdk |
@ -0,0 +1,5 @@ |
|||
distributionBase=GRADLE_USER_HOME |
|||
distributionPath=wrapper/dists |
|||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0-bin.zip |
|||
zipStoreBase=GRADLE_USER_HOME |
|||
zipStorePath=wrapper/dists |
@ -0,0 +1,185 @@ |
|||
#!/usr/bin/env sh |
|||
|
|||
# |
|||
# Copyright 2015 the original author or authors. |
|||
# |
|||
# Licensed under the Apache License, Version 2.0 (the "License"); |
|||
# you may not use this file except in compliance with the License. |
|||
# You may obtain a copy of the License at |
|||
# |
|||
# https://www.apache.org/licenses/LICENSE-2.0 |
|||
# |
|||
# Unless required by applicable law or agreed to in writing, software |
|||
# distributed under the License is distributed on an "AS IS" BASIS, |
|||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
# See the License for the specific language governing permissions and |
|||
# limitations under the License. |
|||
# |
|||
|
|||
############################################################################## |
|||
## |
|||
## Gradle start up script for UN*X |
|||
## |
|||
############################################################################## |
|||
|
|||
# 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\"`/" >/dev/null |
|||
APP_HOME="`pwd -P`" |
|||
cd "$SAVED" >/dev/null |
|||
|
|||
APP_NAME="Gradle" |
|||
APP_BASE_NAME=`basename "$0"` |
|||
|
|||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. |
|||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' |
|||
|
|||
# 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 |
|||
nonstop=false |
|||
case "`uname`" in |
|||
CYGWIN* ) |
|||
cygwin=true |
|||
;; |
|||
Darwin* ) |
|||
darwin=true |
|||
;; |
|||
MINGW* ) |
|||
msys=true |
|||
;; |
|||
NONSTOP* ) |
|||
nonstop=true |
|||
;; |
|||
esac |
|||
|
|||
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" -a "$nonstop" = "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" = "true" ]; then |
|||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" |
|||
fi |
|||
|
|||
# For Cygwin or MSYS, switch paths to Windows format before running java |
|||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then |
|||
APP_HOME=`cygpath --path --mixed "$APP_HOME"` |
|||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` |
|||
|
|||
JAVACMD=`cygpath --unix "$JAVACMD"` |
|||
|
|||
# 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=`expr $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 |
|||
|
|||
# Escape application args |
|||
save () { |
|||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done |
|||
echo " " |
|||
} |
|||
APP_ARGS=`save "$@"` |
|||
|
|||
# Collect all arguments for the java command |
|||
set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" |
|||
|
|||
exec "$JAVACMD" "$@" |
@ -0,0 +1,17 @@ |
|||
pluginManagement { |
|||
repositories { |
|||
google() |
|||
mavenCentral() |
|||
gradlePluginPortal() |
|||
} |
|||
} |
|||
dependencyResolutionManagement { |
|||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) |
|||
repositories { |
|||
google() |
|||
mavenCentral() |
|||
} |
|||
} |
|||
|
|||
rootProject.name = "OxFaceLogin" |
|||
include ':app' |
Write
Preview
Loading…
Cancel
Save
Reference in new issue