@ -1,2 +1,2 @@
|
||||
#Mon Apr 21 08:14:16 CST 2025
|
||||
#Fri Apr 25 19:53:19 CST 2025
|
||||
gradle.version=8.5
|
||||
|
@ -1,2 +1,2 @@
|
||||
#Mon Apr 21 08:12:48 CST 2025
|
||||
#Fri Apr 25 19:53:31 CST 2025
|
||||
java.home=/Applications/Android Studio.app/Contents/jbr/Contents/Home
|
||||
|
@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="WizardSettings">
|
||||
<option name="children">
|
||||
<map>
|
||||
<entry key="imageWizard">
|
||||
<value>
|
||||
<PersistentState />
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
@ -1,607 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DeviceStreaming">
|
||||
<option name="deviceSelectionList">
|
||||
<list>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="27" />
|
||||
<option name="brand" value="DOCOMO" />
|
||||
<option name="codename" value="F01L" />
|
||||
<option name="id" value="F01L" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="FUJITSU" />
|
||||
<option name="name" value="F-01L" />
|
||||
<option name="screenDensity" value="360" />
|
||||
<option name="screenX" value="720" />
|
||||
<option name="screenY" value="1280" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="OnePlus" />
|
||||
<option name="codename" value="OP5552L1" />
|
||||
<option name="id" value="OP5552L1" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="OnePlus" />
|
||||
<option name="name" value="CPH2415" />
|
||||
<option name="screenDensity" value="480" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2412" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="OPPO" />
|
||||
<option name="codename" value="OP573DL1" />
|
||||
<option name="id" value="OP573DL1" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="OPPO" />
|
||||
<option name="name" value="CPH2557" />
|
||||
<option name="screenDensity" value="480" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2400" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="28" />
|
||||
<option name="brand" value="DOCOMO" />
|
||||
<option name="codename" value="SH-01L" />
|
||||
<option name="id" value="SH-01L" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="SHARP" />
|
||||
<option name="name" value="AQUOS sense2 SH-01L" />
|
||||
<option name="screenDensity" value="480" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2160" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="Lenovo" />
|
||||
<option name="codename" value="TB370FU" />
|
||||
<option name="formFactor" value="Tablet" />
|
||||
<option name="id" value="TB370FU" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Lenovo" />
|
||||
<option name="name" value="Tab P12" />
|
||||
<option name="screenDensity" value="340" />
|
||||
<option name="screenX" value="1840" />
|
||||
<option name="screenY" value="2944" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="a15" />
|
||||
<option name="id" value="a15" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="A15" />
|
||||
<option name="screenDensity" value="450" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2340" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="a35x" />
|
||||
<option name="id" value="a35x" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="A35" />
|
||||
<option name="screenDensity" value="450" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2340" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="31" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="a51" />
|
||||
<option name="id" value="a51" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy A51" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2400" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="akita" />
|
||||
<option name="id" value="akita" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 8a" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2400" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="motorola" />
|
||||
<option name="codename" value="arcfox" />
|
||||
<option name="id" value="arcfox" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Motorola" />
|
||||
<option name="name" value="razr plus 2024" />
|
||||
<option name="screenDensity" value="360" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="1272" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="33" />
|
||||
<option name="brand" value="motorola" />
|
||||
<option name="codename" value="austin" />
|
||||
<option name="id" value="austin" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Motorola" />
|
||||
<option name="name" value="moto g 5G (2022)" />
|
||||
<option name="screenDensity" value="280" />
|
||||
<option name="screenX" value="720" />
|
||||
<option name="screenY" value="1600" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="33" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="b0q" />
|
||||
<option name="id" value="b0q" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy S22 Ultra" />
|
||||
<option name="screenDensity" value="600" />
|
||||
<option name="screenX" value="1440" />
|
||||
<option name="screenY" value="3088" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="32" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="bluejay" />
|
||||
<option name="id" value="bluejay" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 6a" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2400" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="caiman" />
|
||||
<option name="id" value="caiman" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 9 Pro" />
|
||||
<option name="screenDensity" value="360" />
|
||||
<option name="screenX" value="960" />
|
||||
<option name="screenY" value="2142" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="comet" />
|
||||
<option name="default" value="true" />
|
||||
<option name="id" value="comet" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 9 Pro Fold" />
|
||||
<option name="screenDensity" value="390" />
|
||||
<option name="screenX" value="2076" />
|
||||
<option name="screenY" value="2152" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="29" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="crownqlteue" />
|
||||
<option name="id" value="crownqlteue" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy Note9" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="2220" />
|
||||
<option name="screenY" value="1080" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="dm2q" />
|
||||
<option name="id" value="dm2q" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="S23 Plus" />
|
||||
<option name="screenDensity" value="450" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2340" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="dm3q" />
|
||||
<option name="id" value="dm3q" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy S23 Ultra" />
|
||||
<option name="screenDensity" value="600" />
|
||||
<option name="screenX" value="1440" />
|
||||
<option name="screenY" value="3088" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="e1q" />
|
||||
<option name="default" value="true" />
|
||||
<option name="id" value="e1q" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy S24" />
|
||||
<option name="screenDensity" value="480" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2340" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="e3q" />
|
||||
<option name="id" value="e3q" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy S24 Ultra" />
|
||||
<option name="screenDensity" value="450" />
|
||||
<option name="screenX" value="1440" />
|
||||
<option name="screenY" value="3120" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="33" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="eos" />
|
||||
<option name="id" value="eos" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Eos" />
|
||||
<option name="screenDensity" value="320" />
|
||||
<option name="screenX" value="384" />
|
||||
<option name="screenY" value="384" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="33" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="felix" />
|
||||
<option name="id" value="felix" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel Fold" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="2208" />
|
||||
<option name="screenY" value="1840" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="felix" />
|
||||
<option name="id" value="felix" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel Fold" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="2208" />
|
||||
<option name="screenY" value="1840" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="33" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="felix_camera" />
|
||||
<option name="id" value="felix_camera" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel Fold (Camera-enabled)" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="2208" />
|
||||
<option name="screenY" value="1840" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="motorola" />
|
||||
<option name="codename" value="fogona" />
|
||||
<option name="id" value="fogona" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Motorola" />
|
||||
<option name="name" value="moto g play - 2024" />
|
||||
<option name="screenDensity" value="280" />
|
||||
<option name="screenX" value="720" />
|
||||
<option name="screenY" value="1600" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="g0q" />
|
||||
<option name="id" value="g0q" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="SM-S906U1" />
|
||||
<option name="screenDensity" value="450" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2340" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="gta9pwifi" />
|
||||
<option name="id" value="gta9pwifi" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="SM-X210" />
|
||||
<option name="screenDensity" value="240" />
|
||||
<option name="screenX" value="1200" />
|
||||
<option name="screenY" value="1920" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="gts7xllite" />
|
||||
<option name="id" value="gts7xllite" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="SM-T738U" />
|
||||
<option name="screenDensity" value="340" />
|
||||
<option name="screenX" value="1600" />
|
||||
<option name="screenY" value="2560" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="33" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="gts8uwifi" />
|
||||
<option name="formFactor" value="Tablet" />
|
||||
<option name="id" value="gts8uwifi" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy Tab S8 Ultra" />
|
||||
<option name="screenDensity" value="320" />
|
||||
<option name="screenX" value="1848" />
|
||||
<option name="screenY" value="2960" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="gts8wifi" />
|
||||
<option name="formFactor" value="Tablet" />
|
||||
<option name="id" value="gts8wifi" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy Tab S8" />
|
||||
<option name="screenDensity" value="274" />
|
||||
<option name="screenX" value="1600" />
|
||||
<option name="screenY" value="2560" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="gts9fe" />
|
||||
<option name="id" value="gts9fe" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy Tab S9 FE 5G" />
|
||||
<option name="screenDensity" value="280" />
|
||||
<option name="screenX" value="1440" />
|
||||
<option name="screenY" value="2304" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="husky" />
|
||||
<option name="id" value="husky" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 8 Pro" />
|
||||
<option name="screenDensity" value="390" />
|
||||
<option name="screenX" value="1008" />
|
||||
<option name="screenY" value="2244" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="30" />
|
||||
<option name="brand" value="motorola" />
|
||||
<option name="codename" value="java" />
|
||||
<option name="id" value="java" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Motorola" />
|
||||
<option name="name" value="G20" />
|
||||
<option name="screenDensity" value="280" />
|
||||
<option name="screenX" value="720" />
|
||||
<option name="screenY" value="1600" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="komodo" />
|
||||
<option name="id" value="komodo" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 9 Pro XL" />
|
||||
<option name="screenDensity" value="360" />
|
||||
<option name="screenX" value="1008" />
|
||||
<option name="screenY" value="2244" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="33" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="lynx" />
|
||||
<option name="id" value="lynx" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 7a" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2400" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="33" />
|
||||
<option name="brand" value="motorola" />
|
||||
<option name="codename" value="maui" />
|
||||
<option name="id" value="maui" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Motorola" />
|
||||
<option name="name" value="moto g play - 2023" />
|
||||
<option name="screenDensity" value="280" />
|
||||
<option name="screenX" value="720" />
|
||||
<option name="screenY" value="1600" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="o1q" />
|
||||
<option name="id" value="o1q" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy S21" />
|
||||
<option name="screenDensity" value="421" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2400" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="31" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="oriole" />
|
||||
<option name="id" value="oriole" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 6" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2400" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="33" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="panther" />
|
||||
<option name="id" value="panther" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 7" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2400" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="q5q" />
|
||||
<option name="id" value="q5q" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy Z Fold5" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1812" />
|
||||
<option name="screenY" value="2176" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="q6q" />
|
||||
<option name="id" value="q6q" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy Z Fold6" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1856" />
|
||||
<option name="screenY" value="2160" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="30" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="r11" />
|
||||
<option name="formFactor" value="Wear OS" />
|
||||
<option name="id" value="r11" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel Watch" />
|
||||
<option name="screenDensity" value="320" />
|
||||
<option name="screenX" value="384" />
|
||||
<option name="screenY" value="384" />
|
||||
<option name="type" value="WEAR_OS" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="r11q" />
|
||||
<option name="id" value="r11q" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="SM-S711U" />
|
||||
<option name="screenDensity" value="450" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2340" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="30" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="redfin" />
|
||||
<option name="id" value="redfin" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 5" />
|
||||
<option name="screenDensity" value="440" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2340" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="shiba" />
|
||||
<option name="id" value="shiba" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 8" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2400" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="t2q" />
|
||||
<option name="id" value="t2q" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy S21 Plus" />
|
||||
<option name="screenDensity" value="394" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2400" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="33" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="tangorpro" />
|
||||
<option name="formFactor" value="Tablet" />
|
||||
<option name="id" value="tangorpro" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel Tablet" />
|
||||
<option name="screenDensity" value="320" />
|
||||
<option name="screenX" value="1600" />
|
||||
<option name="screenY" value="2560" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="tokay" />
|
||||
<option name="default" value="true" />
|
||||
<option name="id" value="tokay" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 9" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2424" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="35" />
|
||||
<option name="brand" value="google" />
|
||||
<option name="codename" value="tokay" />
|
||||
<option name="default" value="true" />
|
||||
<option name="id" value="tokay" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Google" />
|
||||
<option name="name" value="Pixel 9" />
|
||||
<option name="screenDensity" value="420" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2424" />
|
||||
</PersistentDeviceSelectionData>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RenderSettings">
|
||||
<option name="showDecorations" value="true" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,120 @@
|
||||
package org.tensorflow.lite.examples.poseestimation
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.MotionEvent
|
||||
import android.widget.ImageButton
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import kotlin.math.abs
|
||||
|
||||
class AgeSelectionActivity : AppCompatActivity() {
|
||||
private lateinit var selectedAgeText: TextView
|
||||
private lateinit var age1Above: TextView
|
||||
private lateinit var age2Above: TextView
|
||||
private lateinit var age1Below: TextView
|
||||
private lateinit var age2Below: TextView
|
||||
private lateinit var nextButton: MaterialButton
|
||||
private lateinit var backButton: ImageButton
|
||||
private var selectedGender: String? = null
|
||||
|
||||
private var currentAge = 25
|
||||
private val minAge = 12
|
||||
private val maxAge = 90
|
||||
|
||||
private var lastY: Float = 0f
|
||||
private val scrollSensitivity = 15f // 调整这个值可以改变滑动灵敏度
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_age_selection)
|
||||
|
||||
selectedGender = intent.getStringExtra("selected_gender")
|
||||
|
||||
selectedAgeText = findViewById(R.id.selectedAgeText)
|
||||
age1Above = findViewById(R.id.age1Above)
|
||||
age2Above = findViewById(R.id.age2Above)
|
||||
age1Below = findViewById(R.id.age1Below)
|
||||
age2Below = findViewById(R.id.age2Below)
|
||||
nextButton = findViewById(R.id.nextButton)
|
||||
backButton = findViewById(R.id.backButton)
|
||||
|
||||
setupUI()
|
||||
setupClickListeners()
|
||||
}
|
||||
|
||||
private fun setupUI() {
|
||||
updateAgeDisplay()
|
||||
nextButton.isEnabled = true
|
||||
}
|
||||
|
||||
private fun updateAgeDisplay() {
|
||||
selectedAgeText.text = currentAge.toString()
|
||||
|
||||
// 更新上方年龄(显示较小的数字)
|
||||
if (currentAge - 1 >= minAge) {
|
||||
age1Above.text = (currentAge - 1).toString()
|
||||
} else {
|
||||
age1Above.text = ""
|
||||
}
|
||||
if (currentAge - 2 >= minAge) {
|
||||
age2Above.text = (currentAge - 2).toString()
|
||||
} else {
|
||||
age2Above.text = ""
|
||||
}
|
||||
|
||||
// 更新下方年龄(显示较大的数字)
|
||||
if (currentAge + 1 <= maxAge) {
|
||||
age1Below.text = (currentAge + 1).toString()
|
||||
} else {
|
||||
age1Below.text = ""
|
||||
}
|
||||
if (currentAge + 2 <= maxAge) {
|
||||
age2Below.text = (currentAge + 2).toString()
|
||||
} else {
|
||||
age2Below.text = ""
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupClickListeners() {
|
||||
nextButton.setOnClickListener {
|
||||
val intent = Intent(this, WeightSelectionActivity::class.java)
|
||||
intent.putExtra("selected_gender", selectedGender)
|
||||
intent.putExtra("selected_age", currentAge)
|
||||
startActivity(intent)
|
||||
finish()
|
||||
}
|
||||
|
||||
backButton.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
lastY = event.y
|
||||
return true
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
val currentY = event.y
|
||||
val deltaY = currentY - lastY
|
||||
|
||||
// 计算应该改变多少年龄
|
||||
val change = -(deltaY / scrollSensitivity).toInt()
|
||||
if (abs(change) > 0) {
|
||||
// 更新年龄
|
||||
val newAge = (currentAge + change).coerceIn(minAge, maxAge)
|
||||
if (newAge != currentAge) {
|
||||
currentAge = newAge
|
||||
updateAgeDisplay()
|
||||
lastY = currentY
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
return super.onTouchEvent(event)
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package org.tensorflow.lite.examples.poseestimation
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Path
|
||||
import android.util.AttributeSet
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import androidx.core.content.ContextCompat
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
class CustomWeightPicker @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : View(context, attrs, defStyleAttr) {
|
||||
|
||||
private val paint = Paint().apply {
|
||||
isAntiAlias = true
|
||||
color = ContextCompat.getColor(context, R.color.purple_500)
|
||||
}
|
||||
|
||||
private val path = Path()
|
||||
private var lastX = 0f
|
||||
private var scrollOffset = 0f
|
||||
private var selectedWeight = 54
|
||||
private val minWeight = 30
|
||||
private val maxWeight = 200
|
||||
private val scaleWidth = 40f // 每个刻度的宽度
|
||||
private val scaleHeight = 20f // 刻度的高度
|
||||
private val centerLineWidth = 2f
|
||||
|
||||
private var onWeightChangeListener: ((Int) -> Unit)? = null
|
||||
|
||||
override fun onDraw(canvas: Canvas) {
|
||||
super.onDraw(canvas)
|
||||
|
||||
val centerX = width / 2f
|
||||
val centerY = height / 2f
|
||||
|
||||
// 绘制刻度
|
||||
val startX = centerX + scrollOffset
|
||||
val startWeight = selectedWeight - (centerX / scaleWidth).toInt()
|
||||
|
||||
for (i in -10..10) {
|
||||
val x = startX + i * scaleWidth
|
||||
val weight = startWeight + i
|
||||
|
||||
if (weight in minWeight..maxWeight) {
|
||||
// 绘制刻度线
|
||||
canvas.drawLine(
|
||||
x,
|
||||
centerY - scaleHeight,
|
||||
x,
|
||||
centerY + scaleHeight,
|
||||
paint
|
||||
)
|
||||
|
||||
// 绘制刻度值
|
||||
if (i % 2 == 0) {
|
||||
canvas.drawText(
|
||||
weight.toString(),
|
||||
x - 10f,
|
||||
centerY + scaleHeight + 20f,
|
||||
paint
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
lastX = event.x
|
||||
return true
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
val deltaX = event.x - lastX
|
||||
scrollOffset += deltaX
|
||||
|
||||
// 计算新的体重值
|
||||
val newWeight = selectedWeight - (deltaX / scaleWidth).toInt()
|
||||
if (newWeight in minWeight..maxWeight) {
|
||||
selectedWeight = newWeight
|
||||
onWeightChangeListener?.invoke(selectedWeight)
|
||||
}
|
||||
|
||||
lastX = event.x
|
||||
invalidate()
|
||||
return true
|
||||
}
|
||||
}
|
||||
return super.onTouchEvent(event)
|
||||
}
|
||||
|
||||
fun setOnWeightChangeListener(listener: (Int) -> Unit) {
|
||||
onWeightChangeListener = listener
|
||||
}
|
||||
|
||||
fun getSelectedWeight(): Int = selectedWeight
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package org.tensorflow.lite.examples.poseestimation
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.cardview.widget.CardView
|
||||
import com.google.android.material.button.MaterialButton
|
||||
|
||||
class GenderSelectionActivity : AppCompatActivity() {
|
||||
private lateinit var maleButton: CardView
|
||||
private lateinit var femaleButton: CardView
|
||||
private lateinit var maleText: TextView
|
||||
private lateinit var femaleText: TextView
|
||||
private lateinit var nextButton: MaterialButton
|
||||
private var selectedGender: String? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_gender_selection)
|
||||
|
||||
maleButton = findViewById(R.id.maleButton)
|
||||
femaleButton = findViewById(R.id.femaleButton)
|
||||
maleText = findViewById(R.id.maleText)
|
||||
femaleText = findViewById(R.id.femaleText)
|
||||
nextButton = findViewById(R.id.nextButton)
|
||||
|
||||
setupClickListeners()
|
||||
}
|
||||
|
||||
private fun setupClickListeners() {
|
||||
maleButton.setOnClickListener {
|
||||
updateSelection("male")
|
||||
}
|
||||
|
||||
femaleButton.setOnClickListener {
|
||||
updateSelection("female")
|
||||
}
|
||||
|
||||
nextButton.setOnClickListener {
|
||||
// 跳转到年龄选择页面,并传递性别信息
|
||||
val intent = Intent(this, AgeSelectionActivity::class.java)
|
||||
intent.putExtra("selected_gender", selectedGender)
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateSelection(gender: String) {
|
||||
selectedGender = gender
|
||||
|
||||
// 更新UI状态
|
||||
when (gender) {
|
||||
"male" -> {
|
||||
maleButton.setCardBackgroundColor(getColor(android.R.color.holo_purple))
|
||||
femaleButton.setCardBackgroundColor(getColor(android.R.color.darker_gray))
|
||||
maleText.setTextColor(getColor(android.R.color.holo_purple))
|
||||
femaleText.setTextColor(getColor(android.R.color.white))
|
||||
}
|
||||
"female" -> {
|
||||
femaleButton.setCardBackgroundColor(getColor(android.R.color.holo_purple))
|
||||
maleButton.setCardBackgroundColor(getColor(android.R.color.darker_gray))
|
||||
femaleText.setTextColor(getColor(android.R.color.holo_purple))
|
||||
maleText.setTextColor(getColor(android.R.color.white))
|
||||
}
|
||||
}
|
||||
|
||||
// 启用Next按钮
|
||||
nextButton.isEnabled = true
|
||||
}
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
package org.tensorflow.lite.examples.poseestimation
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.MotionEvent
|
||||
import android.widget.ImageButton
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import kotlin.math.abs
|
||||
|
||||
class HeightSelectionActivity : AppCompatActivity() {
|
||||
private lateinit var selectedHeightText: TextView
|
||||
private lateinit var heightUnit: TextView
|
||||
private lateinit var height1Above: TextView
|
||||
private lateinit var height2Above: TextView
|
||||
private lateinit var height1Below: TextView
|
||||
private lateinit var height2Below: TextView
|
||||
private lateinit var nextButton: MaterialButton
|
||||
private lateinit var backButton: ImageButton
|
||||
private var selectedGender: String? = null
|
||||
private var selectedAge: Int = 0
|
||||
private var selectedWeight: Int = 0
|
||||
|
||||
private var currentHeight = 167
|
||||
private val minHeight = 100
|
||||
private val maxHeight = 220
|
||||
|
||||
private var lastY: Float = 0f
|
||||
private val scrollSensitivity = 15f // 调整这个值可以改变滑动灵敏度
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_height_selection)
|
||||
|
||||
selectedGender = intent.getStringExtra("selected_gender")
|
||||
selectedAge = intent.getIntExtra("selected_age", 0)
|
||||
selectedWeight = intent.getIntExtra("selected_weight", 0)
|
||||
|
||||
selectedHeightText = findViewById(R.id.selectedHeightText)
|
||||
heightUnit = findViewById(R.id.heightUnit)
|
||||
height1Above = findViewById(R.id.height1Above)
|
||||
height2Above = findViewById(R.id.height2Above)
|
||||
height1Below = findViewById(R.id.height1Below)
|
||||
height2Below = findViewById(R.id.height2Below)
|
||||
nextButton = findViewById(R.id.nextButton)
|
||||
backButton = findViewById(R.id.backButton)
|
||||
|
||||
setupUI()
|
||||
setupClickListeners()
|
||||
}
|
||||
|
||||
private fun setupUI() {
|
||||
updateHeightDisplay()
|
||||
nextButton.isEnabled = true
|
||||
}
|
||||
|
||||
private fun updateHeightDisplay() {
|
||||
selectedHeightText.text = currentHeight.toString()
|
||||
// 上方身高
|
||||
if (currentHeight - 1 >= minHeight) {
|
||||
height1Above.text = (currentHeight - 1).toString()
|
||||
} else {
|
||||
height1Above.text = ""
|
||||
}
|
||||
if (currentHeight - 2 >= minHeight) {
|
||||
height2Above.text = (currentHeight - 2).toString()
|
||||
} else {
|
||||
height2Above.text = ""
|
||||
}
|
||||
// 下方身高
|
||||
if (currentHeight + 1 <= maxHeight) {
|
||||
height1Below.text = (currentHeight + 1).toString()
|
||||
} else {
|
||||
height1Below.text = ""
|
||||
}
|
||||
if (currentHeight + 2 <= maxHeight) {
|
||||
height2Below.text = (currentHeight + 2).toString()
|
||||
} else {
|
||||
height2Below.text = ""
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupClickListeners() {
|
||||
nextButton.setOnClickListener {
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
intent.putExtra("selected_gender", selectedGender)
|
||||
intent.putExtra("selected_age", selectedAge)
|
||||
intent.putExtra("selected_weight", selectedWeight)
|
||||
intent.putExtra("selected_height", currentHeight)
|
||||
startActivity(intent)
|
||||
finish()
|
||||
}
|
||||
|
||||
backButton.setOnClickListener {
|
||||
val intent = Intent(this, WeightSelectionActivity::class.java)
|
||||
intent.putExtra("selected_gender", selectedGender)
|
||||
intent.putExtra("selected_age", selectedAge)
|
||||
intent.putExtra("selected_weight", selectedWeight)
|
||||
startActivity(intent)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
lastY = event.y
|
||||
return true
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
val currentY = event.y
|
||||
val deltaY = currentY - lastY
|
||||
val change = -(deltaY / scrollSensitivity).toInt()
|
||||
if (abs(change) > 0) {
|
||||
val newHeight = (currentHeight + change).coerceIn(minHeight, maxHeight)
|
||||
if (newHeight != currentHeight) {
|
||||
currentHeight = newHeight
|
||||
updateHeightDisplay()
|
||||
lastY = currentY
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
return super.onTouchEvent(event)
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package org.tensorflow.lite.examples.poseestimation
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
|
||||
class Onboarding1Fragment : Fragment() {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
return inflater.inflate(R.layout.activity_onboarding1, container, false)
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package org.tensorflow.lite.examples.poseestimation
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
|
||||
class Onboarding2Fragment : Fragment() {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
return inflater.inflate(R.layout.activity_onboarding2, container, false)
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package org.tensorflow.lite.examples.poseestimation
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import androidx.fragment.app.Fragment
|
||||
|
||||
class Onboarding3Fragment : Fragment() {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val view = inflater.inflate(R.layout.activity_onboarding3, container, false)
|
||||
|
||||
// 找到Start now按钮并设置点击事件
|
||||
val startButton = view.findViewById<FrameLayout>(R.id.small_butto_container)
|
||||
startButton.setOnClickListener {
|
||||
// 跳转到性别选择页面
|
||||
val intent = Intent(requireActivity(), GenderSelectionActivity::class.java)
|
||||
startActivity(intent)
|
||||
requireActivity().finish() // 结束当前的OnboardingActivity
|
||||
}
|
||||
|
||||
return view
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package org.tensorflow.lite.examples.poseestimation
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
|
||||
class OnboardingActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_onboarding)
|
||||
|
||||
val viewPager = findViewById<ViewPager2>(R.id.viewPager)
|
||||
viewPager.adapter = OnboardingAdapter(this)
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package org.tensorflow.lite.examples.poseestimation
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
|
||||
class OnboardingAdapter(activity: FragmentActivity) : FragmentStateAdapter(activity) {
|
||||
override fun getItemCount(): Int = 3
|
||||
|
||||
override fun createFragment(position: Int): Fragment {
|
||||
return when (position) {
|
||||
0 -> Onboarding1Fragment()
|
||||
1 -> Onboarding2Fragment()
|
||||
2 -> Onboarding3Fragment()
|
||||
else -> Onboarding1Fragment()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
package org.tensorflow.lite.examples.poseestimation
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.MotionEvent
|
||||
import android.widget.ImageButton
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import kotlin.math.abs
|
||||
|
||||
class WeightSelectionActivity : AppCompatActivity() {
|
||||
private lateinit var selectedWeightText: TextView
|
||||
private lateinit var weight1Above: TextView
|
||||
private lateinit var weight2Above: TextView
|
||||
private lateinit var weight1Below: TextView
|
||||
private lateinit var weight2Below: TextView
|
||||
private lateinit var nextButton: MaterialButton
|
||||
private lateinit var backButton: ImageButton
|
||||
|
||||
private var selectedGender: String? = null
|
||||
private var selectedAge: Int = 0
|
||||
private var currentWeight = 54
|
||||
|
||||
private var lastY: Float = 0f
|
||||
private val scrollSensitivity = 15f // 调整这个值可以改变滑动灵敏度
|
||||
private val minWeight = 30
|
||||
private val maxWeight = 200
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_weight_selection)
|
||||
|
||||
// 获取从上一个页面传递的数据
|
||||
selectedGender = intent.getStringExtra("selected_gender")
|
||||
selectedAge = intent.getIntExtra("selected_age", 0)
|
||||
|
||||
// 初始化视图
|
||||
selectedWeightText = findViewById(R.id.selectedWeightText)
|
||||
weight1Above = findViewById(R.id.weight1Above)
|
||||
weight2Above = findViewById(R.id.weight2Above)
|
||||
weight1Below = findViewById(R.id.weight1Below)
|
||||
weight2Below = findViewById(R.id.weight2Below)
|
||||
nextButton = findViewById(R.id.nextButton)
|
||||
backButton = findViewById(R.id.backButton)
|
||||
|
||||
setupUI()
|
||||
setupClickListeners()
|
||||
}
|
||||
|
||||
private fun setupUI() {
|
||||
updateWeightDisplay()
|
||||
nextButton.isEnabled = true
|
||||
}
|
||||
|
||||
private fun updateWeightDisplay() {
|
||||
selectedWeightText.text = currentWeight.toString()
|
||||
|
||||
// 更新上方体重(显示较小的数字)
|
||||
if (currentWeight - 1 >= minWeight) {
|
||||
weight1Above.text = (currentWeight - 1).toString()
|
||||
} else {
|
||||
weight1Above.text = ""
|
||||
}
|
||||
if (currentWeight - 2 >= minWeight) {
|
||||
weight2Above.text = (currentWeight - 2).toString()
|
||||
} else {
|
||||
weight2Above.text = ""
|
||||
}
|
||||
|
||||
// 更新下方体重(显示较大的数字)
|
||||
if (currentWeight + 1 <= maxWeight) {
|
||||
weight1Below.text = (currentWeight + 1).toString()
|
||||
} else {
|
||||
weight1Below.text = ""
|
||||
}
|
||||
if (currentWeight + 2 <= maxWeight) {
|
||||
weight2Below.text = (currentWeight + 2).toString()
|
||||
} else {
|
||||
weight2Below.text = ""
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupClickListeners() {
|
||||
nextButton.setOnClickListener {
|
||||
val intent = Intent(this, HeightSelectionActivity::class.java)
|
||||
intent.putExtra("selected_gender", selectedGender)
|
||||
intent.putExtra("selected_age", selectedAge)
|
||||
intent.putExtra("selected_weight", currentWeight)
|
||||
startActivity(intent)
|
||||
finish()
|
||||
}
|
||||
|
||||
backButton.setOnClickListener {
|
||||
val intent = Intent(this, AgeSelectionActivity::class.java)
|
||||
intent.putExtra("selected_gender", selectedGender)
|
||||
startActivity(intent)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
lastY = event.y
|
||||
return true
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
val currentY = event.y
|
||||
val deltaY = currentY - lastY
|
||||
|
||||
// 计算应该改变多少体重
|
||||
val change = -(deltaY / scrollSensitivity).toInt()
|
||||
if (abs(change) > 0) {
|
||||
// 更新体重
|
||||
val newWeight = (currentWeight + change).coerceIn(minWeight, maxWeight)
|
||||
if (newWeight != currentWeight) {
|
||||
currentWeight = newWeight
|
||||
updateWeightDisplay()
|
||||
lastY = currentY
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
return super.onTouchEvent(event)
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<solid android:color="#333333" />
|
||||
</shape>
|
After Width: | Height: | Size: 647 B |
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
|
||||
</vector>
|
After Width: | Height: | Size: 171 B |
After Width: | Height: | Size: 173 B |
After Width: | Height: | Size: 165 B |
After Width: | Height: | Size: 768 B |
After Width: | Height: | Size: 957 KiB |
After Width: | Height: | Size: 1.1 MiB |
After Width: | Height: | Size: 1.5 MiB |
@ -0,0 +1,18 @@
|
||||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="185dp"
|
||||
android:height="50dp"
|
||||
android:viewportWidth="185"
|
||||
android:viewportHeight="50"
|
||||
>
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M25 0H160C173.807 0 185 11.1929 185 25C185 38.8071 173.807 50 160 50H25C11.1929 50 0 38.8071 0 25C0 11.1929 11.1929 0 25 0Z"
|
||||
/>
|
||||
<path
|
||||
android:pathData="M0 0V50H185V0"
|
||||
android:fillColor="#BF5AF2"
|
||||
/>
|
||||
</group>
|
||||
</vector>
|
@ -0,0 +1,14 @@
|
||||
<!-- drawable/vector.xml -->
|
||||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="269.5dp"
|
||||
android:height="63.46dp"
|
||||
android:viewportWidth="269.5"
|
||||
android:viewportHeight="63.46">
|
||||
<path
|
||||
android:pathData="M269.5,0 L0,63.46"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#BF5AF2"
|
||||
android:fillColor="@android:color/transparent"/>
|
||||
</vector>
|
||||
|
@ -0,0 +1 @@
|
||||
// 该文件仅用于占位,实际字体文件请放在本目录下。
|
@ -0,0 +1,147 @@
|
||||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/black">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="64dp"
|
||||
android:text="How old are you?"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="28sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/subtitleText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="This helps us create your personalized plan"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#808080"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/titleText" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/agePickerContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/nextButton"
|
||||
app:layout_constraintTop_toBottomOf="@id/subtitleText">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/age2Above"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#404040"
|
||||
android:textSize="60sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@id/age1Above"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/age1Above"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#808080"
|
||||
android:textSize="80sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@id/selectedAgeText"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/selectedAgeText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="100sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/age1Below"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#808080"
|
||||
android:textSize="80sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toBottomOf="@id/selectedAgeText"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/age2Below"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#404040"
|
||||
android:textSize="60sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toBottomOf="@id/age1Below"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<View
|
||||
android:id="@+id/topDivider"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="4dp"
|
||||
android:background="#BF5AF2"
|
||||
app:layout_constraintBottom_toTopOf="@id/selectedAgeText"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginBottom="0dp" />
|
||||
|
||||
<View
|
||||
android:id="@+id/bottomDivider"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="4dp"
|
||||
android:background="#BF5AF2"
|
||||
app:layout_constraintTop_toBottomOf="@id/selectedAgeText"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginTop="0dp" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/backButton"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:background="@drawable/circle_button_background"
|
||||
android:src="@drawable/ic_back"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/nextButton"
|
||||
android:layout_width="141dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:text="Next"
|
||||
android:textSize="17sp"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="#FFFFFF"
|
||||
app:backgroundTint="#BF5AF2"
|
||||
app:cornerRadius="25dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -0,0 +1,112 @@
|
||||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/black">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="64dp"
|
||||
android:text="Tell us about yourself!"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="28sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/subtitleText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="To give you a better experience we need\nto know your gender"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#808080"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/titleText" />
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/maleButton"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="120dp"
|
||||
android:layout_marginTop="64dp"
|
||||
app:cardBackgroundColor="#333333"
|
||||
app:cardCornerRadius="60dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/subtitleText">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/maleIcon"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/male" />
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/maleText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="Male"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintEnd_toEndOf="@id/maleButton"
|
||||
app:layout_constraintStart_toStartOf="@id/maleButton"
|
||||
app:layout_constraintTop_toBottomOf="@id/maleButton" />
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/femaleButton"
|
||||
android:layout_width="120dp"
|
||||
android:layout_height="120dp"
|
||||
android:layout_marginTop="32dp"
|
||||
app:cardBackgroundColor="#333333"
|
||||
app:cardCornerRadius="60dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/maleText">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/femaleIcon"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/female" />
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/femaleText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="Female"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintEnd_toEndOf="@id/femaleButton"
|
||||
app:layout_constraintStart_toStartOf="@id/femaleButton"
|
||||
app:layout_constraintTop_toBottomOf="@id/femaleButton" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/nextButton"
|
||||
android:layout_width="141dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:enabled="false"
|
||||
android:text="Next"
|
||||
android:textSize="17sp"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="#FFFFFF"
|
||||
app:backgroundTint="#BF5AF2"
|
||||
app:cornerRadius="25dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -0,0 +1,170 @@
|
||||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/black">
|
||||
|
||||
<!-- 标题 -->
|
||||
<TextView
|
||||
android:id="@+id/heightTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="80dp"
|
||||
android:text="What's your height?"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<!-- 副标题 -->
|
||||
<TextView
|
||||
android:id="@+id/heightSubtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="This helps us create your personalized plan"
|
||||
android:textColor="#808080"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/heightTitle" />
|
||||
|
||||
<!-- 身高选择器容器 -->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/heightPickerContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/nextButton"
|
||||
app:layout_constraintTop_toBottomOf="@id/heightSubtitle">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/height2Above"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#404040"
|
||||
android:textSize="60sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@id/height1Above"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/height1Above"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#808080"
|
||||
android:textSize="80sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@id/heightDisplayContainer"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<!-- 当前身高和单位 -->
|
||||
<LinearLayout
|
||||
android:id="@+id/heightDisplayContainer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/selectedHeightText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="167"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="100sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/heightUnit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:text="cm"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="32sp"
|
||||
android:textStyle="normal" />
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/height1Below"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#808080"
|
||||
android:textSize="80sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toBottomOf="@id/heightDisplayContainer"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/height2Below"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#404040"
|
||||
android:textSize="60sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toBottomOf="@id/height1Below"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<View
|
||||
android:id="@+id/topDivider"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="4dp"
|
||||
android:background="#BF5AF2"
|
||||
app:layout_constraintBottom_toTopOf="@id/heightDisplayContainer"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginBottom="0dp" />
|
||||
|
||||
<View
|
||||
android:id="@+id/bottomDivider"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="4dp"
|
||||
android:background="#BF5AF2"
|
||||
app:layout_constraintTop_toBottomOf="@id/heightDisplayContainer"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginTop="0dp" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<!-- 底部按钮区域 -->
|
||||
<ImageButton
|
||||
android:id="@+id/backButton"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:background="@drawable/circle_button_background"
|
||||
android:src="@drawable/ic_back"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/nextButton"
|
||||
android:layout_width="141dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:text="Next"
|
||||
android:textSize="17sp"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="#FFFFFF"
|
||||
app:backgroundTint="#BF5AF2"
|
||||
app:cornerRadius="25dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -0,0 +1,12 @@
|
||||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/viewPager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -0,0 +1,51 @@
|
||||
<?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"
|
||||
android:id="@+id/onboarding1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#1C1C1E">
|
||||
|
||||
<!-- 图片自适应宽度,顶部贴屏幕,比例不变 -->
|
||||
<ImageView
|
||||
android:id="@+id/onboarding1_man"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/onboarding1_man"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintDimensionRatio="417:515"
|
||||
app:layout_constraintWidth_default="percent"
|
||||
app:layout_constraintWidth_percent="1.0"/>
|
||||
|
||||
<!-- 指示器,底部居中 -->
|
||||
<ImageView
|
||||
android:id="@+id/indicator1"
|
||||
android:layout_width="88dp"
|
||||
android:layout_height="4dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:src="@drawable/indicator1"
|
||||
android:scaleType="fitXY" />
|
||||
|
||||
<!-- 文本,图片下方居中 -->
|
||||
<TextView
|
||||
android:id="@+id/meet_your_c"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@id/onboarding1_man"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:textSize="28sp"
|
||||
android:textColor="#FFFFFF"
|
||||
android:text="@string/meet_your_c"
|
||||
android:lineSpacingExtra="-4sp"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="16dp" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -0,0 +1,51 @@
|
||||
<?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"
|
||||
android:id="@+id/onboarding2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#1C1C1E">
|
||||
|
||||
<!-- 图片自适应宽度,顶部贴屏幕,比例不变 -->
|
||||
<ImageView
|
||||
android:id="@+id/onboarding2_woman"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/onboarding2_woman"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintDimensionRatio="417:515"
|
||||
app:layout_constraintWidth_default="percent"
|
||||
app:layout_constraintWidth_percent="1.0"/>
|
||||
|
||||
<!-- 指示器,底部居中 -->
|
||||
<ImageView
|
||||
android:id="@+id/indicator2"
|
||||
android:layout_width="88dp"
|
||||
android:layout_height="4dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:src="@drawable/indicator2"
|
||||
android:scaleType="fitXY" />
|
||||
|
||||
<!-- 文本,图片下方居中 -->
|
||||
<TextView
|
||||
android:id="@+id/create_a_wo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@id/onboarding2_woman"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:textSize="28sp"
|
||||
android:textColor="#FFFFFF"
|
||||
android:text="@string/create_a_wo"
|
||||
android:lineSpacingExtra="-4sp"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="16dp" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -0,0 +1,82 @@
|
||||
<?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"
|
||||
android:id="@+id/onboarding3"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#1C1C1E">
|
||||
|
||||
<!-- 图片自适应宽度,顶部贴屏幕,比例不变 -->
|
||||
<ImageView
|
||||
android:id="@+id/onboarding3_man"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/onboarding3_man"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintDimensionRatio="417:515"
|
||||
app:layout_constraintWidth_default="percent"
|
||||
app:layout_constraintWidth_percent="1.0"
|
||||
android:contentDescription="@null"/>
|
||||
|
||||
<!-- 指示器,底部居中 -->
|
||||
<ImageView
|
||||
android:id="@+id/indicator3"
|
||||
android:layout_width="88dp"
|
||||
android:layout_height="4dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:src="@drawable/indicator3"
|
||||
android:scaleType="fitXY"
|
||||
android:contentDescription="@null"/>
|
||||
|
||||
<!-- 文本,图片下方居中 -->
|
||||
<TextView
|
||||
android:id="@+id/action_is_t"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@id/onboarding3_man"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:textSize="28sp"
|
||||
android:textColor="#FFFFFF"
|
||||
android:text="@string/action_is_t"
|
||||
android:lineSpacingExtra="-4sp"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="16dp" />
|
||||
|
||||
<!-- small_butto按钮和文字叠加 -->
|
||||
<FrameLayout
|
||||
android:id="@+id/small_butto_container"
|
||||
android:layout_width="185dp"
|
||||
android:layout_height="50dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/action_is_t"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginTop="16dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/small_butto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/small_butto"
|
||||
android:contentDescription="@null"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sign_up"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/sign_up"
|
||||
android:textSize="17sp"
|
||||
android:textColor="#FFFFFF"
|
||||
android:gravity="center" />
|
||||
</FrameLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Auto layout, variables, and unit scale are not yet supported -->
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/splash"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#1C1C1E">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/some_id"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:gravity="center"
|
||||
android:lineSpacingExtra="28sp"
|
||||
android:text="@string/some_id"
|
||||
android:textSize="48sp"
|
||||
android:textColor="#BF5AF2"
|
||||
android:translationY="-13.95sp" />
|
||||
|
||||
<View
|
||||
android:id="@+id/vector1"
|
||||
android:layout_width="268.5dp"
|
||||
android:layout_height="62.46dp"
|
||||
android:background="@drawable/vector" />
|
||||
|
||||
<View
|
||||
android:id="@+id/vector2"
|
||||
android:layout_width="268.5dp"
|
||||
android:layout_height="62.46dp"
|
||||
android:background="@drawable/vector" />
|
||||
|
||||
</RelativeLayout>
|
@ -0,0 +1,151 @@
|
||||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/black">
|
||||
|
||||
<!-- 标题 -->
|
||||
<TextView
|
||||
android:id="@+id/weightTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="80dp"
|
||||
android:text="What's your weight?"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<!-- 副标题 -->
|
||||
<TextView
|
||||
android:id="@+id/weightSubtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="You can always change this later"
|
||||
android:textColor="#808080"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/weightTitle" />
|
||||
|
||||
<!-- 体重选择器容器 -->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/weightPickerContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/nextButton"
|
||||
app:layout_constraintTop_toBottomOf="@id/weightSubtitle">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/weight2Above"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#404040"
|
||||
android:textSize="60sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@id/weight1Above"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/weight1Above"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#808080"
|
||||
android:textSize="80sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@id/selectedWeightText"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/selectedWeightText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="54"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="100sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/weight1Below"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#808080"
|
||||
android:textSize="80sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toBottomOf="@id/selectedWeightText"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/weight2Below"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#404040"
|
||||
android:textSize="60sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toBottomOf="@id/weight1Below"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<View
|
||||
android:id="@+id/topDivider"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="4dp"
|
||||
android:background="#BF5AF2"
|
||||
app:layout_constraintBottom_toTopOf="@id/selectedWeightText"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginBottom="0dp" />
|
||||
|
||||
<View
|
||||
android:id="@+id/bottomDivider"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="4dp"
|
||||
android:background="#BF5AF2"
|
||||
app:layout_constraintTop_toBottomOf="@id/selectedWeightText"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginTop="0dp" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<!-- 底部按钮区域 -->
|
||||
<ImageButton
|
||||
android:id="@+id/backButton"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:background="@drawable/circle_button_background"
|
||||
android:src="@drawable/ic_back"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/nextButton"
|
||||
android:layout_width="141dp"
|
||||
android:layout_height="50dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:text="Next"
|
||||
android:textSize="17sp"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="#FFFFFF"
|
||||
app:backgroundTint="#BF5AF2"
|
||||
app:cornerRadius="25dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -0,0 +1,2 @@
|
||||
#Mon Apr 21 08:14:16 CST 2025
|
||||
gradle.version=8.5
|
@ -0,0 +1,2 @@
|
||||
#Mon Apr 21 08:12:48 CST 2025
|
||||
java.home=/Applications/Android Studio.app/Contents/jbr/Contents/Home
|
@ -0,0 +1,3 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
@ -0,0 +1 @@
|
||||
TFLite Pose Estimation
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AndroidProjectSystem">
|
||||
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="21" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetSelector">
|
||||
<selectionStates>
|
||||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
</SelectionState>
|
||||
</selectionStates>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="CHOOSE_PER_TEST" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="KotlinJpsPluginSettings">
|
||||
<option name="version" value="1.9.21" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectMigrations">
|
||||
<option name="MigrateToGradleLocalJavaHome">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,9 @@
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<set>
|
||||
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,73 @@
|
||||
# TensorFlow Lite Pose Estimation Android Demo
|
||||
|
||||
### Overview
|
||||
This is an app that continuously detects the body parts in the frames seen by
|
||||
your device's camera. These instructions walk you through building and running
|
||||
the demo on an Android device. Camera captures are discarded immediately after
|
||||
use, nothing is stored or saved.
|
||||
|
||||
The app demonstrates how to use 4 models:
|
||||
|
||||
* Single pose models: The model can estimate the pose of only one person in the
|
||||
input image. If the input image contains multiple persons, the detection result
|
||||
can be largely incorrect.
|
||||
* PoseNet
|
||||
* MoveNet Lightning
|
||||
* MoveNet Thunder
|
||||
* Multi pose models: The model can estimate pose of multiple persons in the
|
||||
input image.
|
||||
* MoveNet MultiPose: Support up to 6 persons.
|
||||
|
||||
See this [blog post](https://blog.tensorflow.org/2021/05/next-generation-pose-detection-with-movenet-and-tensorflowjs.html)
|
||||
for a comparison between these models.
|
||||
|
||||

|
||||
|
||||
## Build the demo using Android Studio
|
||||
|
||||
### Prerequisites
|
||||
|
||||
* If you don't have it already, install **[Android Studio](
|
||||
https://developer.android.com/studio/index.html)** 4.2 or
|
||||
above, following the instructions on the website.
|
||||
|
||||
* Android device and Android development environment with minimum API 21.
|
||||
|
||||
### Building
|
||||
* Open Android Studio, and from the `Welcome` screen, select
|
||||
`Open an existing Android Studio project`.
|
||||
|
||||
* From the `Open File or Project` window that appears, navigate to and select
|
||||
the `lite/examples/pose_estimation/android` directory from wherever you
|
||||
cloned the `tensorflow/examples` GitHub repo. Click `OK`.
|
||||
|
||||
* If it asks you to do a `Gradle Sync`, click `OK`.
|
||||
|
||||
* You may also need to install various platforms and tools, if you get errors
|
||||
like `Failed to find target with hash string 'android-21'` and similar. Click
|
||||
the `Run` button (the green arrow) or select `Run` > `Run 'android'` from the
|
||||
top menu. You may need to rebuild the project using `Build` > `Rebuild Project`.
|
||||
|
||||
* If it asks you to use `Instant Run`, click `Proceed Without Instant Run`.
|
||||
|
||||
* Also, you need to have an Android device plugged in with developer options
|
||||
enabled at this point. See **[here](
|
||||
https://developer.android.com/studio/run/device)** for more details
|
||||
on setting up developer devices.
|
||||
|
||||
|
||||
### Model used
|
||||
Downloading, extraction and placement in assets folder has been managed
|
||||
automatically by `download.gradle`.
|
||||
|
||||
If you explicitly want to download the model, you can download it from here:
|
||||
|
||||
* [Posenet](https://storage.googleapis.com/download.tensorflow.org/models/tflite/posenet_mobilenet_v1_100_257x257_multi_kpt_stripped.tflite)
|
||||
* [Movenet Lightning](https://kaggle.com/models/google/movenet/frameworks/tfLite/variations/singlepose-lightning)
|
||||
* [Movenet Thunder](https://www.kaggle.com/models/google/movenet/frameworks/tfLite/variations/singlepose-thunder)
|
||||
* [Movenet MultiPose](https://www.kaggle.com/models/google/movenet/frameworks/tfLite/variations/multipose-lightning-tflite-float16)
|
||||
|
||||
### Additional Note
|
||||
_Please do not delete the assets folder content_. If you explicitly deleted the
|
||||
files, then please choose `Build` > `Rebuild` from menu to re-download the
|
||||
deleted model files into assets folder.
|
@ -0,0 +1 @@
|
||||
/build
|
@ -0,0 +1,56 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'kotlin-android'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 30
|
||||
buildToolsVersion "30.0.3"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "org.tensorflow.lite.examples.poseestimation"
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 30
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
namespace "org.tensorflow.lite.examples.poseestimation"
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled 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'
|
||||
}
|
||||
}
|
||||
|
||||
// Download tflite model
|
||||
apply from:"download.gradle"
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
implementation 'androidx.core:core-ktx:1.5.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.3.0'
|
||||
implementation 'com.google.android.material:material:1.3.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||
implementation "androidx.activity:activity-ktx:1.2.3"
|
||||
implementation 'androidx.fragment:fragment-ktx:1.3.5'
|
||||
implementation 'org.tensorflow:tensorflow-lite:2.14.0'
|
||||
implementation 'org.tensorflow:tensorflow-lite-gpu:2.5.0'
|
||||
implementation 'org.tensorflow:tensorflow-lite-support:0.3.0'
|
||||
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||
androidTestImplementation "com.google.truth:truth:1.1.3"
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
task downloadPosenetModel(type: DownloadUrlTask) {
|
||||
def modelPosenetDownloadUrl = "https://storage.googleapis.com/download.tensorflow.org/models/tflite/posenet_mobilenet_v1_100_257x257_multi_kpt_stripped.tflite"
|
||||
doFirst {
|
||||
println "Downloading ${modelPosenetDownloadUrl}"
|
||||
}
|
||||
sourceUrl = "${modelPosenetDownloadUrl}"
|
||||
target = file("src/main/assets/posenet.tflite")
|
||||
}
|
||||
|
||||
task downloadMovenetLightningModel(type: DownloadUrlTask) {
|
||||
def modelMovenetLightningDownloadUrl = "https://tfhub.dev/google/lite-model/movenet/singlepose/lightning/tflite/float16/4?lite-format=tflite"
|
||||
doFirst {
|
||||
println "Downloading ${modelMovenetLightningDownloadUrl}"
|
||||
}
|
||||
sourceUrl = "${modelMovenetLightningDownloadUrl}"
|
||||
target = file("src/main/assets/movenet_lightning.tflite")
|
||||
}
|
||||
|
||||
task downloadMovenetThunderModel(type: DownloadUrlTask) {
|
||||
def modelMovenetThunderDownloadUrl = "https://tfhub.dev/google/lite-model/movenet/singlepose/thunder/tflite/float16/4?lite-format=tflite"
|
||||
doFirst {
|
||||
println "Downloading ${modelMovenetThunderDownloadUrl}"
|
||||
}
|
||||
sourceUrl = "${modelMovenetThunderDownloadUrl}"
|
||||
target = file("src/main/assets/movenet_thunder.tflite")
|
||||
}
|
||||
|
||||
task downloadMovenetMultiPoseModel(type: DownloadUrlTask) {
|
||||
def modelMovenetThunderDownloadUrl = "https://tfhub.dev/google/lite-model/movenet/multipose/lightning/tflite/float16/1?lite-format=tflite"
|
||||
doFirst {
|
||||
println "Downloading ${modelMovenetThunderDownloadUrl}"
|
||||
}
|
||||
sourceUrl = "${modelMovenetThunderDownloadUrl}"
|
||||
target = file("src/main/assets/movenet_multipose_fp16.tflite")
|
||||
}
|
||||
|
||||
task downloadPoseClassifierModel(type: DownloadUrlTask) {
|
||||
def modelPoseClassifierDownloadUrl = "https://storage.googleapis.com/download.tensorflow.org/models/tflite/pose_classifier/yoga_classifier.tflite"
|
||||
doFirst {
|
||||
println "Downloading ${modelPoseClassifierDownloadUrl}"
|
||||
}
|
||||
sourceUrl = "${modelPoseClassifierDownloadUrl}"
|
||||
target = file("src/main/assets/classifier.tflite")
|
||||
}
|
||||
|
||||
task downloadModel {
|
||||
dependsOn downloadPosenetModel
|
||||
dependsOn downloadMovenetLightningModel
|
||||
dependsOn downloadMovenetThunderModel
|
||||
dependsOn downloadPoseClassifierModel
|
||||
dependsOn downloadMovenetMultiPoseModel
|
||||
}
|
||||
|
||||
class DownloadUrlTask extends DefaultTask {
|
||||
@Input
|
||||
String sourceUrl
|
||||
|
||||
@OutputFile
|
||||
File target
|
||||
|
||||
@TaskAction
|
||||
void download() {
|
||||
ant.get(src: sourceUrl, dest: target)
|
||||
}
|
||||
}
|
||||
|
||||
preBuild.dependsOn downloadModel
|
@ -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
|
After Width: | Height: | Size: 175 KiB |