feat: 初次提交
1
app/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
63
app/build.gradle.kts
Normal file
@@ -0,0 +1,63 @@
|
||||
plugins {
|
||||
alias(libs.plugins.android.application)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.cariad.cea.aircondition"
|
||||
compileSdk = 34
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.cariad.cea.aircondition"
|
||||
minSdk = 29
|
||||
targetSdk = 34
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = false
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
}
|
||||
|
||||
dataBinding {
|
||||
enable = true
|
||||
}
|
||||
|
||||
viewBinding {
|
||||
enable = true
|
||||
}
|
||||
|
||||
useLibrary("android.car")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.appcompat)
|
||||
implementation(libs.material)
|
||||
implementation(libs.androidx.activity)
|
||||
implementation(libs.androidx.constraintlayout)
|
||||
testImplementation(libs.junit)
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
androidTestImplementation(libs.androidx.espresso.core)
|
||||
implementation(libs.gif.android.gif.drawable)// 支持展示Gif的View
|
||||
}
|
||||
21
app/proguard-rules.pro
vendored
Normal file
@@ -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,24 @@
|
||||
package com.cariad.cea.aircondition
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("com.cariad.cea.aircondition", appContext.packageName)
|
||||
}
|
||||
}
|
||||
26
app/src/main/AndroidManifest.xml
Normal file
@@ -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.AirConditionSetting"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.cariad.cea.aircondition
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import com.cariad.cea.aircondition.databinding.ActivityMainBinding
|
||||
import com.cariad.cea.aircondition.fragments.AirConditionFragment
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
private val bindView by lazy { ActivityMainBinding.inflate(layoutInflater) }
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
setContentView(bindView.main)
|
||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||
insets
|
||||
}
|
||||
|
||||
// 显示空调手势调节的Fragment
|
||||
val transaction = supportFragmentManager.beginTransaction()
|
||||
transaction.add(bindView.layoutAirConditionFragment.id, AirConditionFragment.newInstance())
|
||||
transaction.commit()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.cariad.cea.aircondition.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.cariad.cea.aircondition.databinding.FragmentAirConditionBinding
|
||||
|
||||
/**
|
||||
* @author xiao
|
||||
* 空调设置的Fragment界面
|
||||
*/
|
||||
class AirConditionFragment : Fragment() {
|
||||
private val airConditionBinding by lazy { FragmentAirConditionBinding.inflate(layoutInflater) }
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
// initView()
|
||||
return airConditionBinding.root
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun newInstance() =
|
||||
AirConditionFragment().apply {
|
||||
// arguments = Bundle().apply {
|
||||
// putString(ARG_PARAM1, param1)
|
||||
// putString(ARG_PARAM2, param2)
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.cariad.cea.aircondition.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Camera;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.drawable.AnimationDrawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
|
||||
import pl.droidsonroids.gif.GifImageView;
|
||||
|
||||
public class BaseSimulationWindView extends GifImageView {
|
||||
protected float touchXPosition/*取值范围是-1/2到1/2的宽度*/, touchYPosition/*取值范围是0到-2倍的高度*/; // 当前图片沿X轴翻转和沿Y轴拉伸的初始值,默认都是0
|
||||
protected Bitmap bufferBitmap;
|
||||
protected Canvas bufferCanvas; // 双缓冲方式绘制
|
||||
protected Camera mCamera;
|
||||
protected Paint paint; // 绘制标准线的画笔
|
||||
protected float touchDownX, touchDownY, touchXDistance, touchYDistance;
|
||||
protected float[] srcScale = new float[2];
|
||||
public BaseSimulationWindView(Context context) {
|
||||
super(context);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public BaseSimulationWindView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public BaseSimulationWindView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public BaseSimulationWindView(Context context, AttributeSet attrs, int defStyle, int defStyleRes) {
|
||||
super(context, attrs, defStyle, defStyleRes);
|
||||
init(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
srcScale = preSrcScale();
|
||||
}
|
||||
|
||||
protected void init(Context context) {
|
||||
if (paint == null) {
|
||||
paint = new Paint();
|
||||
paint.setColor(getResources().getColor(android.R.color.holo_green_dark));
|
||||
// 设置抗锯齿
|
||||
paint.setAntiAlias(true);
|
||||
}
|
||||
// BitmapFactory.decodeResource()
|
||||
}
|
||||
|
||||
/**
|
||||
* 因为图片资源可能和ImageView控件不匹配,需要记录初始状态下图片资源在X轴和Y轴被缩放的比例
|
||||
* */
|
||||
protected float[] preSrcScale() {
|
||||
// 首先计算ImageView中图片的大小和ImageView控件的大小比例,缩放该图片
|
||||
AnimationDrawable bitmapDrawable = (AnimationDrawable) getDrawable();
|
||||
Log.d("WindowBottomView", "bitmap-width:"+(bitmapDrawable.getBounds().right-bitmapDrawable.getBounds().left)+" bitmap-height:"+(bitmapDrawable.getBounds().bottom-bitmapDrawable.getBounds().top)+"view-width:"+getWidth()+" view-height:"+getHeight());
|
||||
// 宽度和高度的缩放比例
|
||||
float scaleWidth = (float) getWidth()/(bitmapDrawable.getBounds().right-bitmapDrawable.getBounds().left) ;
|
||||
float scaleHeight = (float) getHeight()/(bitmapDrawable.getBounds().bottom-bitmapDrawable.getBounds().top) ;
|
||||
return new float[]{scaleWidth, scaleHeight};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.cariad.cea.aircondition.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class SimulationWindBottomView extends BaseSimulationWindView {
|
||||
public SimulationWindBottomView(@NonNull Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public SimulationWindBottomView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public SimulationWindBottomView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
touchXPosition = (float) getWidth() /2;
|
||||
touchYPosition = getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
touchDownX = event.getX();
|
||||
touchDownY = event.getY();
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
touchXDistance = event.getX() - touchDownX;
|
||||
touchYDistance = event.getY() - touchDownY;
|
||||
if (touchXPosition + touchXDistance >= getWidth()) {
|
||||
touchXDistance = getWidth() - touchXPosition;
|
||||
} else if (touchXPosition + touchXDistance <= 0) {
|
||||
touchXDistance = 0 - touchXPosition;
|
||||
}
|
||||
|
||||
if (touchYPosition + touchYDistance <= 0) {
|
||||
touchYDistance = 0 - touchYPosition;
|
||||
} else if (touchYPosition + touchYDistance >= getHeight()) {
|
||||
touchYDistance = getHeight() - touchYPosition;
|
||||
}
|
||||
// 根据当前拖动的位置,重绘当前图片
|
||||
invalidate();
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
touchXPosition = touchXPosition+event.getX() - touchDownX;
|
||||
touchYPosition = touchYPosition+event.getY() - touchDownY;
|
||||
touchXDistance = 0f;
|
||||
touchYDistance = 0f;
|
||||
break;
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(@NonNull Canvas canvas) {
|
||||
super.draw(canvas);
|
||||
|
||||
if (bufferBitmap == null) {
|
||||
bufferBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
|
||||
bufferCanvas = new Canvas(bufferBitmap);
|
||||
}
|
||||
float currentTouchPositionX = touchXPosition+touchXDistance;
|
||||
float currentTouchPositionY = touchYPosition+touchYDistance;
|
||||
if (currentTouchPositionX<= 0) {
|
||||
currentTouchPositionX = 0;
|
||||
} else if (currentTouchPositionX>= getWidth()) {
|
||||
currentTouchPositionX = getWidth();
|
||||
}
|
||||
|
||||
if (currentTouchPositionY<= 0) {
|
||||
currentTouchPositionY = 0;
|
||||
} else if (currentTouchPositionY>= getHeight()) {
|
||||
currentTouchPositionY = getHeight();
|
||||
}
|
||||
// // 【0,0】状态下,默认图片显示的是向下展开的图片,点位显示在图片底部正中间
|
||||
// bufferCanvas.drawColor(getResources().getColor(android.R.color.transparent), PorterDuff.Mode.CLEAR);
|
||||
// bufferCanvas.drawCircle(currentTouchPositionX, currentTouchPositionY, 15, paint);
|
||||
|
||||
// 根据当前的虚拟的触摸位置,对当前View通过matrix实现缩放、翻转操作
|
||||
canvas.drawBitmap(bufferBitmap, 0, 0, paint);
|
||||
Matrix matrix = new Matrix();
|
||||
// 根据当前点位,计算View的旋转角度和缩放比例,旋转角度根据X轴的偏移量获取,缩放比例按照Y的偏移量获取
|
||||
float degree = (float) Math.atan2((currentTouchPositionX-(getWidth()/2)), currentTouchPositionY);
|
||||
matrix.setSkew(degree, 0f, getWidth()/2, 0);
|
||||
float scale = currentTouchPositionY / getHeight();
|
||||
matrix.preScale(1, scale, getWidth()/2, 0);
|
||||
// 最开始对图片进行缩放处理,适配当前ImageView控件
|
||||
matrix.preScale(srcScale[0], srcScale[1]);
|
||||
setImageMatrix(matrix);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.cariad.cea.aircondition.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.AnimationDrawable;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
|
||||
import com.cariad.cea.aircondition.R;
|
||||
|
||||
public class SimulationWindLayout extends ConstraintLayout {
|
||||
private View rootView;
|
||||
private SimulationWindBottomView imgSimWindBottom;
|
||||
private SimulationWindTopView imgSimWindTop;
|
||||
private AnimationDrawable bottomAnimation;
|
||||
private AnimationDrawable topAnimation;
|
||||
|
||||
public SimulationWindLayout(@NonNull Context context) {
|
||||
super(context);
|
||||
initView(context, null);
|
||||
}
|
||||
|
||||
public SimulationWindLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initView(context, attrs);
|
||||
}
|
||||
|
||||
public SimulationWindLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
initView(context, attrs);
|
||||
}
|
||||
|
||||
public SimulationWindLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
initView(context, attrs);
|
||||
}
|
||||
|
||||
private void initView(Context context, @Nullable AttributeSet attrs) {
|
||||
View.inflate(context, R.layout.layout_simulation_wind, this);
|
||||
rootView = findViewById(R.id.layout_sim_wind);
|
||||
imgSimWindBottom = findViewById(R.id.img_sim_wind_bottom);
|
||||
imgSimWindTop = findViewById(R.id.img_sim_wind_top);
|
||||
// 启动线程执行动画操作,防止因为动画资源图片太多导致界面卡顿的问题
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (bottomAnimation == null) {
|
||||
bottomAnimation = (AnimationDrawable) imgSimWindBottom.getDrawable();
|
||||
}
|
||||
if (!bottomAnimation.isRunning()) {
|
||||
bottomAnimation.start();
|
||||
}
|
||||
if (topAnimation == null) {
|
||||
topAnimation = (AnimationDrawable) imgSimWindTop.getDrawable();
|
||||
}
|
||||
if (!topAnimation.isRunning()) {
|
||||
topAnimation.start();
|
||||
}
|
||||
handler.sendEmptyMessage(0x101);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
// 设置rootView的touch事件
|
||||
rootView.setOnTouchListener(new OnTouchListener() {
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
imgSimWindBottom.onTouchEvent(event);
|
||||
imgSimWindTop.onTouchEvent(event);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void startAnimation() {
|
||||
if (bottomAnimation == null) {
|
||||
bottomAnimation = (AnimationDrawable) imgSimWindBottom.getDrawable();
|
||||
}
|
||||
if (!bottomAnimation.isRunning()) {
|
||||
bottomAnimation.start();
|
||||
}
|
||||
if (topAnimation == null) {
|
||||
topAnimation = (AnimationDrawable) imgSimWindTop.getDrawable();
|
||||
}
|
||||
if (!topAnimation.isRunning()) {
|
||||
topAnimation.start();
|
||||
}
|
||||
}
|
||||
|
||||
private Handler handler = new Handler(Looper.getMainLooper()){
|
||||
@Override
|
||||
public void handleMessage(@NonNull Message msg) {
|
||||
super.handleMessage(msg);
|
||||
if (msg.what == 0x101) {
|
||||
startAnimation();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.cariad.cea.aircondition.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class SimulationWindTopView extends BaseSimulationWindView {
|
||||
public SimulationWindTopView(@NonNull Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public SimulationWindTopView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public SimulationWindTopView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
// 默认拖动位置是当前图片底部两倍高度的位置(bottom图片的底部中间位置)
|
||||
touchXPosition = (float) getWidth() /2;
|
||||
touchYPosition = getHeight()*2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
touchDownX = event.getX();
|
||||
touchDownY = event.getY();
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
touchXDistance = event.getX() - touchDownX;
|
||||
touchYDistance = event.getY() - touchDownY;
|
||||
if (touchXPosition + touchXDistance >= getWidth()) {
|
||||
touchXDistance = getWidth() - touchXPosition;
|
||||
} else if (touchXPosition + touchXDistance <= 0) {
|
||||
touchXDistance = 0 - touchXPosition;
|
||||
}
|
||||
|
||||
if (touchYPosition + touchYDistance <= 0) {
|
||||
touchYDistance = 0 - touchYPosition;
|
||||
} else if (touchYPosition + touchYDistance >= getHeight()) {
|
||||
touchYDistance = getHeight() - touchYPosition;
|
||||
}
|
||||
// 根据当前拖动的位置,重绘当前图片
|
||||
invalidate();
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
touchXPosition = touchXPosition+event.getX() - touchDownX;
|
||||
touchYPosition = touchYPosition+event.getY() - touchDownY;
|
||||
touchXDistance = 0f;
|
||||
touchYDistance = 0f;
|
||||
break;
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(@NonNull Canvas canvas) {
|
||||
super.draw(canvas);
|
||||
if (bufferBitmap == null) {
|
||||
bufferBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
|
||||
bufferCanvas = new Canvas(bufferBitmap);
|
||||
}
|
||||
float currentTouchPositionX = touchXPosition+touchXDistance;
|
||||
float currentTouchPositionY = touchYPosition+touchYDistance;
|
||||
if (currentTouchPositionX<= 0) {
|
||||
currentTouchPositionX = 0;
|
||||
} else if (currentTouchPositionX>= getWidth()) {
|
||||
currentTouchPositionX = getWidth();
|
||||
}
|
||||
|
||||
if (currentTouchPositionY<= 0) {
|
||||
currentTouchPositionY = 0;
|
||||
} else if (currentTouchPositionY>= getHeight()) {
|
||||
currentTouchPositionY = getHeight();
|
||||
}
|
||||
// // 【0,0】状态下,默认图片显示的是向下展开的图片,点位显示在图片底部正中间
|
||||
// bufferCanvas.drawColor(getResources().getColor(android.R.color.transparent), PorterDuff.Mode.CLEAR);
|
||||
// bufferCanvas.drawCircle(currentTouchPositionX, currentTouchPositionY, 15, paint);
|
||||
|
||||
// 根据当前的虚拟的触摸位置,对当前View通过matrix实现缩放、翻转操作
|
||||
canvas.drawBitmap(bufferBitmap, 0, 0, paint);
|
||||
Matrix matrix = new Matrix();
|
||||
// // 根据当前点位,计算View的旋转角度和缩放比例,旋转角度根据X轴的偏移量获取,缩放比例按照Y的偏移量获取
|
||||
float degree = (float) Math.atan2((currentTouchPositionX-(getWidth()/2)), getHeight()-currentTouchPositionY);
|
||||
if (getHeight()-currentTouchPositionY<=0) { // 如果当前触控点在底部区域,则不需要变形处理
|
||||
degree = 0f;
|
||||
}
|
||||
matrix.setSkew(-degree, 0f, getWidth()/2, getHeight());
|
||||
float scale = (getHeight()-currentTouchPositionY) / getHeight();
|
||||
if (scale < 0 ) {
|
||||
matrix.preScale(1, 0, getWidth()/2, getHeight());
|
||||
} else {
|
||||
matrix.preScale(1, scale, getWidth()/2, getHeight());
|
||||
}
|
||||
// 对图片资源翻转180度
|
||||
matrix.preRotate(180, getWidth()/2, getHeight()/2);
|
||||
// 最开始对图片进行缩放处理,适配当前ImageView控件
|
||||
matrix.preScale(srcScale[0], srcScale[1]);
|
||||
setImageMatrix(matrix);
|
||||
}
|
||||
}
|
||||
BIN
app/src/main/res/drawable/ac_00000.png
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
app/src/main/res/drawable/ac_00001.png
Normal file
|
After Width: | Height: | Size: 105 KiB |
BIN
app/src/main/res/drawable/ac_00002.png
Normal file
|
After Width: | Height: | Size: 105 KiB |
BIN
app/src/main/res/drawable/ac_00003.png
Normal file
|
After Width: | Height: | Size: 105 KiB |
BIN
app/src/main/res/drawable/ac_00004.png
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
app/src/main/res/drawable/ac_00005.png
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
app/src/main/res/drawable/ac_00006.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
app/src/main/res/drawable/ac_00007.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
app/src/main/res/drawable/ac_00008.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
app/src/main/res/drawable/ac_00009.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
app/src/main/res/drawable/ac_00010.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
app/src/main/res/drawable/ac_00011.png
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
app/src/main/res/drawable/ac_00012.png
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
app/src/main/res/drawable/ac_00013.png
Normal file
|
After Width: | Height: | Size: 105 KiB |
BIN
app/src/main/res/drawable/ac_00014.png
Normal file
|
After Width: | Height: | Size: 105 KiB |
BIN
app/src/main/res/drawable/ac_00015.png
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
app/src/main/res/drawable/ac_00016.png
Normal file
|
After Width: | Height: | Size: 109 KiB |
BIN
app/src/main/res/drawable/ac_00017.png
Normal file
|
After Width: | Height: | Size: 109 KiB |
BIN
app/src/main/res/drawable/ac_00018.png
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
app/src/main/res/drawable/ac_00019.png
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
app/src/main/res/drawable/ac_00020.png
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
app/src/main/res/drawable/ac_00021.png
Normal file
|
After Width: | Height: | Size: 109 KiB |
BIN
app/src/main/res/drawable/ac_00022.png
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
app/src/main/res/drawable/ac_00023.png
Normal file
|
After Width: | Height: | Size: 110 KiB |
BIN
app/src/main/res/drawable/ac_00024.png
Normal file
|
After Width: | Height: | Size: 108 KiB |
BIN
app/src/main/res/drawable/ac_00025.png
Normal file
|
After Width: | Height: | Size: 108 KiB |
BIN
app/src/main/res/drawable/ac_00026.png
Normal file
|
After Width: | Height: | Size: 108 KiB |
BIN
app/src/main/res/drawable/ac_00027.png
Normal file
|
After Width: | Height: | Size: 108 KiB |
BIN
app/src/main/res/drawable/ac_00028.png
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
app/src/main/res/drawable/ac_00029.png
Normal file
|
After Width: | Height: | Size: 106 KiB |
94
app/src/main/res/drawable/ac_animation_list.xml
Normal file
@@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:oneshot="false">
|
||||
<item
|
||||
android:drawable="@drawable/ac_00000"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00001"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00002"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00003"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00004"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00005"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00006"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00007"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00008"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00009"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00010"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00011"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00012"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00013"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00014"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00015"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00016"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00017"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00018"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00019"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00020"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00021"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00022"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00023"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00024"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00025"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00026"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00027"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00028"
|
||||
android:duration="70"/>
|
||||
<item
|
||||
android:drawable="@drawable/ac_00029"
|
||||
android:duration="70"/>
|
||||
</animation-list>
|
||||
170
app/src/main/res/drawable/ic_launcher_background.xml
Normal file
@@ -0,0 +1,170 @@
|
||||
<?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="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
||||
30
app/src/main/res/drawable/ic_launcher_foreground.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
||||
15
app/src/main/res/layout/activity_main.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?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:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/layout_air_condition_fragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
21
app/src/main/res/layout/fragment_air_condition.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@mipmap/car_body_air_condition_black_bg"/>
|
||||
<com.cariad.cea.aircondition.views.SimulationWindLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintWidth_percent="0.3"
|
||||
app:layout_constraintHeight_percent="0.6"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
31
app/src/main/res/layout/layout_simulation_wind.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/layout_sim_wind"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
<com.cariad.cea.aircondition.views.SimulationWindTopView
|
||||
android:id="@+id/img_sim_wind_top"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintHeight_percent="0.5"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintWidth_percent="0.5"
|
||||
android:scaleType="matrix"
|
||||
android:src="@drawable/ac_animation_list"/>
|
||||
<com.cariad.cea.aircondition.views.SimulationWindBottomView
|
||||
android:id="@+id/img_sim_wind_bottom"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintHeight_percent="0.5"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintWidth_percent="0.5"
|
||||
android:scaleType="matrix"
|
||||
android:src="@drawable/ac_animation_list"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
6
app/src/main/res/mipmap-anydpi/ic_launcher.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?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" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
6
app/src/main/res/mipmap-anydpi/ic_launcher_round.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?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" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 982 B |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 232 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
7
app/src/main/res/values-night/themes.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Base.Theme.AirConditionSetting" parent="Theme.Material3.DayNight.NoActionBar">
|
||||
<!-- Customize your dark theme here. -->
|
||||
<!-- <item name="colorPrimary">@color/my_dark_primary</item> -->
|
||||
</style>
|
||||
</resources>
|
||||
5
app/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
</resources>
|
||||
3
app/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">AirConditionSetting</string>
|
||||
</resources>
|
||||
9
app/src/main/res/values/themes.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Base.Theme.AirConditionSetting" parent="Theme.Material3.DayNight.NoActionBar">
|
||||
<!-- Customize your light theme here. -->
|
||||
<!-- <item name="colorPrimary">@color/my_light_primary</item> -->
|
||||
</style>
|
||||
|
||||
<style name="Theme.AirConditionSetting" parent="Base.Theme.AirConditionSetting" />
|
||||
</resources>
|
||||
13
app/src/main/res/xml/backup_rules.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?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 31
|
||||
See https://developer.android.com/about/versions/12/backup-restore
|
||||
-->
|
||||
<full-backup-content>
|
||||
<!--
|
||||
<include domain="sharedpref" path="."/>
|
||||
<exclude domain="sharedpref" path="device.xml"/>
|
||||
-->
|
||||
</full-backup-content>
|
||||
19
app/src/main/res/xml/data_extraction_rules.xml
Normal file
@@ -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,17 @@
|
||||
package com.cariad.cea.aircondition
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
class ExampleUnitTest {
|
||||
@Test
|
||||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
||||