Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[develop] 사진 선택하기 화면 UI 수정, 기능 보완 #73

Merged
merged 13 commits into from
Mar 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.core.view.WindowInsetsControllerCompat
import androidx.core.view.isVisible
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupWithNavController
Expand Down Expand Up @@ -111,4 +112,12 @@ class MainActivity : BaseActivity<ActivityMainBinding>(R.layout.activity_main) {
fun getMap(): SupportMapFragment? = mapFragment

fun getLocationClient(): FusedLocationProviderClient? = fusedLocationClient

fun setStatusBarColor(id: Int, isLight: Boolean) {
val view = window.decorView
val wicc = WindowInsetsControllerCompat(window, view)

wicc.isAppearanceLightStatusBars = isLight
window.statusBarColor = resources.getColor(id, null)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.cheocharm.presentation.R
import com.cheocharm.presentation.base.BaseFragment
import com.cheocharm.presentation.common.EventObserver
import com.cheocharm.presentation.databinding.FragmentGroupsBinding
import com.cheocharm.presentation.ui.MainActivity
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
Expand All @@ -29,6 +30,8 @@ class GroupsFragment : BaseFragment<FragmentGroupsBinding>(R.layout.fragment_gro

binding.viewmodel = groupsViewModel

(requireActivity() as MainActivity).setStatusBarColor(R.color.map_z_red_500, false)

setupSwipeRefreshLayout()
setupRecyclerView()
setupToast()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
package com.cheocharm.presentation.ui.write

import android.Manifest
import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.provider.Settings
import android.view.View
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.exifinterface.media.ExifInterface
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
Expand All @@ -12,40 +21,82 @@ import com.cheocharm.presentation.R
import com.cheocharm.presentation.base.BaseFragment
import com.cheocharm.presentation.databinding.FragmentPictureBinding
import com.cheocharm.presentation.model.Picture
import com.cheocharm.presentation.ui.MainActivity
import com.cheocharm.presentation.util.GeocodeUtil
import com.google.android.gms.maps.model.LatLng
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.Dispatchers

class PictureFragment : BaseFragment<FragmentPictureBinding>(R.layout.fragment_picture) {
private val locationViewModel: LocationViewModel by navGraphViewModels(R.id.write)

private val requestPermissionsLauncher =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
permissions.forEach {
if (it.value.not()) {
// TODO: 권한 없을 때 처리
if (permissions.all { it.value.not() }) {
val snackbar = Snackbar.make(
binding.containerPicture,
R.string.picture_set_permission,
Snackbar.LENGTH_LONG
)
snackbar.setAction(R.string.picture_snackbar_action) {
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
val uri = Uri.fromParts("package", requireActivity().packageName, null)
intent.data = uri
startActivity(intent)
}
snackbar.show()
}
}
private val getContent =
registerForActivityResult(ActivityResultContracts.GetContent()) {
it?.let { uri ->
requireContext().contentResolver.openInputStream(uri)?.let { inputStream ->
val exif = ExifInterface(inputStream)
val latLng = exif.latLong?.let { array ->
LatLng(array[0], array[1])
private val getContentLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == Activity.RESULT_OK) {
val pictures = mutableListOf<Picture>()
val clipData = it?.data?.clipData
val geocodeUtil = GeocodeUtil(requireContext(), Dispatchers.IO)

if (clipData == null) {
val uri = it?.data?.data
val picture = uri?.toPicture()

picture?.let { pic ->
pictures.add(pic)
}
} else {
for (i in 0 until clipData.itemCount) {
val uri = clipData.getItemAt(i).uri
val picture = uri.toPicture()

picture?.let { pic ->
pictures.add(pic)
}
}
val picture = Picture(uri, latLng)
val geocodeUtil = GeocodeUtil(requireContext(), Dispatchers.IO)

locationViewModel.loadPicture(picture, geocodeUtil)
inputStream.close()
}

val picture = pictures[0]

locationViewModel.loadPicture(picture, geocodeUtil)
navigateToLocationFragment()
}
}

private fun Uri.toPicture(): Picture? {
var picture: Picture? = null

requireContext().contentResolver.openInputStream(this)?.let { inputStream ->
val exif = ExifInterface(inputStream)
val latLng = exif.latLong?.let { array ->
LatLng(array[0], array[1])
}

picture = Picture(this, latLng)

inputStream.close()
}

return picture
}

private fun navigateToLocationFragment() {
val action = PictureFragmentDirections.actionPictureFragmentToLocationFragment()
findNavController().navigate(action)
Expand All @@ -54,7 +105,14 @@ class PictureFragment : BaseFragment<FragmentPictureBinding>(R.layout.fragment_p
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

launchPermissionRequest()
setupToolbar()
setupButton()

requestPermissions()
}

private fun setupToolbar() {
(requireActivity() as MainActivity).setStatusBarColor(R.color.white, true)

with(binding.toolbarPicture) {
setNavigationIcon(R.drawable.ic_back)
Expand All @@ -63,18 +121,52 @@ class PictureFragment : BaseFragment<FragmentPictureBinding>(R.layout.fragment_p
findNavController().navigate(action)
}
}
}

private fun setupButton() {
binding.btnPictureGetPicture.setOnClickListener {
val intent = Intent(Intent.ACTION_PICK)
intent.setDataAndType(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
MediaStore.Images.Media.CONTENT_TYPE
)
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)

getContentLauncher.launch(intent)
}
}

private fun requestPermissions() {
when {
shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE) -> {
Toast.makeText(
context,
R.string.picture_permission_rationale,
Toast.LENGTH_SHORT
).show()

binding.btnPictureGet.setOnClickListener {
getContent.launch("image/*")
launchPermissionRequest()
}
ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.READ_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_DENIED -> {
launchPermissionRequest()
}
}
}

private fun launchPermissionRequest() {
requestPermissionsLauncher.launch(
val permissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_MEDIA_LOCATION
)
)
} else {
arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE
)
}
requestPermissionsLauncher.launch(permissions)
}
}
145 changes: 145 additions & 0 deletions presentation/src/main/res/drawable/bg_btn_picture.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item>
<shape>
<corners
android:radius="50dp" />
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid
android:color="#00CCCCCC" />
</shape>
</item>
<item>
<shape>
<corners
android:radius="50dp" />
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid
android:color="#06CCCCCC" />
</shape>
</item>
<item>
<shape>
<corners
android:radius="50dp" />
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid
android:color="#09CCCCCC" />
</shape>
</item>
<item>
<shape>
<corners
android:radius="50dp" />
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid
android:color="#0BCCCCCC" />
</shape>
</item>
<item>
<shape>
<corners
android:radius="50dp" />
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid
android:color="#0DCCCCCC" />
</shape>
</item>
<item>
<shape>
<corners
android:radius="50dp" />
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid
android:color="#10CCCCCC" />
</shape>
</item>
<item>
<shape>
<corners
android:radius="50dp" />
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid
android:color="#12CCCCCC" />
</shape>
</item>
<item>
<shape>
<corners
android:radius="50dp" />
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid
android:color="#15CCCCCC" />
</shape>
</item>
<item>
<shape>
<corners
android:radius="50dp" />
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid
android:color="#17CCCCCC" />
</shape>
</item>
<item>
<shape>
<corners
android:radius="50dp" />
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<solid
android:color="#1ACCCCCC" />
</shape>
</item>

<item>
<shape
android:shape="rectangle">
<corners
android:radius="50dp" />
<solid
android:color="@color/map_z_red_500" />
</shape>
</item>

</layer-list>
Binary file not shown.
Binary file not shown.
Binary file not shown.
5 changes: 3 additions & 2 deletions presentation/src/main/res/layout/fragment_groups.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

<androidx.constraintlayout.widget.ConstraintLayout
style="@style/root_layout_default"
android:background="@color/map_z_red_common"
android:background="@color/map_z_red_500"
tools:context=".ui.write.GroupsFragment">

<androidx.appcompat.widget.AppCompatTextView
Expand All @@ -24,7 +24,8 @@
android:layout_marginTop="@dimen/space_small"
android:text="@string/groups_title"
android:textColor="@color/white"
android:textSize="@dimen/groups_title_text_size"
android:textSize="@dimen/write_title_text_size"
android:fontFamily="@font/apple_sd_gothic_neo_b"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

Expand Down
Loading
Loading