android da activity orqali user ga kerakli file ni belgilashi va u file Uri ni olish kodi
val content = registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
// use uri
}
content.launch("fileType")
content.launch("image/*") // example all type imageandroid native orqali rasm shaklini istalgancha boshqarish mumkin bo'lgan componenta
@style/ShapeAppearance.Material3.Corner.TopBottom
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:src="@drawable/img_path"
app:shapeAppearance="@style/ShapeAppearance.Material3.Corner.TopBottom"
app:strokeWidth="0dp"
android:layout_gravity="center" />
@style/ShapeAppearance.Material3.Corner.TopBottom
<style name="ShapeAppearance.Material3.Corner.TopBottom">
<item name="cornerSizeBottomLeft">30dp</item>
<item name="cornerSizeBottomRight">12dp</item>
<item name="cornerSizeTopRight">30dp</item>
<item name="cornerSizeTopLeft">12dp</item>
</style>
1. Small 3-4" screens (~320x426 dp) (31.9% smaller than normal)
2. Normal 4-5" screens (~320x470 dp)
3. Large 7" tablet (~480x640 dp) (21.6% larger than normal)
4. X-Large 10" tablet (~720x960 dp) (34.7% larger than normal)
com.example.yourapp/
βββ data/ # Ma'lumotlar bilan ishlash logikasi (Repository, API, Database)
β βββ model/ # Ma'lumot modellari (Data Classes)
β βββ repository/ # Ma'lumotlar ombori
βββ di/ # Dependency Injection (Hilt, Koin)
βββ ui/ # Barcha UI (interfeys) bilan bog'liq kodlar
βββ components/ # Ilovaning turli qismlarida qayta ishlatiladigan kichik komponentlar (Masalan, CustomButton, LoadingSpinner)
βββ navigation/ # Navigatsiya grafigi, marshrutlar (routes) va ularning logikasi
βββ screens/ # Har bir alohida ekran uchun Composable funksiyalar
β βββ home/
β β βββ HomeScreen.kt
β β βββ HomeViewModel.kt
β βββ details/
β βββ DetailsScreen.kt
β βββ DetailsViewModel.kt
βββ theme/ # Ilova mavzusi: ranglar, shriftlar, shakllar
βββ Color.kt
βββ Theme.kt
βββ Typography.kt
fun Fragment.applyWindowInsetsAndImeUpAnimation(
target: View? = view,
top: Boolean = true,
bottom: Boolean = true,
) {
val view = target ?: return
var isAnimating = false
ViewCompat.setOnApplyWindowInsetsListener(view) { v, windowInsets ->
val topInset =
if (top) windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()).top else 0
val bottomInset =
if (bottom) windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom else 0
if (!isAnimating) {
val ime = windowInsets.getInsets(WindowInsetsCompat.Type.ime())
val bottomSize = maxOf(ime.bottom, bottomInset)
v.updatePadding(top = topInset, bottom = bottomSize)
} else v.updatePadding(top = topInset)
windowInsets
}
ViewCompat.setWindowInsetsAnimationCallback(
view,
object : WindowInsetsAnimationCompat.Callback(DISPATCH_MODE_CONTINUE_ON_SUBTREE) {
override fun onPrepare(animation: WindowInsetsAnimationCompat) {
super.onPrepare(animation)
isAnimating = true
}
override fun onStart(
animation: WindowInsetsAnimationCompat,
bounds: WindowInsetsAnimationCompat.BoundsCompat
): WindowInsetsAnimationCompat.BoundsCompat {
isAnimating = true
return super.onStart(animation, bounds)
}
override fun onProgress(
insets: WindowInsetsCompat,
runningAnimations: List<WindowInsetsAnimationCompat?>
): WindowInsetsCompat {
isAnimating = true
val ime = insets.getInsets(WindowInsetsCompat.Type.ime())
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
view.updatePadding(bottom = maxOf(ime.bottom, systemBars.bottom))
return insets
}
override fun onEnd(animation: WindowInsetsAnimationCompat) {
super.onEnd(animation)
isAnimating = false
}
}
)
}
β€1π1π₯1
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.widget.FrameLayout
import android.view.View
import android.view.VelocityTracker
import android.view.ViewConfiguration
import android.view.MotionEvent
import android.view.animation.DecelerateInterpolator
import eld.hos.lloraeld.R
import kotlin.math.abs
// CustomDrawerLayout.kt
class CustomDrawerLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
private lateinit var contentView: View
private lateinit var scrimView: View
private lateinit var drawerView: View
private var drawerWidth = resources.getDimensionPixelSize(R.dimen.menu_side_panel_width)
private var offset = 0f
private var isDragging = false
private var startX = 0f
private var startY = 0f
private var lastX = 0f
private val velocityTracker = VelocityTracker.obtain()
private val touchSlop = ViewConfiguration.get(context).scaledTouchSlop
private val minFlingVelocity = ViewConfiguration.get(context).scaledMinimumFlingVelocity
private val maxFlingVelocity = ViewConfiguration.get(context).scaledMaximumFlingVelocity
var isDrawerOpen = false
private set
var onDrawerStateChanged: ((Boolean) -> Unit)? = null
override fun onFinishInflate() {
super.onFinishInflate()
require(childCount >= 3) {
"CustomDrawerLayout must have 3 children: content, scrim, drawer"
}
contentView = getChildAt(0)
scrimView = getChildAt(1)
drawerView = getChildAt(2)
drawerView.post {
drawerWidth = drawerView.width
}
drawerView.translationX = -drawerWidth.toFloat()
scrimView.alpha = 0f
scrimView.visibility = GONE
scrimView.setOnClickListener { closeDrawer() }
}
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
when (ev.actionMasked) {
MotionEvent.ACTION_DOWN -> {
startX = ev.x
startY = ev.y
lastX = ev.x
isDragging = false
velocityTracker.clear()
velocityTracker.addMovement(ev)
}
MotionEvent.ACTION_MOVE -> {
val dx = ev.x - startX
val dy = ev.y - startY
if (abs(dx) > touchSlop && abs(dx) > abs(dy)) {
// drawer yopiq boβlsa β oβngga
// drawer ochiq boβlsa β chapga
if (!isDrawerOpen && dx > 0 || isDrawerOpen && dx < 0) {
isDragging = true
parent.requestDisallowInterceptTouchEvent(true)
return true
}
}
}
}
return false
}
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(ev: MotionEvent): Boolean {
velocityTracker.addMovement(ev)
when (ev.actionMasked) {
MotionEvent.ACTION_MOVE -> {
if (!isDragging) return false
val dx = ev.x - lastX
offset = (offset + dx).coerceIn(0f, drawerWidth.toFloat())
applyOffset(offset)
lastX = ev.x
return true
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
if (!isDragging) return false
velocityTracker.computeCurrentVelocity(1000, maxFlingVelocity.toFloat())
val velocityX = velocityTracker.xVelocity
val open = if (abs(velocityX) > minFlingVelocity) {
velocityX > 0
} else {
offset > drawerWidth / 2
}
if (open) openDrawer() else closeDrawer()
isDragging = false
parent.requestDisallowInterceptTouchEvent(false)
return true
}
}
return true
}
private fun applyOffset(value: Float) {
offset = value
val progress = value / drawerWidth
drawerView.translationX = -drawerWidth + value
contentView.translationX = value
scrimView.alpha = progress
scrimView.visibility = if (progress > 0f) VISIBLE else GONE
}
fun openDrawer(animated: Boolean = true) {
if (isDrawerOpen) return
animateTo(drawerWidth.toFloat(), animated)
}
fun closeDrawer(animated: Boolean = true) {
if (!isDrawerOpen && offset == 0f) return
animateTo(0f, animated)
}
fun toggleDrawer() {
if (isDrawerOpen) closeDrawer() else openDrawer()
}
private fun animateTo(target: Float, animated: Boolean) {
if (!animated) {
applyOffset(target)
setState(target > 0)
return
}
ValueAnimator.ofFloat(offset, target).apply {
duration = 250
interpolator = DecelerateInterpolator()
addUpdateListener { applyOffset(it.animatedValue as Float) }
addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
setState(target > 0)
}
})
start()
}
}
private fun setState(open: Boolean) {
if (isDrawerOpen != open) {
isDrawerOpen = open
onDrawerStateChanged?.invoke(open)
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
velocityTracker.recycle()
}
}
β€1π1π₯1