V1.0.0(1) 完成版

This commit is contained in:
lihongwei 2025-03-18 13:58:35 +08:00
parent 485cc39aaf
commit 546c90b7be
39 changed files with 506 additions and 343 deletions

BIN
app/ARDrawingFlow.jks Normal file

Binary file not shown.

View File

@ -18,4 +18,17 @@
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
#-renamesourcefileattribute SourceFile
-keepclassmembers class com.ardraw.ardrawingflow.MyApplication {
public static final java.lang.String DATABASE_NAME;
public static final int DATABASE_VERSION;
}
-keepclassmembers class * {
@androidx.room.Query <methods>;
}
-keep class com.ardraw.ardrawingflow.data.database.AppDatabase { *; }
-keep class com.ardraw.ardrawingflow.data.database.dao.FlowDataDao { *; }
-keep class com.ardraw.ardrawingflow.data.database.entity.FlowData { *; }

View File

@ -8,15 +8,13 @@
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32"
tools:ignore="ScopedStorage" />
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<application
android:name=".MyApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
@ -33,10 +31,10 @@
android:name=".ui.activity.SecondActivity"
android:exported="false" />
<activity
android:name=".ui.activity.SplashActivity"
android:name=".ui.activity.MainActivity"
android:exported="false" />
<activity
android:name=".ui.activity.MainActivity"
android:name=".ui.activity.SplashActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

View File

@ -0,0 +1,7 @@
package com.ardraw.ardrawingflow.callback;
import com.ardraw.ardrawingflow.data.database.entity.FlowData;
public interface DeleteCallback {
void onDelete(FlowData flowData);
}

View File

@ -1,4 +1,4 @@
package com.ardraw.ardrawingflow.data.database.database;
package com.ardraw.ardrawingflow.data.database;
import android.content.Context;

View File

@ -2,6 +2,7 @@ package com.ardraw.ardrawingflow.data.database.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
@ -13,18 +14,21 @@ import java.util.List;
@Dao
public interface FlowDataDao {
@Insert
void insertAll(List<FlowData> FlowData);
void insertAll(List<FlowData> flowDataList);
@Insert
void insert(FlowData FlowData);
void insert(FlowData flowData);
@Update
void update(FlowData FlowData);
void update(FlowData flowData);
@Query("SELECT * FROM FlowData WHERE imagePath LIKE 'png_' || :name || '/%' AND imageType = 0")
@Delete
void delete(FlowData flowData);
@Query("SELECT * FROM FlowData WHERE imagePath LIKE 'png_' || :name || '/%' AND imageType = 0 ORDER by id DESC")
LiveData<List<FlowData>> getDataByName(String name);
@Query("SELECT * FROM FlowData WHERE id IN ( SELECT MIN(id) FROM FlowData WHERE imageType = 0 GROUP BY SUBSTR(ImagePath, 1, INSTR(ImagePath, '/') - 1))")
@Query("SELECT * FROM FlowData WHERE id IN ( SELECT Max(id) FROM FlowData WHERE imageType = 0 GROUP BY SUBSTR(ImagePath, 1, INSTR(ImagePath, '/') - 1))")
LiveData<List<FlowData>> getMinId();
@Query("SELECT * FROM FlowData WHERE imageType = 1 ")

View File

@ -23,7 +23,11 @@ public class FlowRepository {
}
public void insert(FlowData flowData) {
flowDataDao.insert(flowData);
executorService.execute(() -> flowDataDao.insert(flowData));
}
public void delete(FlowData flowData) {
executorService.execute(() -> flowDataDao.delete(flowData));
}
public LiveData<List<FlowData>> getLike() {

View File

@ -11,6 +11,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
@ -21,7 +22,6 @@ import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraControl;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageCapture;
import androidx.camera.core.ImageCaptureException;
@ -35,28 +35,31 @@ import androidx.core.view.WindowInsetsCompat;
import com.ardraw.ardrawingflow.R;
import com.ardraw.ardrawingflow.databinding.ActivityDetailBinding;
import com.ardraw.ardrawingflow.util.ImageManager;
import com.ardraw.ardrawingflow.util.PermissionsHelper;
import com.ardraw.ardrawingflow.util.FileUtil;
import com.ardraw.ardrawingflow.util.PermissionUtil;
import com.google.common.util.concurrent.ListenableFuture;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.ExecutionException;
public class DetailActivity extends AppCompatActivity implements View.OnTouchListener, SeekBar.OnSeekBarChangeListener {
public class DetailActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener, View.OnTouchListener {
private ActivityDetailBinding binding;
private static final int CAMERA_PERMISSION_REQUEST_CODE = 200;
private static final int STORAGE_PERMISSION_REQUEST_CODE = 201;
private static final int PICK_IMAGE_REQUEST_CODE = 202;
private static final int CAMERA_PERMISSION_REQUEST = 200;
private static final int STORAGE_PERMISSION_REQUEST = 201;
private static final int PICK_IMAGE_REQUEST = 202;
private final Matrix matrix = new Matrix();
private final Matrix savedMatrix = new Matrix();
private final PointF startPointF = new PointF();
private float initialDistance;
private int mode = MODE_NONE;
private static final int MODE_NONE = 0;
private static final int MODE_DRAG = 1;
private static final int MODE_ZOOM = 2;
private final Matrix matrix = new Matrix();
private final Matrix savedMatrix = new Matrix();
private final PointF startPoint = new PointF();
private float initialDistance;
private int mode = MODE_NONE;
private boolean isFlash = false;
private Camera camera;
private ImageCapture imageCapture;
@ -74,175 +77,117 @@ public class DetailActivity extends AppCompatActivity implements View.OnTouchLis
});
initData();
initEvent();
initEvents();
}
private void initData() {
String imagePath = getIntent().getStringExtra("WallpaperPath");
String imagePath = getIntent().getStringExtra("path");
if (imagePath == null) {
finish();
return;
}
ImageManager.loadImage(imagePath, binding.imageView, this, this);
FileUtil.loadImage(imagePath, binding.imageView, this);
}
private void initEvent() {
private void initEvents() {
binding.imageView.setOnTouchListener(this);
setupListeners();
checkPermissionsAndStartCamera();
}
private void setupListeners() {
binding.seekbar.setOnSeekBarChangeListener(this);
binding.photo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openImagePicker();
}
});
binding.photo.setOnClickListener(v -> openImagePicker());
binding.flash.setOnClickListener(v -> toggleFlash());
binding.back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
binding.back.setOnClickListener(v -> finish());
binding.camera.setOnClickListener(v -> takePhotoAndSave());
binding.imageView.setOnTouchListener(this);
checkPermissionsAndStartCamera();
}
private void checkPermissionsAndStartCamera() {
String[] permissions = getPermissions();
if (PermissionsHelper.arePermissionsGranted(this, permissions)) {
if (PermissionUtil.hasPerms(this, permissions)) {
initiateCamera();
} else {
PermissionsHelper.requestUserPermissions(this, permissions, CAMERA_PERMISSION_REQUEST_CODE);
PermissionUtil.reqPerms(this, permissions, CAMERA_PERMISSION_REQUEST);
}
}
private void initiateCamera() {
ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this);
cameraProviderFuture.addListener(() -> {
ListenableFuture<ProcessCameraProvider> future = ProcessCameraProvider.getInstance(this);
future.addListener(() -> {
try {
ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
setupCameraPreview(cameraProvider);
Preview cameraPreview = new Preview.Builder().build();
cameraPreview.setSurfaceProvider(binding.preview.getSurfaceProvider());
ProcessCameraProvider provider = future.get();
Preview preview = new Preview.Builder().build();
preview.setSurfaceProvider(binding.preview.getSurfaceProvider());
imageCapture = new ImageCapture.Builder().build();
CameraSelector selector = new CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build();
CameraSelector cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA;
cameraProvider.unbindAll();
cameraProvider.bindToLifecycle(this, cameraSelector, cameraPreview, imageCapture);
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
provider.unbindAll();
camera = provider.bindToLifecycle(this, selector, preview, imageCapture);
} catch (ExecutionException | InterruptedException ignored) {
}
}, ContextCompat.getMainExecutor(this));
}
private void setupCameraPreview(@NonNull ProcessCameraProvider cameraProvider) {
Preview cameraPreview = new Preview.Builder().build();
CameraSelector selector = new CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build();
cameraPreview.setSurfaceProvider(binding.preview.getSurfaceProvider());
cameraProvider.unbindAll();
camera = cameraProvider.bindToLifecycle(this, selector, cameraPreview);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
if (PermissionsHelper.wasPermissionsGranted(grantResults)) {
initiateCamera();
} else {
Toast.makeText(this, "Camera permissions are denied. Please go to Settings and enable the permissions.", Toast.LENGTH_SHORT).show();
}
} else if (requestCode == STORAGE_PERMISSION_REQUEST_CODE) {
if (PermissionsHelper.wasPermissionsGranted(grantResults)) {
openImagePicker();
} else {
Toast.makeText(this, "Storage permission is denied. Please go to Settings and enable it.", Toast.LENGTH_SHORT).show();
}
if (requestCode == CAMERA_PERMISSION_REQUEST && PermissionUtil.gotPerms(grantResults)) {
initiateCamera();
} else if (requestCode == STORAGE_PERMISSION_REQUEST && PermissionUtil.gotPerms(grantResults)) {
openImagePicker();
} else {
Toast.makeText(this, "Permission denied. Please enable it in Settings.", Toast.LENGTH_SHORT).show();
}
}
private void takePhotoAndSave() {
if (imageCapture == null) {
Toast.makeText(this, "Camera is not initialized", Toast.LENGTH_SHORT).show();
showToast("Camera not Init");
return;
}
if (!hasCameraPermission()) {
requestCameraPermission();
return;
}
if (!hasCameraPermissions()) {
requestCameraPermissions();
return;
}
ContentValues contentValues = prepareContentValues();
ImageCapture.OutputFileOptions outputOptions = new ImageCapture.OutputFileOptions.Builder(
ImageCapture.OutputFileOptions options = new ImageCapture.OutputFileOptions.Builder(
getContentResolver(),
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
contentValues
prepareContentValues()
).build();
imageCapture.takePicture(
outputOptions,
ContextCompat.getMainExecutor(this),
new ImageCapture.OnImageSavedCallback() {
@Override
public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
Toast.makeText(DetailActivity.this, "Photo saved to album", Toast.LENGTH_SHORT).show();
}
imageCapture.takePicture(options, ContextCompat.getMainExecutor(this), new ImageCapture.OnImageSavedCallback() {
@Override
public void onImageSaved(@NonNull ImageCapture.OutputFileResults output) {
showToast("Successful photo shoot");
}
@Override
public void onError(@NonNull ImageCaptureException exception) {
Toast.makeText(DetailActivity.this, "Photo capture failed: " + exception.getMessage(), Toast.LENGTH_SHORT).show();
}
}
);
@Override
public void onError(@NonNull ImageCaptureException exception) {
showToast("Photo shoot failed");
}
});
}
private boolean hasCameraPermissions() {
return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
}
private void requestCameraPermissions() {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
}
private ContentValues prepareContentValues() {
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "photo_" + System.currentTimeMillis() + ".jpg");
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
return contentValues;
}
private void openImagePicker() {
String[] permissions = PermissionsHelper.getRequiredStoragePermissions();
String[] permissions = PermissionUtil.getStorePerms();
if (ContextCompat.checkSelfPermission(this, permissions[0]) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, permissions, STORAGE_PERMISSION_REQUEST_CODE);
ActivityCompat.requestPermissions(this, permissions, STORAGE_PERMISSION_REQUEST);
} else {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, PICK_IMAGE_REQUEST_CODE);
startActivityForResult(intent, PICK_IMAGE_REQUEST);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST_CODE && resultCode == RESULT_OK && data != null) {
Uri selectedImageUri = data.getData();
if (selectedImageUri != null) {
binding.imageView.setImageURI(selectedImageUri);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null) {
Uri imageUri = data.getData();
if (imageUri != null) {
binding.imageView.setImageURI(imageUri);
}
}
}
@ -263,61 +208,76 @@ public class DetailActivity extends AppCompatActivity implements View.OnTouchLis
@Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
int action = event.getActionMasked();
switch (event.getActionMasked()) {
switch (action) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
startPointF.set(event.getX(), event.getY());
startPoint.set(event.getX(), event.getY());
mode = MODE_DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
initialDistance = ImageManager.calculateDistanceBetweenTouches(event);
initialDistance = FileUtil.calculateDistanceBetweenTouches(event);
if (initialDistance > 10f) {
savedMatrix.set(matrix);
mode = MODE_ZOOM;
}
break;
case MotionEvent.ACTION_MOVE:
if (mode == MODE_DRAG) {
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - startPointF.x, event.getY() - startPointF.y);
} else if (mode == MODE_ZOOM) {
float newDistance = ImageManager.calculateDistanceBetweenTouches(event);
if (newDistance > 10f) {
float scale = newDistance / initialDistance;
matrix.postTranslate(event.getX() - startPoint.x, event.getY() - startPoint.y);
} else if (mode == MODE_ZOOM && event.getPointerCount() >= 2) {
float newDist = FileUtil.calculateDistanceBetweenTouches(event);
if (newDist > 10f) {
float scale = newDist / initialDistance;
matrix.set(savedMatrix);
matrix.postScale(scale, scale, view.getWidth() / 2f, view.getHeight() / 2f);
}
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = MODE_NONE;
break;
}
view.setImageMatrix(matrix);
return true;
}
private void toggleFlash() {
if (camera != null) {
isFlash = !isFlash;
camera.getCameraControl().enableTorch(isFlash);
binding.flash.setImageResource(isFlash ? R.drawable.flash : R.drawable.disflash);
}
}
private boolean hasCameraPermission() {
return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
}
private void requestCameraPermission() {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST);
}
private ContentValues prepareContentValues() {
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DISPLAY_NAME, "photo_" + System.currentTimeMillis() + ".jpg");
values.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
return values;
}
private String[] getPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_MEDIA_IMAGES};
} else {
return new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
}
return new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
}
private void toggleFlash() {
if (camera != null) {
CameraControl cameraControl = camera.getCameraControl();
isFlash = !isFlash;
cameraControl.enableTorch(isFlash);
binding.flash.setImageResource(isFlash ? R.drawable.flash : R.drawable.disflash);
}
private void showToast(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
@Override

View File

@ -18,7 +18,7 @@ import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
public class MainActivity extends AppCompatActivity {
private com.ardraw.ardrawingflow.databinding.ActivityMainBinding viewBinding;
private ActivityMainBinding viewBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -85,7 +85,6 @@ public class MainActivity extends AppCompatActivity {
@Override
public void onTabReselected(TabLayout.Tab tab) {
// No-op
}
private void refreshTabAppearance(TabLayout.Tab tab, boolean active) {
@ -112,10 +111,6 @@ public class MainActivity extends AppCompatActivity {
int[] inactiveIcons = {R.drawable.discategory, R.drawable.disadd, R.drawable.disfavorite};
return active ? activeIcons[pos] : inactiveIcons[pos];
}
private int fetchColor(int colorRes) {
return getResources().getColor(colorRes, null);
}
};
}
@ -131,7 +126,7 @@ public class MainActivity extends AppCompatActivity {
case 0:
return new TabConfig(R.drawable.category, "Category", R.color.black);
case 1:
return new TabConfig(R.drawable.add, "Add", R.color.gray);
return new TabConfig(R.drawable.disadd, "Upload", R.color.gray);
case 2:
return new TabConfig(R.drawable.disfavorite, "Favorite", R.color.gray);
default:

View File

@ -45,7 +45,7 @@ public class SecondActivity extends AppCompatActivity {
}
private void initData() {
String path = getIntent().getStringExtra("Path");
String path = getIntent().getStringExtra("path");
if (path == null) {
finish();
return;
@ -57,7 +57,7 @@ public class SecondActivity extends AppCompatActivity {
flowViewModel = new ViewModelProvider(this).get(FlowViewModel.class);
binding.recyclerView.setLayoutManager(new GridLayoutManager(this, 2));
adapter = new FlowItemAdapter(this, new ArrayList<>(), 1);
adapter = new FlowItemAdapter(this, new ArrayList<>(), 2);
binding.recyclerView.setAdapter(adapter);
ItemDecoration itemDecoration = new ItemDecoration(35, 15, 20);

View File

@ -1,6 +1,8 @@
package com.ardraw.ardrawingflow.ui.activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
@ -9,18 +11,65 @@ import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import com.ardraw.ardrawingflow.R;
import com.ardraw.ardrawingflow.databinding.ActivitySplashBinding;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
public class SplashActivity extends AppCompatActivity {
private ActivitySplashBinding binding;
private static final long TOTAL_TIME = 3000;
private CountDownTimer countDownTimer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_splash);
binding = ActivitySplashBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
Glide.with(this)
.load(R.mipmap.ic_launcher)
.transform(new RoundedCorners(16))
.into(binding.splashImage);
countDownTimer = new CountDownTimer(TOTAL_TIME, 100) {
@Override
public void onTick(long millisUntilFinished) {
int percentage = (int) (100 - (float) millisUntilFinished / TOTAL_TIME * 100);
binding.progressBar.setProgress(percentage);
}
@Override
public void onFinish() {
startMain();
}
};
countDownTimer.start();
}
private void startMain() {
binding.progressBar.setProgress(100);
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (countDownTimer != null) {
countDownTimer.cancel();
}
binding = null;
}
}

View File

@ -12,7 +12,8 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.ardraw.ardrawingflow.R;
import com.ardraw.ardrawingflow.data.database.database.AppDatabase;
import com.ardraw.ardrawingflow.callback.DeleteCallback;
import com.ardraw.ardrawingflow.data.database.AppDatabase;
import com.ardraw.ardrawingflow.data.database.entity.FlowData;
import com.ardraw.ardrawingflow.ui.activity.DetailActivity;
import com.ardraw.ardrawingflow.ui.activity.SecondActivity;
@ -28,6 +29,7 @@ public class FlowItemAdapter extends RecyclerView.Adapter<FlowItemAdapter.ItemVi
private List<FlowData> dataItems;
private final Context appContext;
private final int displayMode;
private DeleteCallback deleteCallback;
public FlowItemAdapter(Context appContext, List<FlowData> dataItems, int displayMode) {
this.appContext = appContext;
@ -40,6 +42,10 @@ public class FlowItemAdapter extends RecyclerView.Adapter<FlowItemAdapter.ItemVi
notifyDataSetChanged();
}
public void setDeleteCallback(DeleteCallback deleteCallback) {
this.deleteCallback = deleteCallback;
}
@NonNull
@Override
public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
@ -72,27 +78,31 @@ public class FlowItemAdapter extends RecyclerView.Adapter<FlowItemAdapter.ItemVi
public class ItemViewHolder extends RecyclerView.ViewHolder {
private final ImageView previewImage;
private final ImageView favoriteIcon;
private final ImageView deleteIcon;
private final TextView titleText;
public ItemViewHolder(@NonNull View view) {
super(view);
previewImage = view.findViewById(R.id.image_view);
previewImage = view.findViewById(R.id.item_image);
favoriteIcon = view.findViewById(R.id.like);
deleteIcon = view.findViewById(R.id.delete);
titleText = view.findViewById(R.id.title);
}
void renderItem(FlowData item, String displayName, int mode) {
configureDisplay(item, displayName, mode);
configureDisplay(displayName, mode);
loadImageContent(item.getImagePath());
setFavoriteState(item);
attachListeners(item, mode);
}
private void configureDisplay(FlowData item, String name, int mode) {
private void configureDisplay(String name, int mode) {
if (mode == 0) {
titleText.setText(name);
titleText.setVisibility(View.VISIBLE);
favoriteIcon.setVisibility(View.GONE);
} else if (mode == 1) {
deleteIcon.setVisibility(View.VISIBLE);
}
}
@ -117,6 +127,12 @@ public class FlowItemAdapter extends RecyclerView.Adapter<FlowItemAdapter.ItemVi
private void attachListeners(FlowData item, int mode) {
previewImage.setOnClickListener(view -> handleImageTap(item, mode));
favoriteIcon.setOnClickListener(view -> switchFavorite(item));
deleteIcon.setOnClickListener(view ->{
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION && deleteCallback != null) {
deleteCallback.onDelete(dataItems.get(position));
}
});
}
private void handleImageTap(FlowData item, int mode) {
@ -126,9 +142,8 @@ public class FlowItemAdapter extends RecyclerView.Adapter<FlowItemAdapter.ItemVi
private Intent createNavigationIntent(FlowData item, int mode) {
Class<?> targetActivity = mode == 0 ? SecondActivity.class : DetailActivity.class;
String extraKey = mode == 0 ? "Path" : "WallpaperPath";
return new Intent(appContext, targetActivity)
.putExtra(extraKey, item.getImagePath());
.putExtra("path", item.getImagePath());
}
private void switchFavorite(FlowData item) {

View File

@ -15,6 +15,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.ardraw.ardrawingflow.callback.DeleteCallback;
import com.ardraw.ardrawingflow.data.database.entity.FlowData;
import com.ardraw.ardrawingflow.databinding.FragmentAddBinding;
import com.ardraw.ardrawingflow.ui.adapter.FlowItemAdapter;
@ -22,11 +23,10 @@ import com.ardraw.ardrawingflow.ui.viewmodel.FlowViewModel;
import com.ardraw.ardrawingflow.util.UploadUtil;
import com.ardraw.ardrawingflow.util.ItemDecoration;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class AddFragment extends Fragment {
public class AddFragment extends Fragment implements DeleteCallback {
private static final int PICK_IMAGE_REQUEST_CODE = 202;
private FragmentAddBinding binding;
private FlowItemAdapter adapter;
@ -51,6 +51,7 @@ public class AddFragment extends Fragment {
adapter = new FlowItemAdapter(requireContext(), new ArrayList<>(), 1);
binding.recyclerView.setAdapter(adapter);
adapter.setDeleteCallback(this);
ItemDecoration itemDecoration = new ItemDecoration(35, 15, 20);
binding.recyclerView.addItemDecoration(itemDecoration);
@ -69,13 +70,13 @@ public class AddFragment extends Fragment {
.getAddLiveData()
.observe(getViewLifecycleOwner(), new Observer<List<FlowData>>() {
@Override
public void onChanged(List<FlowData> flowData) {
if (flowData.isEmpty()) {
public void onChanged(List<FlowData> flowDataList) {
if (flowDataList.isEmpty()) {
binding.text.setVisibility(View.VISIBLE);
} else {
binding.text.setVisibility(View.GONE);
}
adapter.refreshItems(flowData);
adapter.refreshItems(flowDataList);
}
});
}
@ -97,20 +98,17 @@ public class AddFragment extends Fragment {
}
private void processImage(Uri imageUri) {
try {
if (UploadUtil.isImageSizeValid(imageUri, requireContext())) {
UploadUtil.saveImage(imageUri, imagePaths, flowViewModel, requireContext(), requireActivity());
} else {
showToast("The image size is out of limit");
}
} catch (IOException e) {
e.printStackTrace();
showToast("Could not get image size: " + e.getMessage());
if (UploadUtil.isImageSizeValid(imageUri, requireContext())) {
UploadUtil.saveImage(imageUri, imagePaths, flowViewModel, requireContext());
} else {
Toast.makeText(getContext(), "The image size is out of limit", Toast.LENGTH_SHORT).show();
}
}
private void showToast(String message) {
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
@Override
public void onDelete(FlowData flowData) {
UploadUtil.deleteImage(flowData, flowViewModel, requireContext());
loadAllImportImage();
}
@Override
@ -118,5 +116,4 @@ public class AddFragment extends Fragment {
super.onDestroy();
binding = null;
}
}

View File

@ -41,7 +41,7 @@ public class FavoriteFragment extends Fragment {
binding.recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
flowItemAdapter = new FlowItemAdapter(requireContext(), new ArrayList<>(), 0);
flowItemAdapter = new FlowItemAdapter(requireContext(), new ArrayList<>(), 2);
binding.recyclerView.setAdapter(flowItemAdapter);
ItemDecoration itemDecoration = new ItemDecoration(35, 15, 20);
@ -57,8 +57,13 @@ public class FavoriteFragment extends Fragment {
.getLike()
.observe(getViewLifecycleOwner(), new Observer<List<FlowData>>() {
@Override
public void onChanged(List<FlowData> arData) {
flowItemAdapter.refreshItems(arData);
public void onChanged(List<FlowData> flowData) {
if (flowData.isEmpty()) {
binding.text.setVisibility(View.VISIBLE);
} else {
binding.text.setVisibility(View.GONE);
}
flowItemAdapter.refreshItems(flowData);
}
});
}

View File

@ -7,7 +7,7 @@ import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import com.ardraw.ardrawingflow.data.database.dao.FlowDataDao;
import com.ardraw.ardrawingflow.data.database.database.AppDatabase;
import com.ardraw.ardrawingflow.data.database.AppDatabase;
import com.ardraw.ardrawingflow.data.database.entity.FlowData;
import com.ardraw.ardrawingflow.data.repository.FlowRepository;
@ -26,6 +26,10 @@ public class FlowViewModel extends AndroidViewModel {
flowRepository.insert(flowData);
}
public void delete(FlowData flowData) {
flowRepository.delete(flowData);
}
public LiveData<List<FlowData>> getLike() {
return flowRepository.getLike();
}

View File

@ -1,32 +1,29 @@
package com.ardraw.ardrawingflow.util;
import android.app.Activity;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
public class ImageManager {
public class FileUtil {
public static float calculateDistanceBetweenTouches(MotionEvent event) {
float deltaX = event.getX(1) - event.getX(0);
float deltaY = event.getY(1) - event.getY(0);
return (float) Math.sqrt(deltaX * deltaX + deltaY * deltaY);
}
public static void loadImage(String path, ImageView imageView, Context context, Activity activity) {
public static void loadImage(String path, ImageView imageView, Context context) {
if (path == null || imageView == null || context == null) return;
if (path.startsWith("/data/user/")) {
loadImageFromStorage(path, imageView, context);
} else {
loadImageFromAssets(path, activity, context, imageView);
loadImageFromAssets(path, imageView, context);
}
}
@ -39,29 +36,15 @@ public class ImageManager {
}
}
private static void loadImageFromAssets(String path, Activity activity, Context context, ImageView imageView) {
try {
AssetManager assetManager = activity.getAssets();
InputStream inputStream = assetManager.open(path);
private static void loadImageFromAssets(String path, ImageView imageView, Context context) {
try (InputStream inputStream = context.getAssets().open(path)) {
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
imageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
showToast(context, "Failed to load image from assets: " + e.getMessage());
showToast(context, "Failed to load image from assets");
}
}
private static Point getScreenSize(Context context) {
DisplayMetrics metrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
if (windowManager != null) {
windowManager.getDefaultDisplay().getMetrics(metrics);
}
int width = metrics.widthPixels;
int height = metrics.heightPixels;
return new Point(width, height);
}
private static void showToast(Context context, String message) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}

View File

@ -4,7 +4,7 @@ import android.content.Context;
import android.content.res.AssetManager;
import com.ardraw.ardrawingflow.data.database.dao.FlowDataDao;
import com.ardraw.ardrawingflow.data.database.database.AppDatabase;
import com.ardraw.ardrawingflow.data.database.AppDatabase;
import com.ardraw.ardrawingflow.data.database.entity.FlowData;
import com.ardraw.ardrawingflow.data.repository.FlowRepository;

View File

@ -0,0 +1,47 @@
package com.ardraw.ardrawingflow.util;
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
public final class PermissionUtil {
private PermissionUtil() {
}
public static boolean hasPerms(Activity activity, String[] permissions) {
if (activity == null || permissions == null) return false;
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
public static void reqPerms(Activity activity, String[] permissions, int requestCode) {
if (activity != null && permissions != null) {
ActivityCompat.requestPermissions(activity, permissions, requestCode);
}
}
public static boolean gotPerms(int[] grantResults) {
if (grantResults == null || grantResults.length == 0) return false;
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
public static String[] getStorePerms() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
? new String[]{Manifest.permission.READ_MEDIA_IMAGES}
: new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
}
}

View File

@ -1,42 +0,0 @@
package com.ardraw.ardrawingflow.util;
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
public class PermissionsHelper {
public static boolean arePermissionsGranted(Activity activity, String[] permissions) {
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
public static void requestUserPermissions(Activity activity, String[] permissions, int requestCode) {
ActivityCompat.requestPermissions(activity, permissions, requestCode);
}
public static boolean wasPermissionsGranted(int[] grantResults) {
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
public static String[] getRequiredStoragePermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return new String[]{Manifest.permission.READ_MEDIA_IMAGES};
} else {
return new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
}
}
}

View File

@ -1,10 +1,11 @@
package com.ardraw.ardrawingflow.util;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.widget.Toast;
import com.ardraw.ardrawingflow.data.database.entity.FlowData;
@ -17,38 +18,52 @@ import java.io.InputStream;
import java.util.List;
public class UploadUtil {
private static final Handler mainHandler = new Handler(Looper.getMainLooper());
public static void saveImage(Uri imageUri, List<String> imagePaths, FlowViewModel flowViewModel, Context appContext, Activity activity) {
try {
InputStream imageInputStream = appContext.getContentResolver().openInputStream(imageUri);
Bitmap imageBitmap = BitmapFactory.decodeStream(imageInputStream);
public static void saveImage(Uri imageUri, List<String> imagePaths, FlowViewModel flowViewModel, Context context) {
if (imageUri == null || imagePaths == null || flowViewModel == null || context == null)
return;
if (imageBitmap == null) {
showToast(appContext, "Unable to load image");
try (InputStream inputStream = context.getContentResolver().openInputStream(imageUri)) {
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
if (bitmap == null) {
showToast(context, "Unable to load image");
return;
}
File storageDir = appContext.getFilesDir();
File imageFile = new File(storageDir, generateUniqueImageName() + ".jpg");
try (FileOutputStream imageOutputStream = new FileOutputStream(imageFile)) {
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, imageOutputStream);
File imageFile = new File(context.getFilesDir(), generateUniqueImageName() + ".jpg");
try (FileOutputStream outputStream = new FileOutputStream(imageFile)) {
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
}
imageInputStream.close();
String savedImagePath = imageFile.getAbsolutePath();
new Thread(() -> handleImageSaving(savedImagePath, imagePaths, flowViewModel, appContext, activity, imageFile)).start();
new Thread(() -> handleImageSaving(savedImagePath, imagePaths, flowViewModel, context, imageFile)).start();
} catch (IOException e) {
e.printStackTrace();
showToast(appContext, "Failed to save picture: " + e.getMessage());
showToast(context, "Failed to save picture");
}
}
private static void handleImageSaving(String savedImagePath, List<String> imagePaths, FlowViewModel flowViewModel, Context appContext, Activity activity, File imageFile) {
public static void deleteImage(FlowData flowData, FlowViewModel flowViewModel, Context context) {
if (flowData.getImagePath() == null || flowViewModel == null || context == null) return;
File imageFile = new File(flowData.getImagePath());
if (!imageFile.exists()) {
showToast(context, "Image does not exist");
return;
}
if (imageFile.delete()) {
flowViewModel.delete(flowData);
showToast(context, "Image deleted successfully");
} else {
showToast(context, "Failed to delete image");
}
}
private static void handleImageSaving(String savedImagePath, List<String> imagePaths, FlowViewModel flowViewModel, Context context, File imageFile) {
if (isImageAlreadyPresent(savedImagePath, imagePaths, flowViewModel)) {
activity.runOnUiThread(() -> showToast(appContext, "The image already exists"));
imageFile.delete();
showToast(context, "The image already exists");
return;
}
@ -58,6 +73,7 @@ public class UploadUtil {
private static boolean isImageAlreadyPresent(String imagePath, List<String> imagePaths, FlowViewModel flowViewModel) {
File newImageFile = new File(imagePath);
if (!newImageFile.exists()) return false;
for (String path : imagePaths) {
File existingFile = new File(path);
@ -66,40 +82,40 @@ public class UploadUtil {
}
}
List<FlowData> flowData = flowViewModel.getAdd();
for (FlowData flowData1 : flowData) {
File existingFile = new File(flowData1.getImagePath());
List<FlowData> flowDataList = flowViewModel.getAdd();
for (FlowData data : flowDataList) {
File existingFile = new File(data.getImagePath());
if (isFileSizeMatching(existingFile, newImageFile)) {
return true;
}
}
return false;
}
private static boolean isFileSizeMatching(File file1, File file2) {
return file1.length() == file2.length();
return file1.exists() && file2.exists() && file1.length() == file2.length();
}
private static void showToast(Context context, String message) {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
if (context == null || message == null) return;
mainHandler.post(() -> Toast.makeText(context, message, Toast.LENGTH_SHORT).show());
}
private static String generateUniqueImageName() {
return String.valueOf(System.currentTimeMillis());
}
public static boolean isImageSizeValid(Uri imageUri, Context context) throws IOException {
InputStream imageInputStream = context.getContentResolver().openInputStream(imageUri);
if (imageInputStream == null) {
public static boolean isImageSizeValid(Uri imageUri, Context context) {
if (imageUri == null || context == null) return false;
try (InputStream inputStream = context.getContentResolver().openInputStream(imageUri)) {
if (inputStream == null) return false;
long imageSize = inputStream.available();
long maxSize = 10 * 1024 * 1024;
return imageSize <= maxSize;
} catch (IOException e) {
return false;
}
long imageSize = imageInputStream.available();
imageInputStream.close();
long maxSize = 10 * 1024 * 1024;
return imageSize <= maxSize;
}
}

View File

@ -4,9 +4,9 @@
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#FF000000"
android:fillColor="@color/black"
android:pathData="M682.7,955.7L170.7,955.7c-66,0 -102.4,-36.4 -102.4,-102.4L68.3,341.3c0,-66 36.4,-102.4 102.4,-102.4h68.3v-68.3c0,-66 36.4,-102.4 102.4,-102.4h512c66,0 102.4,36.4 102.4,102.4v512c0,66 -36.4,102.4 -102.4,102.4h-68.3v68.3c0,66 -36.4,102.4 -102.4,102.4zM170.7,273.1c-47.2,0 -68.3,21 -68.3,68.3v512c0,47.2 21,68.3 68.3,68.3h512c47.2,0 68.3,-21 68.3,-68.3v-68.3L341.3,785.1c-66,0 -102.4,-36.4 -102.4,-102.4L238.9,273.1h-68.3zM768,750.9h85.3c47.2,0 68.3,-21 68.3,-68.3L921.6,170.7c0,-47.2 -21,-68.3 -68.3,-68.3L341.3,102.4c-47.2,0 -68.3,21 -68.3,68.3v512c0,47.2 21,68.3 68.3,68.3h426.7z"/>
<path
android:fillColor="#FF000000"
android:fillColor="@color/black"
android:pathData="M597.3,631.5a34.1,34.1 0,0 1,-34.1 -34.1v-136.5h-136.5a34.1,34.1 0,0 1,0 -68.3h136.5v-136.5a34.1,34.1 0,0 1,68.3 0v136.5h136.5a34.1,34.1 0,0 1,0 68.3h-136.5v136.5a34.1,34.1 0,0 1,-34.1 34.1z"/>
</vector>

View File

@ -4,6 +4,6 @@
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#FF000000"
android:fillColor="#6CE89E"
android:pathData="M707.5,62.1c-17.4,0 -33.8,6.5 -46.1,18.2L279.6,431.9c-18,17.2 -28.3,40.6 -28.3,65.4s10.2,48.3 28.6,65.9l381.4,350.4c24.6,23.5 67.6,23.5 92.2,0 12.3,-11.7 19.1,-27.3 19.1,-43.8s-6.8,-32.2 -19.1,-43.9l-278,-262.6c-18.5,-17.7 -28.7,-41 -28.7,-65.9s10.2,-48.2 28.6,-65.8l278.1,-263.6c12.3,-11.7 19,-27.3 19,-43.8s-6.8,-32.2 -19.1,-43.9a66.3,66.3 0,0 0,-46.1 -18.2zM707.5,993.8a132.7,132.7 0,0 1,-92.2 -36.4l-52.3,-49.8 -328.5,-300.1c-31.3,-29.8 -48.2,-68.7 -48.2,-110.2s16.9,-80.4 47.7,-109.7L615.7,36a132.6,132.6 0,0 1,91.7 -36c34.8,0 67.6,12.9 92.1,36.4 24.6,23.4 38.2,54.6 38.2,87.7s-13.6,64.4 -38.2,87.8l-278.1,263.6a30.1,30.1 0,0 0,0.1 43.8l278,262.6c24.7,23.6 38.3,54.8 38.3,87.9s-13.6,64.3 -38.2,87.7a132.9,132.9 0,0 1,-92.1 36.4z"/>
</vector>

View File

@ -4,12 +4,12 @@
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#FF000000"
android:fillColor="#6CE89E"
android:pathData="M512,102.4c227.2,0 409.6,182.4 409.6,409.6 0,227.2 -182.4,409.6 -409.6,409.6 -227.2,0 -409.6,-182.4 -409.6,-409.6C102.4,284.8 284.8,102.4 512,102.4M512,0C230.4,0 0,230.4 0,512s230.4,512 512,512 512,-230.4 512,-512S793.6,0 512,0"/>
<path
android:fillColor="#FF000000"
android:fillColor="#6CE89E"
android:pathData="M512,332.8c99.2,0 179.2,80 179.2,179.2 0,99.2 -80,179.2 -179.2,179.2 -99.2,0 -179.2,-80 -179.2,-179.2 0,-99.2 80,-179.2 179.2,-179.2m0,-102.4c-156.8,0 -281.6,124.8 -281.6,281.6s124.8,281.6 281.6,281.6 281.6,-124.8 281.6,-281.6 -124.8,-281.6 -281.6,-281.6"/>
<path
android:fillColor="#FF000000"
android:fillColor="#6CE89E"
android:pathData="M281.6,204.8c28.8,0 51.2,22.4 51.2,51.2 0,28.8 -22.4,51.2 -51.2,51.2 -28.8,0 -51.2,-22.4 -51.2,-51.2 0,-28.8 22.4,-51.2 51.2,-51.2"/>
</vector>

View File

@ -4,15 +4,15 @@
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#FF000000"
android:fillColor="@color/black"
android:pathData="M418.8,102.5 L158.5,102.5c-30.8,0 -55.8,25 -55.8,55.8l0,260.4c0,30.8 25,55.8 55.8,55.8l260.4,0c30.8,0 55.8,-25 55.8,-55.8L474.6,158.3C474.6,127.5 449.6,102.5 418.8,102.5zM437.4,418.7c0,10.3 -8.3,18.6 -18.6,18.6L158.5,437.3c-10.3,0 -18.6,-8.3 -18.6,-18.6L139.9,158.3c0,-10.3 8.3,-18.6 18.6,-18.6l260.4,0c10.3,0 18.6,8.3 18.6,18.6L437.4,418.7z"/>
<path
android:fillColor="#FF000000"
android:fillColor="@color/black"
android:pathData="M865.2,102.5 L604.8,102.5c-30.8,0 -55.8,25 -55.8,55.8l0,260.4c0,30.8 25,55.8 55.8,55.8l260.4,0c30.8,0 55.8,-25 55.8,-55.8L921,158.3C921,127.5 896,102.5 865.2,102.5zM883.8,418.7c0,10.3 -8.3,18.6 -18.6,18.6L604.8,437.3c-10.3,0 -18.6,-8.3 -18.6,-18.6L586.2,158.3c0,-10.3 8.3,-18.6 18.6,-18.6l260.4,0c10.3,0 18.6,8.3 18.6,18.6L883.8,418.7z"/>
<path
android:fillColor="#FF000000"
android:fillColor="@color/black"
android:pathData="M418.8,548.9 L158.5,548.9c-30.8,0 -55.8,25 -55.8,55.8l0,260.4c0,30.8 25,55.8 55.8,55.8l260.4,0c30.8,0 55.8,-25 55.8,-55.8L474.6,604.7C474.6,573.9 449.6,548.9 418.8,548.9zM437.4,865.1c0,10.3 -8.3,18.6 -18.6,18.6L158.5,883.7c-10.3,0 -18.6,-8.3 -18.6,-18.6L139.9,604.7c0,-10.3 8.3,-18.6 18.6,-18.6l260.4,0c10.3,0 18.6,8.3 18.6,18.6L437.4,865.1z"/>
<path
android:fillColor="#FF000000"
android:fillColor="@color/black"
android:pathData="M846.4,548.9 L623.7,548.9c-41.2,0 -74.6,33.5 -74.6,74.6l0,222.7c0,41.2 33.4,74.6 74.4,74.6l106.6,0c10.3,0 18.6,-8.3 18.6,-18.6s-8.3,-18.6 -18.6,-18.6L623.5,883.7c-20.5,0 -37.2,-16.8 -37.2,-37.4L586.2,623.5c0,-20.6 16.8,-37.4 37.4,-37.4l222.7,0c20.6,0 37.4,16.6 37.4,37.1l0,114.6c0,10.3 8.3,18.6 18.6,18.6s18.6,-8.3 18.6,-18.6L921,623.2C921,582.2 887.5,548.9 846.4,548.9z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M844.1,256a46.5,46.5 0,0 1,46.5 49.5l-35.7,563.8a139.6,139.6 0,0 1,-139.4 131.4L308.6,1000.7a139.6,139.6 0,0 1,-139.4 -131.4L133.4,305.5a46.5,46.5 0,0 1,43.5 -49.4l1.5,-0.1h665.6zM780.9,349.1L243.9,349.1a14,14 0,0 0,-14 14.9l32.1,499.9a46.5,46.5 0,0 0,41.2 43.5l5.2,0.3h406.9a46.5,46.5 0,0 0,45.9 -38.6l0.6,-5.2 32,-499.9a14,14 0,0 0,-13 -14.8zM418.9,442.2a46.5,46.5 0,0 1,46.5 46.5v279.3a46.5,46.5 0,0 1,-93.1 0v-279.3a46.5,46.5 0,0 1,46.5 -46.5zM605.1,442.2a46.5,46.5 0,0 1,46.5 46.5v279.3a46.5,46.5 0,0 1,-93.1 0v-279.3a46.5,46.5 0,0 1,46.5 -46.5zM530.6,23.3A74.5,74.5 0,0 1,605.1 97.7v18.6h325.8a46.5,46.5 0,0 1,0 93.1L93.1,209.5a46.5,46.5 0,1 1,0 -93.1h325.8v-18.6A74.5,74.5 0,0 1,493.4 23.3h37.2z"
android:fillColor="#EA340F"/>
</vector>

View File

@ -1,4 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
</selector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="@color/gray"
android:pathData="M682.7,955.7L170.7,955.7c-66,0 -102.4,-36.4 -102.4,-102.4L68.3,341.3c0,-66 36.4,-102.4 102.4,-102.4h68.3v-68.3c0,-66 36.4,-102.4 102.4,-102.4h512c66,0 102.4,36.4 102.4,102.4v512c0,66 -36.4,102.4 -102.4,102.4h-68.3v68.3c0,66 -36.4,102.4 -102.4,102.4zM170.7,273.1c-47.2,0 -68.3,21 -68.3,68.3v512c0,47.2 21,68.3 68.3,68.3h512c47.2,0 68.3,-21 68.3,-68.3v-68.3L341.3,785.1c-66,0 -102.4,-36.4 -102.4,-102.4L238.9,273.1h-68.3zM768,750.9h85.3c47.2,0 68.3,-21 68.3,-68.3L921.6,170.7c0,-47.2 -21,-68.3 -68.3,-68.3L341.3,102.4c-47.2,0 -68.3,21 -68.3,68.3v512c0,47.2 21,68.3 68.3,68.3h426.7z"/>
<path
android:fillColor="@color/gray"
android:pathData="M597.3,631.5a34.1,34.1 0,0 1,-34.1 -34.1v-136.5h-136.5a34.1,34.1 0,0 1,0 -68.3h136.5v-136.5a34.1,34.1 0,0 1,68.3 0v136.5h136.5a34.1,34.1 0,0 1,0 68.3h-136.5v136.5a34.1,34.1 0,0 1,-34.1 34.1z"/>
</vector>

View File

@ -1,4 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
</selector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="@color/gray"
android:pathData="M418.8,102.5 L158.5,102.5c-30.8,0 -55.8,25 -55.8,55.8l0,260.4c0,30.8 25,55.8 55.8,55.8l260.4,0c30.8,0 55.8,-25 55.8,-55.8L474.6,158.3C474.6,127.5 449.6,102.5 418.8,102.5zM437.4,418.7c0,10.3 -8.3,18.6 -18.6,18.6L158.5,437.3c-10.3,0 -18.6,-8.3 -18.6,-18.6L139.9,158.3c0,-10.3 8.3,-18.6 18.6,-18.6l260.4,0c10.3,0 18.6,8.3 18.6,18.6L437.4,418.7z"/>
<path
android:fillColor="@color/gray"
android:pathData="M865.2,102.5 L604.8,102.5c-30.8,0 -55.8,25 -55.8,55.8l0,260.4c0,30.8 25,55.8 55.8,55.8l260.4,0c30.8,0 55.8,-25 55.8,-55.8L921,158.3C921,127.5 896,102.5 865.2,102.5zM883.8,418.7c0,10.3 -8.3,18.6 -18.6,18.6L604.8,437.3c-10.3,0 -18.6,-8.3 -18.6,-18.6L586.2,158.3c0,-10.3 8.3,-18.6 18.6,-18.6l260.4,0c10.3,0 18.6,8.3 18.6,18.6L883.8,418.7z"/>
<path
android:fillColor="@color/gray"
android:pathData="M418.8,548.9 L158.5,548.9c-30.8,0 -55.8,25 -55.8,55.8l0,260.4c0,30.8 25,55.8 55.8,55.8l260.4,0c30.8,0 55.8,-25 55.8,-55.8L474.6,604.7C474.6,573.9 449.6,548.9 418.8,548.9zM437.4,865.1c0,10.3 -8.3,18.6 -18.6,18.6L158.5,883.7c-10.3,0 -18.6,-8.3 -18.6,-18.6L139.9,604.7c0,-10.3 8.3,-18.6 18.6,-18.6l260.4,0c10.3,0 18.6,8.3 18.6,18.6L437.4,865.1z"/>
<path
android:fillColor="@color/gray"
android:pathData="M846.4,548.9 L623.7,548.9c-41.2,0 -74.6,33.5 -74.6,74.6l0,222.7c0,41.2 33.4,74.6 74.4,74.6l106.6,0c10.3,0 18.6,-8.3 18.6,-18.6s-8.3,-18.6 -18.6,-18.6L623.5,883.7c-20.5,0 -37.2,-16.8 -37.2,-37.4L586.2,623.5c0,-20.6 16.8,-37.4 37.4,-37.4l222.7,0c20.6,0 37.4,16.6 37.4,37.1l0,114.6c0,10.3 8.3,18.6 18.6,18.6s18.6,-8.3 18.6,-18.6L921,623.2C921,582.2 887.5,548.9 846.4,548.9z"/>
</vector>

View File

@ -1,4 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
</selector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M679.5,918.2c-3,0 -5.9,-1.3 -7.9,-3.8L497.7,700.2c-25.7,-29.6 -41.8,-64.4 -46.7,-100.8 -4.5,-33.4 0.5,-67 14.3,-97.3 25,-54.9 74.6,-89.1 129.4,-89.1 5.5,0 11.1,0.3 16.7,1 23.9,2.9 49.8,16.5 72.9,38.2 16.5,15.5 30.7,34.4 40.4,53.5 12.5,-14.8 28.4,-28.3 46.1,-39.1 24.6,-15 50.8,-23.3 73.7,-23.3 3.8,0 7.6,0.2 11.2,0.7 57.5,7.1 103.2,48.4 119.5,107.8 9.1,33.4 8,68.9 -3.3,102.7 -12.3,36.7 -36.3,69.6 -69.5,95.1l-216.7,166.4C683.9,917.5 681.7,918.2 679.5,918.2zM594.7,433.5c-46.7,0 -89.2,29.6 -110.9,77.1 -20.6,45.2 -23.7,115.3 29.3,176.3 0.1,0.1 0.1,0.2 0.2,0.3l167.8,206.7 208.9,-160.3c69.3,-53.2 79.3,-125.9 65.5,-176.2 -14,-51.3 -53.2,-86.9 -102.3,-92.9 -2.8,-0.3 -5.8,-0.5 -8.8,-0.5 -38.7,0 -88.6,29.7 -113.6,67.6 -2.1,3.2 -5.9,5 -9.7,4.5 -3.8,-0.4 -7.1,-3 -8.4,-6.6 -8,-21.7 -23.5,-44.4 -42.5,-62.2 -20,-18.7 -41.8,-30.4 -61.4,-32.8C604.2,433.8 599.4,433.5 594.7,433.5z"
android:fillColor="@color/gray"/>
<path
android:pathData="M487.7,829.9c-2.1,0 -4.3,-0.7 -6.1,-2L160.5,586.6c-48.4,-34 -83.9,-79.4 -102.6,-131.4 -17.2,-47.7 -19.9,-98.4 -7.8,-146.8 10.2,-41 30.5,-77.2 58.7,-104.8 30,-29.3 67.8,-47.5 109.5,-52.6 33.8,-4.2 74.2,5.7 113.6,27.7 30.5,17.1 58.6,40.5 79.3,65.8 13.4,-29.5 34.6,-58.9 59.8,-82.8 32.5,-30.9 69.1,-50.1 103,-54.3 41.5,-5.1 82.6,2.9 118.7,23.1 34.1,19.1 62.9,48.4 83.3,84.7 24.2,43.2 34.9,92.8 30.9,143.5 -4.3,55.2 -26.4,109.2 -63.7,156.1 -3.5,4.4 -9.9,5.1 -14.3,1.6 -4.4,-3.5 -5.1,-9.9 -1.6,-14.3 80.5,-101.2 68.8,-209.5 31,-277 -38.8,-69.2 -108.4,-106.6 -181.7,-97.6 -29.6,3.6 -62,21 -91.4,48.9 -27.8,26.4 -50.3,60 -61.5,92 -1.3,3.6 -4.5,6.2 -8.3,6.7 -3.8,0.5 -7.6,-1.2 -9.8,-4.4 -19.3,-28.4 -49.8,-55.4 -83.5,-74.3 -35.6,-19.9 -71.6,-28.9 -101.1,-25.2 -73.5,9 -131.3,63.5 -150.9,142.1 -23.8,95.6 16.4,196.3 102.5,256.6 0.1,0.1 0.2,0.1 0.3,0.2l313.3,235.4 49.6,-62.4c3.5,-4.4 9.9,-5.1 14.3,-1.6 4.4,3.5 5.1,9.9 1.6,14.3l-55.8,70.2C493.7,828.6 490.7,829.9 487.7,829.9z"
android:fillColor="@color/gray"/>
</vector>

View File

@ -5,5 +5,5 @@
android:viewportHeight="1024">
<path
android:pathData="M661.3,516.1a40,40 0,0 1,-4.3 -56.4c6.4,-7.4 4.5,-14.7 2.8,-18.4 -1.6,-3.6 -5.8,-9.6 -15.4,-9.6h-211a40,40 0,0 1,-34.8 -59.7l161.8,-284.6 0.4,-0.7a4,4 0,0 0,0 -4.5c-1.3,-2.2 -3.1,-2.2 -3.9,-2.2a4.5,4.5 0,0 0,-2.2 0.6L123.4,485.2c-0.4,0.4 -0.9,0.8 -1.3,1.2 -12.8,11 -14.8,23.9 -14.2,32.8 1.3,19.2 15.6,38.6 40.6,38.6h201.1a40,40 0,0 1,35.5 58.4l-167,320.7c-0.8,1.7 -1.3,3.3 1.6,5.4 2.8,2 4.1,1.3 5.4,0.1l309.1,-333.8a40,40 0,1 1,58.7 54.3l-309.9,334.6a42.3,42.3 0,0 1,-1.2 1.3c-16.6,16.4 -37.8,24.8 -59.2,24.8 -17.2,0 -34.5,-5.4 -49.7,-16.4 -34.1,-24.6 -45,-68.2 -26.4,-105.9l0.4,-0.8 136.8,-262.7L148.5,637.7C84,637.7 32.2,589 28,524.4c-2.4,-37.4 12.6,-73.1 41.3,-98.1L501.8,20.7c0.7,-0.7 1.4,-1.3 2.2,-1.9A84.7,84.7 0,0 1,557.1 0c30.8,0 58.2,16 73.4,42.7 15.1,26.6 14.9,58.2 -0.7,84.5L502.2,351.8h142.3c38.4,0 72.1,21.5 88,56.2 16,34.8 10.3,74.6 -14.8,103.8a40,40 0,0 1,-56.4 4.3zM983.6,955.3a40,40 0,1 1,-56.5 56.5L825.4,910.1l-101.7,101.7a39.9,39.9 0,0 1,-28.3 11.7,40 40,0 0,1 -28.3,-68.2l101.7,-101.7 -101.7,-101.7a40,40 0,1 1,56.5 -56.5l101.7,101.7 101.7,-101.7a40,40 0,1 1,56.5 56.5l-101.7,101.7 101.7,101.7z"
android:fillColor="#4A90E2"/>
android:fillColor="#6CE89E"/>
</vector>

View File

@ -5,8 +5,8 @@
android:viewportHeight="1024">
<path
android:pathData="M679.5,918.2c-3,0 -5.9,-1.3 -7.9,-3.8L497.7,700.2c-25.7,-29.6 -41.8,-64.4 -46.7,-100.8 -4.5,-33.4 0.5,-67 14.3,-97.3 25,-54.9 74.6,-89.1 129.4,-89.1 5.5,0 11.1,0.3 16.7,1 23.9,2.9 49.8,16.5 72.9,38.2 16.5,15.5 30.7,34.4 40.4,53.5 12.5,-14.8 28.4,-28.3 46.1,-39.1 24.6,-15 50.8,-23.3 73.7,-23.3 3.8,0 7.6,0.2 11.2,0.7 57.5,7.1 103.2,48.4 119.5,107.8 9.1,33.4 8,68.9 -3.3,102.7 -12.3,36.7 -36.3,69.6 -69.5,95.1l-216.7,166.4C683.9,917.5 681.7,918.2 679.5,918.2zM594.7,433.5c-46.7,0 -89.2,29.6 -110.9,77.1 -20.6,45.2 -23.7,115.3 29.3,176.3 0.1,0.1 0.1,0.2 0.2,0.3l167.8,206.7 208.9,-160.3c69.3,-53.2 79.3,-125.9 65.5,-176.2 -14,-51.3 -53.2,-86.9 -102.3,-92.9 -2.8,-0.3 -5.8,-0.5 -8.8,-0.5 -38.7,0 -88.6,29.7 -113.6,67.6 -2.1,3.2 -5.9,5 -9.7,4.5 -3.8,-0.4 -7.1,-3 -8.4,-6.6 -8,-21.7 -23.5,-44.4 -42.5,-62.2 -20,-18.7 -41.8,-30.4 -61.4,-32.8C604.2,433.8 599.4,433.5 594.7,433.5z"
android:fillColor="#444344"/>
android:fillColor="@color/black"/>
<path
android:pathData="M487.7,829.9c-2.1,0 -4.3,-0.7 -6.1,-2L160.5,586.6c-48.4,-34 -83.9,-79.4 -102.6,-131.4 -17.2,-47.7 -19.9,-98.4 -7.8,-146.8 10.2,-41 30.5,-77.2 58.7,-104.8 30,-29.3 67.8,-47.5 109.5,-52.6 33.8,-4.2 74.2,5.7 113.6,27.7 30.5,17.1 58.6,40.5 79.3,65.8 13.4,-29.5 34.6,-58.9 59.8,-82.8 32.5,-30.9 69.1,-50.1 103,-54.3 41.5,-5.1 82.6,2.9 118.7,23.1 34.1,19.1 62.9,48.4 83.3,84.7 24.2,43.2 34.9,92.8 30.9,143.5 -4.3,55.2 -26.4,109.2 -63.7,156.1 -3.5,4.4 -9.9,5.1 -14.3,1.6 -4.4,-3.5 -5.1,-9.9 -1.6,-14.3 80.5,-101.2 68.8,-209.5 31,-277 -38.8,-69.2 -108.4,-106.6 -181.7,-97.6 -29.6,3.6 -62,21 -91.4,48.9 -27.8,26.4 -50.3,60 -61.5,92 -1.3,3.6 -4.5,6.2 -8.3,6.7 -3.8,0.5 -7.6,-1.2 -9.8,-4.4 -19.3,-28.4 -49.8,-55.4 -83.5,-74.3 -35.6,-19.9 -71.6,-28.9 -101.1,-25.2 -73.5,9 -131.3,63.5 -150.9,142.1 -23.8,95.6 16.4,196.3 102.5,256.6 0.1,0.1 0.2,0.1 0.3,0.2l313.3,235.4 49.6,-62.4c3.5,-4.4 9.9,-5.1 14.3,-1.6 4.4,3.5 5.1,9.9 1.6,14.3l-55.8,70.2C493.7,828.6 490.7,829.9 487.7,829.9z"
android:fillColor="#444344"/>
android:fillColor="@color/black"/>
</vector>

View File

@ -5,5 +5,5 @@
android:viewportHeight="1024">
<path
android:pathData="M861,408.2C845,373.5 811.1,352 772.5,352H629.3l128.5,-224.7c15.6,-26.4 15.9,-57.9 0.7,-84.5C743.2,16 715.5,0 684.6,0c-19.4,0 -38.4,6.7 -53.4,18.8a39.3,39.3 0,0 0,-2.2 1.9L193.8,426.5C164.9,451.4 149.8,487.2 152.3,524.6c4.3,64.6 56.3,113.4 121.2,113.4h136L271.8,900.8a37.4,37.4 0,0 0,-0.4 0.8c-18.7,37.8 -7.8,81.4 26.5,106 15.3,11 32.7,16.4 50,16.4 21.5,0 42.8,-8.4 59.5,-24.8 0.4,-0.4 0.9,-0.9 1.3,-1.3L720.4,663.2a39.8,39.8 0,0 0,-2.2 -56.5,40.4 40.4,0 0,0 -56.8,2.2l-311,334c-1.3,1.2 -2.6,1.9 -5.4,-0.1 -3,-2.1 -2.5,-3.7 -1.6,-5.4l168,-320.9a39.8,39.8 0,0 0,-1.3 -39.2,40.3 40.3,0 0,0 -34.4,-19.2H273.4c-25.2,0 -39.6,-19.4 -40.9,-38.6 -0.6,-8.9 1.4,-21.8 14.3,-32.8 0.5,-0.4 0.9,-0.8 1.3,-1.2l434.1,-404.8a4.5,4.5 0,0 1,2.2 -0.6c0.8,0 2.6,0 3.9,2.2 1.3,2.3 0.4,3.8 -0,4.5l-0.4,0.7L525.2,372.2a39.8,39.8 0,0 0,0.2 39.9,40.3 40.3,0 0,0 34.8,19.9h212.3c9.6,0 13.8,6 15.5,9.6 1.7,3.7 3.6,10.9 -2.9,18.4a39.8,39.8 0,0 0,4.3 56.4,40.4 40.4,0 0,0 56.7,-4.3c25.3,-29.3 31,-69.1 14.9,-103.9z"
android:fillColor="#4A90E2"/>
android:fillColor="#6CE89E"/>
</vector>

View File

@ -4,12 +4,12 @@
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#FF000000"
android:fillColor="#6CE89E"
android:pathData="M679.7,916.5H344.3c-137,0 -248.3,-112.6 -248.3,-252.2V359.7c0,-139.5 111.4,-252.2 248.3,-252.2h337.9c135.7,0 245.8,112.6 245.8,252.2v307.2c0,137 -111.4,249.6 -248.3,249.6zM344.3,171.5c-101.1,0 -184.3,84.5 -184.3,188.2v304.6c0,103.7 83.2,188.2 184.3,188.2h335.4c101.1,0 184.3,-83.2 184.3,-185.6v-307.2c0,-103.7 -81.9,-188.2 -181.8,-188.2H344.3z"/>
<path
android:fillColor="#FF000000"
android:fillColor="#6CE89E"
android:pathData="M704,704c-11.5,0 -23,-6.4 -28.2,-17.9l-71.7,-139.5 -79.4,140.8c-5.1,10.2 -15.4,16.6 -25.6,16.6 -11.5,0 -21.8,-5.1 -28.2,-14.1l-65.3,-93.4 -57.6,92.2c-9,15.4 -29.4,19.2 -43.5,10.2 -15.4,-9 -19.2,-29.4 -10.2,-43.5l83.2,-133.1c5.1,-9 15.4,-14.1 26.9,-15.4 11.5,0 20.5,5.1 26.9,14.1l64,90.9 83.2,-148.5c6.4,-10.2 16.6,-16.6 28.2,-16.6 11.5,0 23,6.4 28.2,17.9l98.6,192c7.7,15.4 1.3,34.6 -14.1,43.5 -5.1,2.6 -10.2,3.8 -15.4,3.8z"/>
<path
android:fillColor="#FF000000"
android:fillColor="#6CE89E"
android:pathData="M340.5,363.5m-38.4,0a38.4,38.4 0,1 0,76.8 0,38.4 38.4,0 1,0 -76.8,0Z"/>
</vector>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#4C9AF7" />
<solid android:color="#6CE89E" />
<stroke android:color="@color/white" android:width="4dp"/>
<size
android:width="16dp"

View File

@ -57,18 +57,19 @@
<ImageView
android:id="@+id/flash"
android:layout_width="65dp"
android:layout_height="65dp"
android:layout_marginBottom="24dp"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="24dp"
android:padding="5dp"
android:src="@drawable/disflash"
app:layout_constraintBottom_toTopOf="@+id/camera"
app:layout_constraintEnd_toEndOf="@+id/photo" />
app:layout_constraintBottom_toBottomOf="@+id/photo"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/camera" />
<ImageView
android:id="@+id/camera"
android:layout_width="65dp"
android:layout_height="65dp"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginBottom="24dp"
android:padding="5dp"
android:src="@drawable/camera"
@ -77,10 +78,10 @@
<ImageView
android:id="@+id/photo"
android:layout_width="65dp"
android:layout_height="65dp"
android:layout_marginEnd="26dp"
android:layout_marginBottom="125dp"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="150dp"
android:padding="5dp"
android:src="@drawable/photo"
app:layout_constraintBottom_toBottomOf="parent"

View File

@ -7,4 +7,42 @@
android:layout_height="match_parent"
tools:context=".ui.activity.SplashActivity">
<ImageView
android:id="@+id/splash_image"
android:layout_width="150dp"
android:layout_height="150dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.388" />
<TextView
android:id="@+id/splash_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="@string/app_name"
android:textSize="25sp"
android:textStyle="bold"
android:gravity="center"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/splash_image" />
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="5dp"
android:layout_marginStart="53dp"
android:layout_marginEnd="53dp"
android:layout_marginBottom="80dp"
android:max="100"
android:progress="0"
android:progressDrawable="@drawable/progress_gradient"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -11,7 +11,7 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="5dp"
app:layout_constraintBottom_toTopOf="@+id/add"
app:layout_constraintBottom_toTopOf="@+id/upload"
app:layout_constraintTop_toTopOf="parent" />
<TextView

View File

@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".ui.fragment.FavoriteFragment">
<androidx.recyclerview.widget.RecyclerView
@ -11,4 +12,16 @@
android:layout_height="match_parent"
android:layout_marginTop="16dp" />
</FrameLayout>
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="There's nothing here yet"
android:textColor="@color/gray"
android:textSize="18sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -4,7 +4,7 @@
android:layout_height="200dp">
<ImageView
android:id="@+id/image_view"
android:id="@+id/item_image"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="12dp"
@ -16,10 +16,21 @@
android:id="@+id/like"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:src="@drawable/dislike"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/delete"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:src="@drawable/delete"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<TextView

6
keystore.properties Normal file
View File

@ -0,0 +1,6 @@
app_name=AR Drawing Flow
package_name=com.ardraw.ardrawingflow
keystoreFile=app/ARDrawingFlow.jks
key_alias=ARDrawingFlowkey0
key_store_password=ARDrawingFlow
key_password=ARDrawingFlow